如何确定sys.stdin是从文件重定向还是从另一个进程管道传输?

Ina*_*ist 21 python stdin io-redirection

在一个旨在从shell运行的简单Python脚本中,我是否可以可靠地确定sys.stdin是否已从实际文件重定向而不是从另一个进程传输?

我想根据stdin是来自数据文件还是来自另一个进程通过管道流来改变运行时行为.

正如预期的那样,isatty()在两种情况下都返回False.这是一个快速isatty()测试:

# test.py
import os
import sys
print sys.stdin.isatty()
print os.isatty(sys.stdin.fileno())
Run Code Online (Sandbox Code Playgroud)

测试:

python test.py < file.txt
Run Code Online (Sandbox Code Playgroud)

生产:

False
False
Run Code Online (Sandbox Code Playgroud)

和:

ls -al | python test.py
Run Code Online (Sandbox Code Playgroud)

生产:

False
False
Run Code Online (Sandbox Code Playgroud)

有这样做的pythonic方法吗?

Unix/Linux特定的很好,但知道是否可以以可移植的方式执行此操作会很好.

编辑:请注意评论者:我为什么关心?好吧,在我的情况下,我想处理从另一个进程传输时不规则间隔的时间戳数据; 当我从文件中播放预先录制的数据时,我想使用固定或可变延迟重放它.

我同意使用更干净的方法可能是有利的(我可以想到几个,包括在回放流中插入延迟的中间脚本),但我最终好奇.

geo*_*org 25

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"
Run Code Online (Sandbox Code Playgroud)

  • 而不是`os.fstat(0).st_mode`你应该使用`os.fstat(sys.stdin.fileno()).st_mode` (4认同)
  • @TheTechRobo36414519因为这里的“0”表示_stdin_的文件描述符。不仅仅是一个随机数。想想两年后阅读这段代码。你会发现这个“0”是一个神奇的数字。 (2认同)