我基本上想要重新打开STDERR / STDOUT,以便它们写入一个日志文件,其中每个行都包含流和时间戳。因此print STDERR "Hello World"
会打印STDERR: 20130215123456: Hello World
。我不想将所有的print语句重写为函数调用,也有些输出将通过system()
调用来自外部进程,无论如何我都无法重写。
我还需要将输出放在“实时”文件中,即不仅在过程完成时写入。
(p.s。我不是特别要求详细说明如何生成时间戳,如何重定向到文件并添加字符串)
我已经制定了以下代码,但它很混乱:
my $mode = ">>";
my $file = "outerr.txt";
open(STDOUT, "|-", qq(perl -e 'open(FILE, "$mode", "$file"); while (<>) { print FILE "STDOUT: \$\_"; }'));
open(STDERR, "|-", qq(perl -e 'open(FILE, "$mode", "$file"); while (<>) { print FILE "STDERR: \$\_"; }'));
(以上不会添加日期,但添加日期应该很简单)
我正在寻找一种更清晰的解决方案,一种不需要引用perl代码并在命令行上传递它的方法,或者至少是隐藏一些复杂性的模块。看看Capture::Tiny的代码,看起来它不能处理写入输出的一部分,尽管我不确定。遗憾的是,annotate-output
仅适用于外部命令,我需要使用它来处理外部命令和普通perl打印。
答案 0 :(得分:2)
通过system
启动的子代不会写入STDOUT
,因为它无法访问程序中的变量。因此,在Perl文件句柄写入(例如tie
)上运行代码意味着无效。
编写另一个运行脚本的脚本,其中STDOUT和STDERR替换为管道。从这些管道中读取并打印出修改后的输出。我建议使用IPC :: Run来执行此操作,因为这样可以避免使用select
。如果将STDOUT和STDERR合并在一个流中,则可以在没有它的情况下离开。