Search code examples
pythonstdinio-redirection

How do I determine if sys.stdin is redirected from a file vs. piped from another process?


In a simple Python script intended to be run from the shell, can I reliably determine whether sys.stdin has been redirected from an actual file vs. piped from another process?

I want to change runtime behavior depending on whether stdin is coming from a data file vs. streaming from another process via a pipe.

As expected, isatty() returns False in both cases. Here's a quick isatty() test:

# test.py
import os
import sys
print sys.stdin.isatty()
print os.isatty(sys.stdin.fileno())

Testing:

python test.py < file.txt

produces:

False
False

and:

ls -al | python test.py

produces:

False
False

Is there a pythonic method of doing this?

Unix/Linux specific is fine, though it would be nice to know if it's possible to do this in a portable manner.

Edit: Note in response to commenters: Why do I care? Well, in my case, I want to deal with time-stamped data that comes in at irregular intervals when piped from another process; when I play back pre-recorded data from a file, I'd like to replay it using a fixed or variable delays.

I agree it's probably advantageous to use a cleaner method (and I can think of several, including an intermediate script to insert delays in the playback stream) but I'm terminally curious.


Solution

  • You're looking for stat macros:

    import os, stat
    
    mode = os.fstat(0).st_mode
    if stat.S_ISFIFO(mode):
         print("stdin is piped")
    elif stat.S_ISREG(mode):
         print("stdin is redirected")
    else:
         print("stdin is terminal")