【问题标题】:Redirecting STDOUT and STDERR to a file, except for standard output/error of system()将 STDOUT 和 STDERR 重定向到文件,除了 system() 的标准输出/错误
【发布时间】:2015-02-06 11:30:36
【问题描述】:

我正在尝试在 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:这是我关于 stackoverflow 的第一个问题。如果我还没有这样做,请帮助我正确提问。

【问题讨论】:

  • 很好的问题。一般来说:不要在标题中使用标签名称(“perl”)。我改了标题说明编程问题,而不是你想用它达到的效果。

标签: perl io-redirection


【解决方案1】:

我同意 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 );

【讨论】:

  • 嗯,思路不错。没有考虑过这种方法。当然可以很好地完成一些更复杂的任务。
  • 谢谢,效果很好。捕获 shell 脚本的返回值(退出 EXITCODE)需要一些时间,但使用 $? >> 255 帮助您按照您的建议使用 eval..
【解决方案2】:

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

您可能会关闭/重新打开 STDOUT 以获取您不希望它记录的位。 但我建议您可能要考虑您要完成的工作 - 'print_and_log' 子例程会做您所追求的吗?

【讨论】:

  • system 调用总是写入文件描述符 1 和 2。这些通常对应于 Perl 中的 STDOUTSTDERR,但可以操作它们以映射到其他文件描述符。
  • 不完全是。使用 STDOUT 和 STDERR 进行操作只会对 Perl 中的大多数内部打印产生任何影响。不幸的是,它不会影响外部调用的命令。只有物理重新打开在任何地方都有效,系统流 1 和 2 必须重新打开并分配到选定的流、文件、终端或 .... /dev/null 。
猜你喜欢
  • 2014-07-22
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
相关资源
最近更新 更多