将Perl的系统调用输出写入文件

时间:2014-05-26 15:49:11

标签: perl file-descriptor

我正在尝试合并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 ..)。

2 个答案:

答案 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);