在将STDOUT传送到文件时捕获STDERR的输出

时间:2012-02-03 17:27:13

标签: perl

我有一个相当奇怪的情况。我试图使用Perl自动备份SVN存储库集合。我将shell转发到svnadmin dump命令,该命令将转储发送到STDOUT,以及它遇到的任何STDERR错误。

我需要运行的命令将采用以下形式:

svnadmin dump $repo -q >$backupFile

STDOUT将转到备份文件,但是,我需要在我的Perl脚本中捕获STDERR。

接近这种情况的正确方法是什么?

编辑: 澄清: STDOUT将包含SVN转储数据 STDERR将包含可能发生的任何错误

STDOUT需要以文件结尾,而STDERR需要以Perl结尾。在任何情况下都没有任何东西,但STDOUT的原始内容最终会在该流中转储或转储将被破坏,我会有比没有备份更糟糕的东西,一个糟糕的东西!

5 个答案:

答案 0 :(得分:7)

嗯,有一些通用的方法也可以在perl中完成,但是bash解决方案(上面让我认为你正在寻找)是将stderr 首先重定向到stdout然后重定向stdout到一个文件。直觉上,除非你看到内部发生的事情,否则这并没有多大意义。但这有效:

svnadmin dump $repo -q 2>&1 >$backupFile

但是,以其他方式执行此操作(即,将2>& 1放在最后),否则stdout和stderr的所有输出都将转到您的文件中。

编辑,以避免一些人的混淆,这不起作用:

你想要的是这个:

# perl -e 'print STDERR "foo\n"; print "bar\n";' 2>&1 > /tmp/f 
foo
# cat /tmp/f
bar

具体而言,你不希望这样:

# perl -e 'print STDERR "foo\n"; print "bar\n";' > /tmp/f 2>&1
# cat /tmp/f
foo
bar

答案 1 :(得分:4)

以这种方式:

{
    local $/;   # allow reading stderr as a single chunk

    open(CMD, "svnadmin dump $repo -q 2>\&1 1>$backupFile |") or die "...";
    $errinfo = <CMD>;    # read the stderr from the above command
    close(CMD);
}

换句话说,使用shell 2&gt;&amp; 1机制将stderr送到Perl可以轻松读取它的地方,并使用1&gt;获取发送到文件的转储。我写的关于$ /并将stderr作为单个块读取的内容仅仅是为了方便 - 你可以阅读你当然喜欢的stderr。

答案 2 :(得分:3)

虽然tchrist肯定是正确的,你可以使用手柄方向和反引号来完成这项工作,但我也可以推荐David Golden的Capture::Tiny模块。它提供了捕获或发送STDOUT和STDERR的通用接口,你可以用它来做它们。

答案 3 :(得分:1)

这些东西真的很容易。这是为了善良而发明的反引号。只是做:

$his_error_output = `somecmd 2>&1 1>somefile`;

vo you you you!!!

我不明白麻烦是什么。没有像Jethro那样以小孩的方式钻进你的gazzintas吗? :)

答案 4 :(得分:0)

来自qx的{​​{1}}:

  

要分别读取命令的STDOUT和STDERR,它就是   最简单的方法是将它们分别重定向到文件,然后从这些文件中读取   程序完成后的文件:

     
      
  1. system(“program args 1&gt; program.stdout 2&gt; program.stderr”);
  2.