可能重复:
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 。
答案 0 :(得分:14)
STDOUT
和STDERR
只是初始化为程序标准输出和错误的文件句柄,但可以出于任何原因随时重新分配。为此,您需要保存原始设置,以便还原它们。
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的内容,因为它会为您处理所有细节。