【问题标题】:Perl: redirect output both to file and console, keeping return codePerl:将输出重定向到文件和控制台,保留返回码
【发布时间】:2012-02-10 06:08:13
【问题描述】:

我有问题。在我的 Perl 脚本中,我执行了一个 java 程序,它同时打印到 stdout 和 stderr 流。您能否就如何将stderr 重定向到仅文件和stdout 重定向到同一个文件和控制台给出一个平静的建议。 tee 在这里不适用,因为我还需要 java 程序的返回码。有什么想法吗?

提前致谢!

【问题讨论】:

    标签: perl file redirect console


    【解决方案1】:

    使用 IPC::Open3 调用 java 程序。使用 IO::Select 从文件句柄中读取。自己写。

    IPC::Open3 为您执行 fork() 和 exec(),因此您可以使用 waitpid 获得返回值。

    【讨论】:

      【解决方案2】:

      您不能直接从 shell 中执行此操作(没有 tee)。

      也许您可以重定向到一个文件,然后从 perl 脚本中打开该文件并打印到控制台。比如:

      use Path::Class; # Handy module, but you can do without
      
      my $retvar = system("java -jar prog.jar >stdout.log 2>stderr.log ");
      
      my $output = file('.', 'stdout.log')->slurp();
      print $output; # or print STDERR $output;
      

      希望这会有所帮助。它仍然保持文件分离,这可能不是你想要的。

      米歇尔。

      【讨论】:

      • 感谢您的意见,米歇尔。这不是我真正想要的,但似乎不可能做到我需要的。
      【解决方案3】:

      考虑这样做:

       perl -le 'qx(java -jar prog.jar>output.log 2>&1);$rc=$?;print "rc=",$rc<0 ? -1:$rc>>8'
      

      这会将 STDOUT 和 STDERR 重定向到您的文件中,并捕获并打印返回代码。根据需要检查(或cat)到控制台的输出文件。查看qxsystem 了解更多信息。

      更新:另一种方式是这样的(即次要写入输出文件):

      my $msg=qx(java -jar prog.jar 2>&1);
      my $rc=$? < 0 ? -1 : $? >>8, "\n";
      print  $msg, "rc=$rc\n";
      open my $fh, '>', 'output.log' or die "$!\n";
      print  {$fh} $msg, "rc=$rc\n";
      

      【讨论】:

      • 一切正常,但控制台没有输出,很遗憾。
      • 不,没有输出到控制台。正如我所说,您可以 cat(在 shell 中)或将输出文件打印到控制台。如果/仅输出文件不为空(大小>0),您可能会这样做。
      【解决方案4】:

      您可以尝试通过将 stderr 重定向到 stdout 来跟踪。

      my $retvar = system("java -jar prog.jar 2>&1  > output.log ");
      

      【讨论】:

      • 是的,我试过了,但我也想在控制台中从 java 输出。我无法解决的问题。
      • 使用三通 - my $retvar = system("java -jar prog.jar |tee file.txt 2&gt;&amp;1 &gt; output.log ");
      • tee 阻止我获得返回码,这有助于我了解 java 代码是如何完成他的工作的。
      【解决方案5】:

      如果您在 *nix 下,您应该查找“tee”命令。

      你可能应该这样做:

      perl script.pl 2>stderr.out | tee stdout.out
      

      【讨论】:

      • 不,这不是我要找的。我只需要为 java 程序输出进行重定向。而且条件是我不能在 perl 脚本执行语句中添加任何内容。
      • 好吧,那么您可能可以使用 IPC::Open3 模块中的“open3”函数。它应该允许您为 STDIN、STDOUT 和 STDERR 打开单独的句柄,并且您应该能够逐行读取来自 STDOUT 和 STDERR 句柄的 Java 程序输出,并在需要时将其写入文件。跨度>
      • CPAN 的文档中有一个关于如何使用 open3 捕获进程退出代码的示例。
      【解决方案6】:

      Bash 包含一个选项 pipefail 让管道返回最右边的失败代码而不是最右边的退出代码。

      您也许可以使用类似的方法在设置了pipefail 的 bash 中运行您的命令。

      my $ret = system( q{bash -c 'set -o pipefail; java command 2>>~/test_file | tee -a ~/test_file'} );
      

      【讨论】:

        猜你喜欢
        • 2015-04-20
        • 1970-01-01
        • 2023-03-19
        • 2021-10-21
        • 1970-01-01
        • 2013-12-07
        • 1970-01-01
        • 1970-01-01
        • 2013-11-14
        相关资源
        最近更新 更多