writing consecutive data to subprocess command 'more'

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sat May 2 16:35:19 EDT 2009

En Sat, 02 May 2009 15:53:17 -0300, SanPy <jhmsmits at gmail.com> escribió:

> I have this method that prints a given text via a subprocess command
> 'more' . It is like this:
> def print_by_page(text):
>     if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
>         viewer = 'more -EMR'
>         proc = subprocess.Popen([viewer], shell=True,
> stdin=subprocess.PIPE,
>             stderr=subprocess.PIPE)
>         try:
>             stdout, stderr = proc.communicate(text)
>         except OSError:
>             pass
>         else:
>             if stderr: # probably no 'more' available on this system
>                 sys.stdout.write(text)
>             return
>     sys.stdout.write(text)
> It works fine, but what I really want to do is first print a header
> through the 'more' command, then fetch some data from the web, and
> show it through the same 'more' command/process. And even more data,
> another header, other data from the web, all through the same 'more'
> command/process.
> Can somebody help me out on this?

communicate writes to the child's stdin and waits for it to finish. If you  
want to keep writing, don't use communicate. And you'll need to keep state  
 from one call to another, so use a class. Based on the code above, create  
a class Pager with __init__, write and close methods:

class Pager:
  def __init__(self):
   # copy the logic above
   self.proc = subprocess.Popen(...)
   self.file = self.proc.stdin
   # if something goes wrong, set self.proc=None and self.file=sys.stdout

  def write(self, text):

  def close(self):
   if self.proc:

Also, take a look at the pager function in the pydoc module (see the  
source) - it handles several cases.

Gabriel Genellina

More information about the Python-list mailing list