Perl:如何在执行期间获得实时更新

时间:2013-07-29 02:18:24

标签: perl

我喜欢让我的脚本打印出进度报告作为执行,以便我可以判断它们是否正在工作以及我需要等待多长时间。但是perl似乎在最后打印所有输出,而不是在执行命令时打印。例如,该程序等待10秒钟,然后同时打印“暂停后暂停”:

print("before pause"); 
sleep 10;
print("after pause");

我也尝试过相同的结果:

my $filename="out";
open(OUT, ">>$filename");
print OUT "before pause";
sleep 10;
print OUT "after pause";

无论我是在本地运行还是提交到群集,都会发生这种情况。

我知道通过运行其他人编写的perl脚本可以实现这一点;但通过查看他们的代码,我无法分辨他们是如何做到的。谁能开导我?谢谢!

2 个答案:

答案 0 :(得分:5)

Perl缓冲输出以提高效率。如果您print到终端,则输出是行缓冲的。使用换行符结束您的信息,以便立即显示:

print "before\n";
sleep 3;
print "after\n";

如果您的输出被重定向(到文件或管道),则使用块缓冲,因为这更有效。这通常没问题(除非你是tail文件)。如果没有,您可以通过将$|变量设置为1来关闭缓冲,同时当前选择要解除缓冲处理的句柄(默认为STDOUT):

local $| = 1;
print "before";
sleep 3;
print "after";

但通常情况下,您应该使用IO :: Handle方法:

$some_handle->autoflush(1);
...;

(见ikegami的回答)。

STDERR输出句柄用于错误或任何其他不是程序主要输出的输出。默认情况下它是无缓冲的,非常适合打印进度报告。这也有效:

print STDERR "before";
sleep 3;
print STDERR "after";

答案 1 :(得分:3)

首先,无缘无故地停止使用全局变量。并至少添加一个关于open是否成功的简单检查。

open(my $OUT, ">>", $filename) or die $!;

您只需关闭缓冲

use IO::Handle;  # Only needed for older versions of Perl
$OUT->autoflush(1);

然后你可以照常打印。

print $OUT "text\n";