我在安装了Perl 5.8.8的旧CentOS 5.6服务器上运行Perl脚本。遗憾的是,我无法升级操作系统或在此服务器上运行的Perl版本。
当我从命令提示符运行此脚本时,尽管脚本顶部(在全局范围内)有一个$| = 1;
语句,但它仍然似乎缓冲输出到控制台(在ssh会议上)。
写入日志文件和STDOUT
都由函数执行,例如:
#!/usr/bin/perl
$| = 1;
&writelog("Started...");
# Do work with lots of writelog'ing
&writelog("...Done.");
exit(0);
sub writelog {
# This is greatly simplified for the purpose of this question
my ($logentry) = @_;
my $logfile = "/var/log/thelog.log";
my $logline = "$logentry\n";
print $logline;
open (LOGFILE, ">>$logfile");
print LOGFILE, "$logline";
close (LOGFILE);
}
$|
的值是否仅影响当前范围内的输出,即在这种情况下脚本的全局范围?或者,在上面的示例中,是否应该通过STDOUT
中的LOGFILE
语句立即刷新print
/ writelog
?
答案 0 :(得分:8)
$|
仅影响当前选定的默认输出文件句柄。
您可以将其显式设置为文件句柄,如:
LOGFILE->autoflush(1);
请参阅http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles
答案 1 :(得分:7)
$|
不是一个pragma;更改$|
会更改"永久"中当前select
ed文件句柄中的标记。时尚。默认情况下,该句柄是STDOUT。
您可以使用
影响其他文件句柄use IO::Handle qw( ); # Only required on older versions of Perl.
$handle->autoflush(1);
这是
的快捷方式my $temp = select($handle); $| = 1; select($temp);
除了它试图处理异常。
答案 2 :(得分:2)
每perlvar
,$|
具有全局范围,仅适用于当前选定的输出通道。这是STDOUT
在任何程序的开头,但可以通过1-arg select
调用进行更改。
$| = 1; # set autoflush on STDOUT
open LOGFILE, '>log';
my $fh = select LOGFILE; # change "selected output channel"
$| = 1; # set autoflush on LOGFILE
select $fh; # restore STDOUT as "selected output channel"
$| = 0; # turnoff autoflush on STDOUT
答案 3 :(得分:0)
如果你做的不起作用,你应该看看其他地方。
如果将ssh重定向到文件,则不会使用伪终端。
所以你可能想要使用" ssh -t"强制使用伪终端。
您还可以使用perl中的无缓冲写入:
syswrite(STDOUT, "Hello\n");
syswrite(LOGFILE, $logline);
请注意,在同一个文件句柄上混合缓冲和非缓冲写入并不是一个好主意。