6

当将 python 脚本的打印输出通过管道传输到 grep 等命令时,脚本的输出似乎仅在整个脚本完成后才通过管道传输到后续命令。

例如,在test_grep.py如下脚本中:

#!/usr/bin/env python
from time import sleep

print "message1"
sleep(5)
print "message2"
sleep(5)
print "message3"

当用 调用时./test_grep.py | grep message,10 秒内什么都不会出现,此时所有三行都会出现。

将此与脚本进行比较test_grep.sh

#!/usr/bin/env bash
echo "message1"
sleep 5 
echo "message2"
sleep 5
echo "message3"

./test_grep.sh | grep message将立即输出message1,然后每隔 5 秒输出message2message3

我希望这是因为只有在 python 解释器完成执行后,输出才可用于下一个命令。有没有办法改变这种行为?

4

1 回答 1

8

你能行的:

  • print通过在 python 中刷新每个
  • 通过将 stdout 设置为无缓冲
  • 通过将 stdout 设置为行缓冲

您甚至可以调用python -u禁用缓冲。


我会选择行缓冲选项,因为它看起来最自然。

open(file, mode='r', buffering=-1 ....)

buffering 是一个可选整数,用于设置缓冲策略。传递 0 关闭缓冲(仅在二进制模式下允许),1 选择行缓冲(仅在文本模式下可用),整数 > 1 表示固定大小的块缓冲区的大小。

当您不指定缓冲(典型的“打开”)时,如果它检测到输出将直接执行 TTY,即到您的屏幕控制台,它将使用行缓冲。如果您通过管道输出或将其重定向到文件,它将切换回大型(4K / 8K)缓冲区。


你如何“将标准输出设置为行缓冲”?

您可以stdout通过重新打开sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)

于 2013-02-26T09:19:23.763 回答