Reading output from a child process non-blockingly
Adriaan Renting
renting at astron.nl
Thu Jun 30 03:47:33 EDT 2005
I use the pty module, in combination with select.select.
Search for Pexpect for an elaborate example.
It basically goes something like this:
-------------------------------------------------
import os, select, pty
pid, fd = pty.fork()
fd_eof = 0
if pid == 0:
os.execvp('ls',['ls']) # child process
else: # parent proces
while not fd_eof:
ready = select.select([fd], [], [], 0.25)
if fd in ready[0]:
text = os.read(fd, 1024)
if text == '':
fd_eof = 1
else: print text
-------------------------------------------------------------
In 2.3.4 this exits with an exception OSError: [Errno 5] Input/output
error after showing the 'ls' output, I have a problem that this works in
2.3.4 but in 2.3.5 this just keeps running indefinately. In my own code
I handle the OSError by setting fd_eof=1. This onyl works on Unix.
Adriaan Renting | Email: renting at astron.nl
ASTRON | Phone: +31 521 595 217
P.O. Box 2 | GSM: +31 6 24 25 17 28
NL-7990 AA Dwingeloo | FAX: +31 521 597 332
The Netherlands | Web: http://www.astron.nl/~renting/
>>> Yuan HOng <hongyuan1306 at gmail.com> 06/29/05 10:08 AM >>>
In my program I have to call an external program and parse its output.
For that I use the os.popen2 function, and then read the output
stream.
But the complexity is that the external program gives back its output
in a piecemeal manner, with long delays between the outputs. In the
main program I want to therefore read the output in a non-blocking
manner, to read as many bytes as the child process is spitting out.
The question is, how can I achieve that?
I tried use select.select on the output stream returned by os.popen2,
but it returns a readable file descriptor only after the whole child
process ends.
Here is a script simulating the external program:
test.py:
import sys, time
print 'hello\n'*500
sys.stdout.flush()
time.sleep(100)
print 'world\n'*500
And here is what I am tring to do in the main program to read its
output:
import os, select
cmd = 'python test.py'
pin, pout = os.popen2(cmd)
while not select.select([pout], [], [], some_timeout)[0]:
pass
pout.readline()
I hope to get the first return very soon, before the external program
sleeps, but instead only after the whole program exits do I get any
output.
Can anyone give me a hint?
--
Hong Yuan
www.homemaster.cn
--
http://mail.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list