有没有办法从当前正在执行的python程序逐行输出管道?

时间:2013-02-26 09:15:46

标签: python bash grep pipe

当将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,然后按message2message3的间隔输出5秒。

我希望这是因为只有python解释器完成执行后才能获得下一个命令的输出。有没有办法改变这种行为?

1 个答案:

答案 0 :(得分:8)

你可以这样做:

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

您甚至可以拨打python -u来禁用缓冲。


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

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

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

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


  

你如何“将stdout设置为行缓冲”?

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

相关问题