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.
# ...
}
2 回答
STDOUT
和STDERR
只是初始化为程序标准输出和错误的文件句柄,但可以出于任何原因随时重新分配它们 . 为此,您需要保存原始设置,以便还原它们 .根据程序的布局方式,可以使用
local
自动保存和恢复旧的STDOUT / STDERR设置 .您的问题的重定向部分已在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这样的东西,因为它会为你处理所有细节 .