关闭缓冲

时间:2011-12-07 14:05:08

标签: python linux bash buffering

以下缓冲区在哪里...以及如何将其关闭?

我正在写一个python程序中的stdout,如下:

for line in sys.stdin:
    print line

这里有一些缓冲:

tail -f data.txt | grep -e APL | python -u Interpret.py

我尝试了以下方法来摆脱可能的缓冲......没有运气:

  • 如上所述,使用-u标志和python调用
  • 在每次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 个答案:

答案 0 :(得分:12)

file.readlines()for line in file具有内部缓冲,不受-u选项的影响(请参阅-u option note)。使用

while True:
   l=sys.stdin.readline()
   sys.stdout.write(l)

代替。

顺便说一句,sys.stdout默认是行缓冲的,如果它指向终端而sys.stderr是无缓冲的(请参阅stdio buffering)。

答案 1 :(得分: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。)

答案 2 :(得分:3)

问题出在你的for循环中。在继续之前它会等待EOF。你可以用这样的代码修复它。

while True:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break 

    if not line:
        break

    print line,

试试这个。

答案 3 :(得分:0)

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)并确保在您的环境中设置PYTHONUNBUFFERED