我正在运行这个简单的Python程序,以合并两个子进程的输出行:
import select
from subprocess import PIPE, Popen
import sys
subprocs = [
Popen(cmdline, stdout=PIPE) for cmdline in
[['./repeat', 'abc'], ['./repeat', 'xyz']]
]
while True:
rstreams, _, _ = select.select([p.stdout for p in subprocs], [], [])
for stream in rstreams:
sys.stdout.buffer.write(stream.readline())
…其中repeat是一个定期生成输出的简单脚本:
#!/bin/bash
while sleep 1 ; do echo $@ ; done
我希望将两个子流程的输出逐行合并,以便合并后的输出以任意顺序包含abc和xyz的行,并及时进行中继。(不需要混合数据,例如abxyzc
。)
但是,我发现上面的Python程序很长一段时间都没有产生输出,或者直到我按下Ctrl C为止。
(我尝试将stream.readline()更改为stream.read(1),以防问题是readline()挂起,即使我不想这种交错,但并没有帮助。发生在Linux上的Python 3.5.2和macOS上的Python 3.7.6。)
当子流程清楚地生成输出时,为什么要选择select()呢?
问题来源:stackoverflow
根本原因是您使用了sys.stdout.buffer,它内部具有一个缓冲区,因此我们无法立即看到结果。
我们可以在写入后显式刷新结果。将sys.stdout.buffer.flush()放在buffer.write()之后。或者只是使用print(stream.readline())
而不是sys.stdout.buffer
。
回答来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。