1

我喜欢让我的脚本在执行时打印出进度报告,这样我就可以知道它们是否在工作以及我需要等待多长时间。但是 perl 似乎在最后打印所有输出,而不是在执行命令时打印。例如,这个程序等待 10 秒,然后同时打印“before pauseafterpause”:

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 脚本来实现。但是通过查看他们的代码,我无法判断他们是如何做到的。谁能启发我?谢谢!

4

2 回答 2

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";
于 2013-07-29T02:34:21.890 回答
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";
于 2013-07-29T02:20:14.893 回答