streaming Popen.stdout

M

Michele Simionato

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
 
M

Michele Simionato

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,
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top