我成功地使用IO::Tee
将打印消息发送到stdout和日志文件。我还希望能够从系统()命令捕获和发送stdout和stderr到同一个文件。
我尝试了重定向和/或管道的各种组合,没有运气
简单的脚本很少注释失败的尝试...
#!/usr/bin/env perl
use IO:Tee;
my $teelog = "tee.log"
open my $tee, ">", $teelog or die "open tee failed.\n";
my $tee = new IO:Tee(\*STDOUT, $tee);
print $tee "First line in log\n";
# This command should work. I want the date to go to screen and tee.log
#system("date | tee -a ${teelog}"); <- nothing goes to tee.log
#system("date >& ${teelog}") <- clobbers tee.log
#system("date >& $tee") <- generates syntax errors
# This command should fail. I want error msg to go to screen and tee.log
#system("jibberish | tee -a ${teelog}"); <- nothing goes to tee.log
#system("jibberish >& ${teelog}") <- clobbers tee.log
system("kibberish >& $tee") <- generates syntax errors
print $tee "Last line in log\n";
exit;
Perl缓冲输出到$tee
文件句柄,并且在你进行写入同一文件的$tee
调用后,system
的光标位置没有被调整,因此Perl可能会覆盖system
调用写入文件的任何输出。
像这样的一系列调用更安全。你可以通过更明智的寻求和冲洗来更简洁。
use IO:Tee;
my $teelog = "tee.log"
open my $tee, ">", $teelog or die "open tee failed.\n";
$tee = new IO:Tee(\*STDOUT, $tee);
print $tee "First line in log\n";
close $tee;
system("date | tee -a ${teelog}");
system("jibberish 2>&1 | tee -a ${teelog}");
open $tee, ">>", $teelog or die "open tee failed.\n"; # append mode
$tee = new IO:Tee(\*STDOUT, $tee);
print $tee "Last line in log\n";
exit;
谢谢你们对这个解释和建议的看法。
我还发现在IO中使用capture_exec的另一种方式:CaptureOutput。我用一个看起来像这样的子测试了它....
sub tee_sys_cmd {
(my $cmd) = @_;
print $tee "Executing... \"$cmd\"\n";
my ($stdout, $stderr, $success, $exit_code) = capture_exec($cmd);
print $tee "$stdout\n$stderr\n";
return;
}
这似乎也有效。
你丢弃了system
返回的状态,所以我会改用反引号:
print $tee `date`