使用tee命令从Python实时获取打印语句

29

我有一个类似于这样的Python脚本:

for item in collection:
    print "what up"
    #do complicated stuff that takes a long time.
在Bash中,我通过以下方式运行此脚本:
$ python my.py | tee my_file.txt

然而,在bash中我只看到一个空白行,直到程序完成。然后,所有的打印语句都一次性出现。

这是tee预期的操作吗?我能否使用tee实时查看输出?


1
这将是一个与Python相关的问题。这是故意的。它只是检测到输出不会进入终端,因此正在缓冲。您需要关闭缓冲。如何做到这一点可能更适合在stackexchange.com上讨论。 - phemmer
1
也许这会有所帮助:http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe - Ketan Maheshwari
1
在顶部添加 "import sys",并在缩进的下一行中添加打印语句 "sys.stdout.flush()"。 - Anthon
参见:https://dev59.com/inVD5IYBdhLWcg3wDHDm - Robᵩ
8
选项"-u"可“强制stdin,stdout和stderr完全不加缓冲”,使用它可以解决你的问题。 - BiBi
1个回答

47

像许多程序一样,Python 试图最小化调用 write 系统调用的次数。它通过在实际写入标准输出文件之前收集多个 print 语句的输出来实现这一点。这个过程被称为缓冲输出。

当 Python 连接到终端时,它不会缓冲其输出。这是有道理的,因为终端上的用户希望立即看到输出。

当 Python 写入文件(或管道)时,它会缓冲其输出。这也是有道理的,因为在进程完成之前没有人会看到输出。

您可以通过在需要强制 Python 将其缓冲输出写入其标准输出文件时调用 sys.stdout.flush() 来打败这种优化。

在您的情况下,请尝试使用以下方法:

import sys
...
for item in collection:
    print "what up"
    sys.stdout.flush()
    #do complicated stuff that takes a long time.

47
很好的解释!我想补充一点,用 -u 标志来调用脚本也可以解决你的问题,例如 python -u my.py | tee my_file.txt。请注意,我的翻译尽可能保持原意,同时使之更通俗易懂,但不包括任何额外信息或解释。 - BiBi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接