[Tutor] A question about using stdin/out/err vs named files

Steven D'Aprano steve at pearwood.info
Sun Oct 19 05:04:59 CEST 2014


On Sat, Oct 18, 2014 at 11:36:43AM -0700, George R Goffe wrote:
> Hi,
> 
> When you run a python program, it appears that stdin, stdout, and 
> stderr are opened automatically.
> 
> I've been trying to find out how you tell if there's data in stdin 
> (like when you pipe data to a python program) rather than in a named 
> input file. It seems like most/all the Unix/Linux commands are able to 
> figure this out. Do you know how Python programs do this or might do 
> this?

Hmmm, good question. I've never actually done this before, but I think 
the right way is to just try reading from stdin and see if anything is 
there. Let's try it, using Python 2.7:

# stdin_demo.py
import sys
c = sys.stdin.read(1)
if c:
    text = c + sys.stdin.read()  # Slurp everything.
    print "Read text from stdin:"
    print text
else:
    print "Nothing in stdin."



Alas, that doesn't do what I expected. It works if I pipe something 
into stdin:

[steve at ando ~]$ echo "Some data here" | python2.7 stdin_demo.py
Read text from stdin:
Some data here



but if stdin is empty, the call to read() blocks, waiting for input. I 
have to manually type something (or nothing, as the case may be) 
then type Ctrl-D to force end-of-file:

[steve at ando ~]$ python2.7 stdin_demo.py  # enter something, then Ctrl-D
hello world
Read text from stdin:
hello world

[steve at ando ~]$ python2.7 stdin_demo.py  # immediately Ctrl-D
Nothing in stdin.



Here's my second attempt:

# stdin_demo.py
import sys
if sys.stdin.isatty():
    print "Ignoring stdin."
else:
    c = sys.stdin.read(1)
    if c:
        text = c + sys.stdin.read()  # Slurp everything.
        print "Read text from stdin:"
        print text
    else:
        print "Nothing in stdin."



This version seems to do what I think you want:


[steve at ando ~]$ python2.7 stdin_demo.py
Ignoring stdin.
[steve at ando ~]$ echo "Some data here" | python2.7 stdin_demo.py
Read text from stdin:
Some data here

[steve at ando ~]$ echo -n "" | python2.7 stdin_demo.py
Nothing in stdin.


I haven't tried this under Windows, and I'm not sure if it is the 
"correct" way to do it under POSIX systems like Unix, Linux or Mac, but 
it seems to work.

Oh, in case it wasn't obvious... it's probably not a good idea to slurb 
everything as I do above, but I leave processing stdin line-by-line as 
an exercise.


-- 
Steven


More information about the Tutor mailing list