繁体   English   中英

标准输入不应等待“ CTRL + D”

[英]stdin should not wait for “CTRL+D”

我有一个简单的python脚本,应该从stdin中读取。 因此,如果我将程序的标准输出重定向到我的python脚本的标准输入。

但是,由我的程序记录到python脚本的东西只会在正在记录东西的程序被杀死时才“到达” python脚本。

但是实际上我想处理程序中记录的每一行,而不是实际运行2​​4/7的程序退出时处理。

那么我该如何实现呢? 如何使stdin在处理数据之前不等待CTRL + D或EOF?

# accept_stdin.py
import sys
import datetime

for line in sys.stdin:
    print datetime.datetime.now().second, line

# print_data.py
import time

print "1 foo"
time.sleep(3)
print "2 bar"

# bash
python print_data.py | python accept_stdin.py

像所有文件对象一样, sys.stdin迭代器以块的sys.stdin读取输入。 即使准备好输入一行,迭代器也将尝试在输出任何内容之前读取块大小或EOF。 您可以通过使用readline方法解决此问题,该方法没有此行为:

while True:
    line = sys.stdin.readline()
    if not line:
        # End of input
        break
    do_whatever_with(line)

您可以将其与iter的2参数形式结合使用以使用for循环:

for line in iter(sys.stdin.readline, ''):
    do_whatever_with(line)

我建议在代码中留下注释,以解释为什么不使用常规迭代器。

这也是您的生产者程序的问题,即您将stdout通过管道传送到python脚本的问题。

确实,由于该程序仅打印而从不刷新,因此它打印的数据被保存在内部程序缓冲区中以用于stdout,而不会刷新到系统中。

print_data.py print语句之后, print_data.py添加sys.stdout.flush()调用。

退出程序时会看到数据,因为程序在退出时会自动刷新。

看到这个问题的解释,

正如@ user2357112所说,您需要使用:

for line in iter(sys.stdin.readline, ''):

之后,您需要使用-u标志启动python,以立即刷新stdin和stdout。

python -u print_data.py | python -u accept_stdin.py

您还可以在shebang中指定标志。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM