关闭缓冲
在下面这个问题中,问的是缓冲区在哪里,以及如何关闭它。
我在一个Python程序中这样输出到标准输出(stdout):
for line in sys.stdin:
print line
这里面有一些缓冲的情况:
tail -f data.txt | grep -e APL | python -u Interpret.py
我尝试了以下方法来解决可能的缓冲问题,但都没有成功:
- 像上面那样,在调用Python时加上 -u 参数
- 在每次调用 sys.stdout.write() 后,调用 sys.stdout.flush() ... 这些方法都导致Python创建了一个缓冲流,等了大约一分钟才打印出前几行。
使用了以下修改过的命令:
stdbuf -o0 tail -f data.txt | stdbuf -o0 -i0 grep -e APL | stdbuf -i0 -o0 python -u Interpret.py
为了验证我的预期,我尝试了:
tail -f data.txt | grep -e APL
这个命令产生了稳定的输出流 ... 显然没有Python命令那么缓冲。
那么,我该如何关闭缓冲呢?答案是:原来在管道的两端都有缓冲。
4 个回答
3
你遇到的问题出在你的for循环上。它会在继续执行之前等待文件结束符(EOF)。你可以用下面的代码来解决这个问题。
while True:
try:
line = sys.stdin.readline()
except KeyboardInterrupt:
break
if not line:
break
print line,
试试看这个方法。
6
我认为问题出在 grep
的输出缓冲上。当你使用管道命令 tail -f | grep ... | some_other_prog
时,它会这样做。为了让 grep
每行都立即输出,可以使用 --line-buffered
这个选项:
% tail -f data.txt | grep -e APL --line-buffered | test.py
APL
APL
APL
这里的 test.py
是:
import sys
for line in sys.stdin:
print(line)
(在 Linux 和 gnome-terminal 上测试过。)