我有两个文件,其中第一个是fizz
#!/usr/bin/python
import time
print 'started'
time.sleep(3)
print 'ended'
其次是吧
#!/usr/bin/python
import sys
for line in sys.stdin:
print line
当我运行命令./fizz | ./bar
时,我希望它打印started
然后等待3秒并打印ended
,但真正发生的是打印started
和{ 3秒后同时{1}}。有没有办法达到我想要的行为?感谢
答案 0 :(得分:6)
现在很明显问题出在接收方,我提出了一个我喜欢使用的替代方案:
#!/usr/bin/python
import sys
import os
for line in iter(sys.stdin.readline, ''):
sys.stdout.write(line) # \n included in line
iter(func, sentinel)
为每次迭代调用func()
,如果函数结果== sentinel
则结束。
答案 1 :(得分:5)
好问题。它比它应该有点难。
问题确实在bar
,特别是sys.stdin
被缓冲。我尝试使用较小的缓冲区大小打开sys.stdin
并使用python -u
,但这不起作用。该联机帮助页有这样的说法:
-u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xread‐ lines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option. To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.
最后这对我有用:
#!/usr/bin/python
import sys
import os
while True:
line = sys.stdin.readline()
if not line:
break
sys.stdout.write(line) # or print, doesn't matter.
答案 2 :(得分:1)
有两个问题:
print "something"
中的./foo
如果被重定向则不会刷新其stdout缓冲区(在本例中为管道),即stdout is not connected a tty-like device,例如,交互式控制台for line in sys.stdin:
可能会尝试一次读取几行您可以按照以下方式修复:
$ PYTHONUNBUFFERED=1 ./foo | ./bar
./bar
:
#!/usr/bin/python
import sys
for line in iter(sys.stdin.readline, ''):
print line,
即,使./foo
的stdout无缓冲(-u
option)并按照@Eduardo Ivanec's answer中的建议逐行读取./bar
中的输入。
作为替代方案,您可以在sys.stdout.flush()
中调用./foo
,而不是按照@kev's answer中的建议使其stdout无缓冲。