Unbuffer stdout?

Francis Avila franga at shentel.net
Tue Mar 25 19:24:43 EST 2003


I'm trying to run the stdout of an os.popen*() to sys.stdout.  Problem is
that the output seems to get trapped in a buffer until the command exits.

Code:

>>> import os, sys
>>> sys.stdout.write( os.popen("yes", 'r', 0).readline() )
yes: standard output: Broken pipe
y
>>>

I assume the broken pipe is from having the pipe closed before 'yes' exits.
Strangely enough, the popen[2-4]() variants don't have this problem:

>>> sys.stdout.write( os.popen2("yes", 'r', 0)[1].readline() )
y
>>>

Anyway, this:

>>> sys.stdout.write( os.popen("yes", 'r', 0).read() )

hangs forever (with some disk activity after a while) until you interrupt
the interpreter.  I strongly suspect this is because the output is getting
trapped in a buffer until the command exits (which is what I want to avoid)
because the following works fine:

>>> sys.stdout.write( os.popen("ls", 'r', 0).read() )
directoryOne
directoryTwo
someRandomFile
>>>

This:

>>> sys.stderr.write( os.popen("yes", 'r', 0).read() )

does the same, which seems odd to me because stderr is never buffered, at
least not by the OS.  In any case, even _this_:

#!/bin/sh
yes | more

does give you a screen of y's as soon as 'yes' fills the buffer, but before
'yes' exits.  So python is somewhere doing extra buffering of the whole
output of popen().

What I'm looking for is to pipe the stdout of a child process directly to
the stdout of the parent process (i.e., the python script), without any
buffering along the pipeline.  As I see it, this is either not possible in
python, or I'm going about this the wrong way.

BTW, I was trying to look at the code of popen(), but I couldn't find it
anywhere in the python library, much less in os.py. What's more:

>>> os.popen
<built-in function popen>

But if it's a built-in, why do I have to import os?

I'm running python 2.1.3 on a linux system, if it matters.

Help?
--
Francis Avila





More information about the Python-list mailing list