从管道读取 Python stdin,不阻塞空输入

Read Python stdin from pipe, without blocking on empty input

我正在尝试在 Python 脚本中读取标准输入,同时从管道接收。

我使用了这些行:

for line in sys.stdin:
    print line

和运行脚本:echo "test" | script.py

到目前为止一切正常。但是,如果我不使用管道,程序会停留在 for 命令处。这意味着调用:./script.py 将使脚本无法运行。我该如何解决这个问题?

编辑:在这种情况下您显然甚至不希望它读取行或处理 KeyboardInterrupt,因此您需要做的是检查空 stdin。检查你是否是终端,如编辑示例所示通过。


sys.stdin 类似于文件。尝试:

if not sys.stdin.isatty():
    data = sys.stdin.readlines()
    # Do something with data

如果你 运行 这个没有 stdin 我认为它不会像以前那样挂起...因为 sys.stdin 将是空的。该功能应该会继续。

你的脚本可以运行,只是你的期望似乎不正确。

script.py(调整为Python 3,这是我安装的):

import sys
for line in sys.stdin:
    print(line)

$ python script.py
abcd
abcd

xyz
xyz

第一次出现的“abcd”和“xyz”是我从键盘输入的,第二次出现的是程序的输出。我当时通过 ctrl-d 终止了执行。

问题是在没有管道输入的情况下从 stdin 读取并不能达到您的预期。当你只是 运行 脚本(没有管道输入)时,它只是坐在那里等待你从键盘输入一些东西。您可能需要调查 raw_input 从键盘获取输入。

更新:

在评论中对您想要的内容进行更多说明后,以下脚本可能会为您提供所需的结果:

import sys
if not sys.stdin.isatty():
    for line in sys.stdin:
        print(line)

print("More stuff!")

您可以通过在从 sys.stdin.

派生的文件描述符上调用 isatty 来检查程序是否已通过管道传输

像这样:

import os
import sys

if not os.isatty(sys.stdin.fileno()):
    print (sys.stdin.readlines())
else:
    print ("Skip, so it doesn't hang")

示例 1:

 echo "test" | python ./script.py
 ['test\n']

示例 2:

 python ./script.py 
 Skip, so it doesn't hang