重新打开STDERR/STDOUT以写入带有时间戳的组合日志文件



我基本上想重新打开STDERR/STDOUT,这样他们就可以写入一个日志文件,每行都包含流和时间戳。所以print STDERR "Hello World"打印STDERR: 20130215123456: Hello World。我不想将所有的print语句重写为函数调用,而且一些输出将通过system()调用来自外部进程,无论如何我都无法重写。

我还需要将输出放在"实时"文件中,即不仅在流程完成时写入。

(附言:我并没有特别询问如何生成时间戳的细节,只是询问如何重定向到文件并在字符串前加上前缀)

我已经制定了以下代码,但它很混乱:

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打印。

通过system启动的子级不会写入STDOUT,因为它无法访问程序中的变量。因此,这意味着在Perl文件上运行代码将无法进行写操作(例如tie)。

编写另一个脚本,用管道替换STDOUT和STDERR来运行您的脚本。从这些管道中读取并打印出修改后的输出。我建议使用IPC::Run来完成此操作,因为它可以避免您使用select。如果您将STDOUT和STDERR组合在一个流中,就可以不使用它。

最新更新