如何将STDOUT和STDERR重定向到Perl中的日志文件?

时间:2010-09-29 14:48:06

标签: perl

  

可能重复:
  Can I send STDOUT and STDERR to a log file and also to the screen in Win32 Perl?

我想在完成该过程后将STDOUT,STDERR重定向到 temp_log ,然后重定向到 logfile.txt 。这个过程运行了整整20分钟,因此我想在时间过程运行中涌现 temp_log

2 个答案:

答案 0 :(得分:14)

STDOUTSTDERR只是初始化为程序标准输出和错误的文件句柄,但可以出于任何原因随时重新分配。为此,您需要保存原始设置,以便还原它们。

sub process_that_writes_to_temp_log {

    # save original settings. You could also use lexical typeglobs.
    *OLD_STDOUT = *STDOUT;
    *OLD_STDERR = *STDERR;

    # reassign STDOUT, STDERR
    open my $log_fh, '>>', '/logdirectory/the-log-file';
    *STDOUT = $log_fh;
    *STDERR = $log_fh;

    # ... 
    # run some other code. STDOUT/STDERR are now redirected to log file
    # ...

    # done, restore STDOUT/STDERR
    *STDOUT = *OLD_STDOUT;
    *STDERR = *OLD_STDERR;
}

根据程序的布局方式,可以使用local自动保存和恢复旧的STDOUT / STDERR设置。

sub routine_that_writes_to_log {
    open my $log_fh, '>>', 'log-file';
    local *STDOUT = $log_fh;
    local *STDERR = $log_fh;

    # now STDOUT,STDERR write to log file until this subroutine ends.
    # ...

}

答案 1 :(得分:4)

问题的重定向部分已在Can I send STDOUT and STDERR to a log file and also to the screen in Win32 Perl?中得到解答。即使它说“Win32”,答案也是便携式Perl。

另一部分,即临时文件,在你被它烧了至少一次之前会有点棘手。

  • 将临时文件命名为在运行期间应该是唯一的。包括PID或程序启动时间。您可以使用$filename.$$之类的内容自行完成此操作,但也可以使用File::Temp

  • 如果要将临时日志附加到现有日志,则可能需要创建另一个临时文件以获取整个结果。将整个物体缝合在一起后,将其移动到位。这样你就没有竞争过程改变同一个文件,因为他们都试图将临时日志附加到主文件上。

  • 更好的是,使用类似Log::Log4perl的内容,因为它会为您处理所有细节。