sys.stdin and two CTRL-Ds

John Machin sjmachin at lexicon.net
Sat Jul 1 16:39:10 EDT 2006


On 2/07/2006 5:02 AM, Christoph Haas wrote:
> Hi...
> 
> I encountered a problem that - according to my google search - other
> people have found, too. Example code:
> 
> import sys
> for line in sys.stdin:
>    print line
> 
> Running this code in Python 2.3 or 2.4 has the problem that I need to
> send two EOFs (Ctrl-D) to break out of that loop.
> 
> Use case is a piped Python script that I run as a "CustomLog" pipe for
> an Apache web server. I want to run all the log output through that pipe
> but haven't had much luck. First it takes ages until the script
> processes the input (even though I ran Python with "-u" to make it
> unbuffered)

Which "it" did you expect to make unbuffered? -u unbuffers sys.stdout 
and sys.stderr (and makes them binary, which wouldn't be a good idea on 
a Windows box). If you are concerned that output shows up in real time, 
use sys.stdXXX.flush().

> and then the script needs one EOF to do something with the
> input and a second EOF to break out of the loop.
> 
> Is this a bug? I'm close to write a Perl script for this case. :(

I can reproduce your problem on Windows with Python 2.4.2 (note ^Z is 
EOF for Windows):

|>> import sys
|>> for line in sys.stdin:
...     print >> sys.stderr, "->", repr(line)
...
line1
line2
line3
^Z
-> 'line1\n'
-> 'line2\n'
-> 'line3\n'
^Z
|>>

However this worked for me :

|>> import sys
|>> while 1:
...     line = sys.stdin.readline()
...     if not line: break
...     print >> sys.stderr, "->", repr(line)
...
line1
-> 'line1\n'
line2
-> 'line2\n'
^Z
|>>

The Library Reference Manual, section 2.3.9 (File Objects) says:
"""
Files support the iterator protocol. Each iteration returns the same 
result as file.readline(), and iteration ends when the readline() method 
returns an empty string.
"""

So yes, looks like a bug to me, but perhaps you don't need use Perl :-)

HTH,
John



More information about the Python-list mailing list