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

Cia*_*anH 6 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"
Run Code Online (Sandbox Code Playgroud)

当调用时./test_grep.py | grep message,10秒内不会出现任何内容,此时将显示所有三行.

将其与脚本进行比较test_grep.sh:

#!/usr/bin/env bash
echo "message1"
sleep 5 
echo "message2"
sleep 5
echo "message3"
Run Code Online (Sandbox Code Playgroud)

./test_grep.sh | grep message会立即输出message1,随后在5秒的时间间隔message2message3.

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

cni*_*tar 8

你能行的:

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

你甚至可以打电话python -u来禁用缓冲.


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

open(file, mode='r', buffering=-1 ....)
Run Code Online (Sandbox Code Playgroud)

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

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


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

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