1

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

我还需要将输出放置在“live”文件中,即不仅在进程完成时写入。

(ps我不是特别询问如何生成时间戳的详细信息,只是如何重定向到文件并添加字符串)

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

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

4

1 回答 1

2

via 启动的子进程system不会写入,STDOUT因为它无权访问程序中的变量。因此,意味着让代码在 Perl 文件句柄写入(例如tie)上运行是行不通的。

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

于 2013-02-15T02:30:15.030 回答