将 STDOUT 和 STDERR 重定向到一个文件,除了 system() 的标准 output/error

Redirecting STDOUT and STDERR to a file, except for standard output/error of system()

我正在尝试 运行 Linux 中的 Perl 脚本并将所有输出记录到 STDOUT 和 STDERR 到一个文件,使用:

open (STDOUT, "| tee -i $transcript_file");
open (STDERR, "| tee -ai $transcript_file");

使用它的脚本大致如下:

  1. 为运行创建工具创建环境。有许多 printwarn 和可能的 die 语句。
  2. 运行 工具(当前使用 system 命令)。这会产生很多输出,我希望这些输出出现在 STDOUT 上,但不会出现在日志文件中(该工具会创建自己的日志文件)。
  3. 分析结果,清理并退出。有许多 printwarn 和可能的 die 语句。

一切正常,除了我想从日志中排除步骤 2 的输出。有没有简单的方法可以做到这一点?

谢谢,

PS:这是我关于Whosebug的第一个问题。如果我没有这样做,请帮助我正确提问。

鉴于您要重新分配 STDINSTDOUT 那么简短的回答是否定的。您正在 STDOUT 上捕获 所有,其中包括您的中间输出。

您可能 close/reopen STDOUT 对于您不想记录的位。 但我建议您改为考虑您要完成的任务 - 'print_and_log' 子例程会执行您想要的操作吗?

我同意 Sobrique 使用特殊功能的建议 print_and_log。但是如果你真的想按照你打算做的方式去做,你可以dupSTDOUTSTDERR,将它们重定向到你的日志然后使用 open3 到 运行 您的工具以及复制的原始标准输出和错误文件描述符

use  IPC::Open3;

# dup the old standard output and error 
open(OLDOUT, ">&STDOUT") or die "Can't dup STDOUT: $!\n";
open(OLDERR, ">&STDERR") or die "Can't dup STDERR: $!\n";

# reopen stdout and stderr
open (STDOUT, "|tee $transcript_file") or die "Can't reopen STDOUT: $!\n";
open (STDERR, ">&STDOUT")              or die "Can't reopen STDERR: $!\n";

# print statements now write to log
print "Logging important info: blah!\n";
print STDERR "OOPS!\n";

# run your command; output will go to original stdout
# this will die() instead of returning say -1, so use eval() to catch errors
my $pid = open3(">&OLDOUT", "<&STDIN", ">&OLDERR", $command); 

# wash those dishes....
waitpid( $pid, 0 );