tags:

views:

214

answers:

2

I'm using Python's subprocess.communicate() to read stdout from a process that runs for about a minute. How can I print out each line of that process's stdout in a streaming fashion, so that I can see the output as it's generated, but still block on the process terminating before continuing? subprocess.communicate() appears to give all the output at once.

A: 

If you want a non-blocking approach, don't use process.communicate(). If you set the subprocess.Popen() argument stdout to PIPE, you can read from process.stdout and check if the process still runs using process.poll().

Lukáš Lalinský
+2  A: 

Here is an simple example (with no checking for errors):

import subprocess
proc = subprocess.Popen('ls',
                       shell=True,
                       stdout=subprocess.PIPE,
                       )
while proc.poll() is None:
    output = proc.stdout.readline()
    print output,

If ls ends too fast, then the while loop may end before you've read all the data.

You can catch the remainder in stdout this way:

output=proc.communicate()[0]
print output,
unutbu
does this scheme fall victim to the buffer blocking problem that the python doc refers to?
Heinrich Schmetterling
@Heinrich, the buffer blocking problem is not something I understand well. I believe (just from googling around) that this problem only occurs if you don't read from stdout (and stderr?) inside the while loop. So I think the above code is okay, but I can't say for sure.
unutbu
This actually does suffer from a blocking problem, a few years ago I had no end to the trouble where readline would block 'til it got a newline even if the proc had ended. I don't remember the solution, but I think it had something to do with doing the reads on a worker thread and just looping `while proc.poll() is None: time.sleep(0)` or something to that effect. Basically- you need to either ensure that the output newline is the last thing that the process does (because you can't give the interpreter time to loop again) or you need to do something "fancy."
dash-tom-bang
@Heinrich: Alex Martelli writes about how to avoid the deadlock here: http://stackoverflow.com/questions/1445627/how-can-i-find-out-why-subprocess-popen-wait-waits-forever-if-stdoutpipe/1445647#1445647
unutbu