首页 文章

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

提问于
浏览
5

可能重复:我可以将STDOUT和STDERR发送到日志文件,也可以发送到Win32 Perl中的屏幕吗?

我想在程序完成后将STDOUT,STDERR重定向到temp_log,然后重定向到logfile.txt . 该过程运行完整20分钟,因此我想在时间进程运行中flock temp_log .

2 回答

  • 4

    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.
        # ...
    
    }
    
  • 11

    您的问题的重定向部分已在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这样的东西,因为它会为你处理所有细节 .

相关问题