streaming Popen.stdout

Discussion in 'Python' started by Michele Simionato, Feb 21, 2006.

  1. I was experimenting with subprocess.Popen with the following script:

    $ cat Popen_ex.py
    import sys, subprocess
    po = subprocess.Popen([sys.executable, 'hello.py'],
    stdout=subprocess.PIPE,
    bufsize=0)
    for line in po.stdout:
    print line,

    where hello.py is the following script:

    $ cat hello.py
    import time
    time.sleep(1)
    print 'hello'
    time.sleep(1)
    print 'world'
    time.sleep(1)
    print '*END*'
    time.sleep(1)

    It turns out that Popen collects all the output and write everything
    together
    after 4 seconds, where I would like to print a line every seconds.
    How can I get that in a simple way? A Unix-only solution would be fine,
    too.


    Michele Simionato
     
    Michele Simionato, Feb 21, 2006
    #1
    1. Advertising

  2. Replying to myself ...

    I cooked up this solution involving os.pipe and os.fork, but I am not
    especially happy with
    it; anyway, let me write it. Feedback is welcome, since this was
    written very quickly and
    I may have missed something. BTW, are there libraries out there doing
    something similar?

    ----

    import subprocess
    import os, sys, time

    class ReadObject(object):
    def __init__(self, fileno):
    self.fileno = fileno
    self._closed = False
    self.name = str(self)
    def readline(self):
    if self._closed : return ''
    return ''.join(iter(self.read1, '\n')) + '\n'
    def read(self):
    return ''.join(iter(self.read1, '\x00'))
    def read1(self):
    c = os.read(self.fileno, 1)
    if c == '\x00':
    self._closed = True
    return '\n'
    else:
    return c
    def __iter__(self):
    return iter(self.readline, '')

    class WriteObject(object):
    def __init__(self, fileno):
    self.fileno = fileno
    self.name = str(self)
    def write(self, text):
    os.write(self.fileno, text)
    def flush(self):
    pass
    def close(self):
    self.write('\x00')

    def callproc(child, *args,**kw):
    "Run the child procedure in a child process"
    r, w = os.pipe()
    R, W = ReadObject(r), WriteObject(w)
    if os.fork(): # parent
    return R
    else: # child
    sys.stdout = W
    try:
    child(*args, **kw)
    finally:
    W.close()
    sys.exit()

    if __name__ == '__main__':
    for line in callproc(subprocess.call, [sys.executable,
    'hello.py']):
    print line,
     
    Michele Simionato, Feb 23, 2006
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Greg Ercolano
    Replies:
    2
    Views:
    2,923
  2. Replies:
    7
    Views:
    1,274
    Karthik Gurusamy
    Sep 25, 2007
  3. Replies:
    4
    Views:
    450
    Marc 'BlackJack' Rintsch
    Nov 7, 2007
  4. Helmut Jarausch
    Replies:
    8
    Views:
    2,261
  5. File.popen/IO.popen

    , May 20, 2006, in forum: Ruby
    Replies:
    1
    Views:
    248
    Robert Klemme
    May 20, 2006
Loading...

Share This Page