我成功使用了
IO::Tee
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;
答案 0 :(得分:1)
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;
答案 1 :(得分:0)
感谢你们的解释和建议。
我还发现在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;
}
这似乎也有效。
答案 2 :(得分:-1)
您正在放弃system
返回的状态,因此我会使用反引号:
print $tee `date`