我正在尝试合并Perl脚本的STDOUT和STDERR流,并将其分解为日志文件。
open( MERGED, "|-", "tee /tmp/my.log" );
*STDOUT = *MERGED;
*STDERR = *MERGED;
print "1: print\n";
warn "2: warn\n";
system "echo 3: system call";
在此示例中,“打印”和“警告”消息同时出现在终端和日志中,而系统调用仅出现在终端中。
如何将输出流拆分为日志文件?
注意:只需要在Unix中工作,我不想依赖不属于标准Perl发行版的软件包(例如File :: Tee,IO :: Tee ..)。
答案 0 :(得分:3)
子程序对Perl的变量一无所知。如果要重定向子项的标准输出,则需要重定向文件描述符1。
open(my $MERGED, "|-", "tee", "/tmp/my.log") or die $!;
open(STDOUT, '>&', $MERGED) or die $!;
open(STDERR, '>&', $MERGED) or die $!;
答案 1 :(得分:1)
仅供参考:根据ikegami的建议,我提出了以下建议:
$| = 1;
# Hold on to the original handles
open(my $STDOUT_ORIG, '>&', \*STDOUT) or die $!;
open(my $STDERR_ORIG, '>&', \*STDERR) or die $!;
# Fork to log
open( my $ONE, "|-", "tee /tmp/my0.log" ) || die $!;
open( STDOUT, '>&', $ONE ) || die $!;
open( STDERR, '>&', $ONE ) || die $!;
# Make some noise
print "1: print\n";
warn "2: warn\n";
system "echo 3: system call";
# Unhook from the first `tee`
open( STDOUT, '>&', $STDOUT_ORIG ) || die $!;
open( STDERR, '>&', $STDERR_ORIG ) || die $!;
close($ONE);
# Fork to next log
open( my $TWO, "|-", "tee /tmp/my1.log" ) || die $!;
open( STDOUT, '>&', $TWO ) || die $!;
open( STDERR, '>&', $TWO ) || die $!;
print "A: print\n";
warn "B: warn\n";
system "echo C: system call";
close(STDERR);
close(STDOUT);