从 Perl 中的输出记录

Posted

技术标签:

【中文标题】从 Perl 中的输出记录【英文标题】:Logging from output in Perl 【发布时间】:2012-08-08 17:47:19 【问题描述】:

我有一个程序应该运行一组其他程序并收集它们的输出以进行日志记录。只要有输出到标准输出,一切正常。

这导致了我的两个问题:

    如何在一个文件中同时捕获另一个程序的STDINSTDERR

    如果根本没有输出(或只输出到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 路由时遇到的一个问题是,它似乎对STDOUTSTDERR 有后遗症,我需要在每次调用运行后修复这些问题。这导致了我的代码中的另一个问题。我正在并行运行,对 STDOUTSTDERR 的任何更改都会影响所有线程(至少使用 Windows)

IO::CaptureOutput 对我来说也有同样的问题,但它试图在内部更正 STDOUTSTDERR 的混乱并导致发生以下错误:

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

【问题讨论】:

How do you capture stderr, stdout, and the exit code all at once, in Perl?的可能重复 【参考方案1】:

如果您从类似 POSIX 的 shell 启动,则 2&gt;&amp;1 表示法会将标准错误发送到与标准输出相同的位置:

some-program-to-be-logged 2>&1 | perl logger.pl -o /chosen/log.file

标准输出和标准错误都发送到 Perl 日志记录脚本的标准输入。

记录器脚本中的输入循环将挂起,直到有输入要读取,或者直到管道打开以进行写入的所有进程都关闭管道(通常是因为它们退出)。

【讨论】:

【参考方案2】:

看Proc::Reliable,好像是你想要的。

另见:

How do you capture stderr, stdout, and the exit code all at once, in Perl? Capture::Tiny IO::CaptureOutput

【讨论】:

以上是关于从 Perl 中的输出记录的主要内容,如果未能解决你的问题,请参考以下文章

无法将所有输出存储到Perl中的数组

Perl脚本记录外部可执行文件输出和错误,但仍然运行

Perl - 从外部进程直接输出到标准输出(避免缓冲)

从 Perl 调用命令,需要查看输出

Perl 5.8 从 SSH 命令获取标准输出

如何从 Perl 输出 UTF-8?