如何在脚本仍在运行时使Shell输出重定向(>)写入文件?

10

我写了一个不会停止的简短脚本。该脚本持续产生输出,我需要不时地检查它。我通过SSH在实验室计算机上运行它,并将输出重定向到该机器上我的public_html文件夹中的一个文件。

python script.py > ~/public_html/results.txt

但是,当我刷新地址时,结果不会立即显示出来。结果会在我终止程序后显示,但正如我所说,它本身并不停止。这个重定向(>)是否在写入时很懒惰?有没有办法以连续的方式(或间隔)更新文件中的结果?

还是Web服务器在文件仍在编写时不更新文件?

3个回答

16

如果您想立即看到输出结果,您需要刷新输出 sys.stdout.flush()(或其他方法)。请参见这里


哦,谢谢,我会立刻尝试。我没想到是 Python 缓冲输出。--编辑:我尝试了,没有任何区别。所以要么是 > 缓冲,要么是 Web 服务器。 - noio
不用在意之前的评论,我只是有点不耐烦。它仍然不是“实时”的,但那可能是浏览器缓存的原因。 - noio

7

stdout是有缓冲区的,如果没有连接到终端。

您可以通过stdbuf将其更改为行缓冲策略。

stdbuf -oL python script.py > ~/public_html/results.txt

如果不需要行缓冲,您可以在Python脚本中避免刷新并保持IO效率。


如果很少调用,这是否比Python的flush()效率低?我现在使用flush(),每行调用不到一次。 - noio
我怀疑不会有什么区别,因为如果你不使用flush(3),数据很可能不会写入磁盘。如果您在终端上使用应用程序,则行缓冲将是默认设置。对于长时间运行的后台作业,重定向到文件将选择更有效的缓冲方式。对于像您这样的特殊情况,您可以始终使用stdbuf,从而使IO代码脱离您的应用程序,使其更灵活和易读。 - Jürgen Hötzel
1
在Ubuntu上,我在哪里可以找到stdbuf?它似乎没有包含在coreutils软件包中。 - simao
我实际上更喜欢这个答案,因为它更通用,不需要修改源代码。(或者更技术性地说,它绝对是球状的。) - Eric Cousineau

1

我怀疑该文件正在持续写入,但是Web服务器报告的文件修改日期是打开文件的时间,因此报告文件未发生任何更改并且结果被缓存(在Web服务器或客户端)。

首先尝试强制重新加载(Ctrl + F5或Ctrl + Shift + R或Shift + <reload_button>),看看是否有帮助。如果没有,那么您可以尝试其他方法。

在服务器上的单独shell中执行以下操作:

tail -f ~/public_html/results.txt

Tail命令可以打印文件的最后n行内容(其中n默认为10),但带有-f参数的话,它会监视该文件并在文件增长时持续报告输出。这可以让您至少确认该文件正在逐步写入。

希望这可以帮到你。


谢谢,nc3b的解决方案起作用了。Tail 显示最新写入的结果。浏览器视图现在每隔一段时间批量更新。强制刷新也无法改变这一点。但速度足够快。 - noio

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