Perl 的 $| 的范围是什么?(OUTPUT_AUTOFLUSH)设置?



我有一个 Perl 脚本运行在安装了 Perl 5.8.8 的旧 CentOS 5.6 服务器上。不幸的是,我无法升级操作系统或在此服务器上运行的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 = "$logentryn";
    print $logline;
    open (LOGFILE, ">>$logfile");
    print LOGFILE, "$logline";
    close (LOGFILE);
}

$|的值是否仅影响当前作用域中的输出,即在本例中为脚本的全局作用域?或者,在上面的示例中,它是否也应该立即被 writelog 中的 print 语句刷新以STDOUT/LOGFILE

$|仅影响当前选定的默认输出文件句柄。

您可以为文件句柄显式设置它,例如:

LOGFILE->autoflush(1);

见 http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles

$|不是编译指示;更改$|以"永久"方式更改当前select ed文件句柄中的标志。默认情况下,该句柄是 STDOUT。

您可以使用

use IO::Handle qw( );  # Only required on older versions of Perl.
$handle->autoflush(1);

这是

my $temp = select($handle); $| = 1; select($temp);

除非它尝试处理异常。

根据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

如果你做的不起作用,你应该看看别的地方。

如果将 ssh 重定向到文件,它将不使用伪终端。

所以你可能想用"ssh -t"来强制使用伪终端。

你也可以在perl中使用无缓冲的写入:

syswrite(STDOUT, "Hellon");
syswrite(LOGFILE, $logline);

请注意,在同一文件句柄上混合缓冲和未缓冲写入不是一个好主意。

最新更新