我有一个程序应该运行一组其他程序并收集它们的输出用于记录目的。只要输出标准输出,一切都正常。
这引出了我的两个问题:
如何在一个文件中捕获另一个程序的STDIN
和STDERR
?
如果根本没有输出(或仅输出到STDERR
),程序将卡在线上:
while (<$input>)
如何使程序等待来自另一个不确定运行时程序的可能输出,并且如果程序完成执行时没有输出,则仍然继续。
以下是代码的该部分
my $pid = open (my $input, '-|', "$prog $args")
or push @errors, "A failute has occurred in $prog $args";
if(not @errors){
while (<$input>){ #POSSIBLE LOCATION FOR HANG UP IF NO PRINTING IS DONE
if($input =~ /^END\n$/){
last;
}
print $fh $_;
}
}
else{
print $fh "An error has occurred with executing \"$prog $args\"";
}
注意:$fh
是我用来写入日志文件的文件处理程序,而@errors
用于在我的程序中内部报告错误。
编辑:
我尝试Proc::Reliable路线时遇到的一个问题是它似乎对STDOUT
和STDERR
产生了后效,我需要在每次调用后修复它们。这导致我的代码中的另一个问题。我正在并行运行,对STDOUT
和STDERR
的任何更改都会影响所有线程(至少使用Windows)。
IO::CaptureOutput对我来说有同样的问题,但它会尝试在内部纠正STDOUT
和STDERR
混乱并导致发生以下错误:
Couldn't remove temp file 'C:\Users\SBLAKE~1\AppData\Local\Temp\m8E3pUGfOS' - Permission denied at C:/Perl/site/lib/IO/CaptureOutput.pm line 82
答案 0 :(得分:1)
看看Proc::Reliable,它似乎就是你想要的。
另见:
答案 1 :(得分:1)
如果从类似POSIX的shell启动,则2>&1
表示法会将标准错误发送到与标准输出相同的位置:
some-program-to-be-logged 2>&1 | perl logger.pl -o /chosen/log.file
标准输出和标准错误都将发送到Perl日志记录脚本的标准输入。
记录器脚本中的输入循环将一直等待,直到有读取输入,或者直到打开管道的所有进程都关闭管道(通常是因为它们退出)。