我有一个简单的脚本,它从设备读取值并通过print
输出它们,另一个脚本监听stdin并解释每个数字。设备每秒输出一个数字。令人惊讶的是,在我的ubuntu盒子上管道脚本不起作用。但是,如果第一个脚本不是从设备读取而是尽可能快地生成随机数,则第二个脚本会成功接收数据。
以下是我的情况的简化示例。
print.py:
#!/usr/bin/env python2
import time
import sys
while True:
time.sleep(1) # without this everything works
print "42"
sys.stdout.flush()
read.py:
#!/usr/bin/env python2
import sys
while True:
for str in sys.stdin:
print str
命令行调用:
vorac@laptop:~/test$ ./print.py | ./read.py
这是最终结果。第一个脚本从设备读取,第二个脚本在两个不同的时间帧中绘制数据(显示的是随机数)。
答案 0 :(得分:3)
sys.stdin
(xreadlines()
)的迭代器方法是缓冲的。换句话说,当你的循环隐式调用next(sys.stdin)
来获取下一行输入时,Python tries to read来自真正的底层标准输入流,直到它的内部缓冲区已满,并且只有一次缓冲区它是否已经通过循环体进行。 buffer size is 8 kilobytes,所以这需要一段时间。
您可以通过减少sleep()
调用0.001
或某些此类值的时间延迟来查看此信息,具体取决于系统的功能。如果你恰到好处的时间,你几秒钟内什么也看不见,然后整整一块42
一下子全部出来。
要解决此问题,请使用未缓冲的sys.stdin.readline()
。
while True:
line = sys.stdin.readline()
print line
您可能还希望在打印前删除尾随换行符,否则您将获得双重换行符。使用line.rstrip('\n')
或print line,
来抑制要打印的额外换行符。
答案 1 :(得分:2)
我更改了你的read.py,它对我有用:),你忘了.readline()
来自stdin
。
import sys
while True:
line = sys.stdin.readline()
if line:
print line.strip()
else:
continue
输出是:
$ python write.py | python read.py
42
42
42
42
42
42
42