首页 文章

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

提问于
浏览
2

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

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

svnadmin dump $repo -q >$backupFile

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

处理这种情况的正确方法是什么?

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

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

5 回答

  • 0

    好吧,在perl中也有通用的方法,但是bash解决方案(上面让我认为你正在寻找)是将stderr first 重定向到stdout,然后将stdout重定向到文件 . 直觉上,这并没有在内部发生 . 但这有效:

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

    但是,以另一种方式执行 not (即将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
    
  • 3

    这是一种方式:

    {
        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>&1机制将stderr放到Perl可以轻松读取它的位置,并使用1>来获取发送到文件的转储 . 我写的关于$ /并将stderr作为单个块读取的东西只是为了方便 - 你可以阅读你当然喜欢的stderr .

  • 1

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

  • 7

    这个东西真的很简单 . 这是为了善良而发明的反引号 . 做就是了:

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

    瞧,你已经完成了!

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

  • 4

    perldoc perlopqx

    要分别读取命令的STDOUT和STDERR,最简单的方法是将它们分别重定向到文件,然后在程序完成时从这些文件中读取:system(“program args 1> program.stdout 2> program.stderr”) ;

相关问题