我有一个相当奇怪的情况。我试图使用Perl自动备份SVN存储库集合。我将shell转发到svnadmin dump命令,该命令将转储发送到STDOUT,以及它遇到的任何STDERR错误。
我需要运行的命令将采用以下形式:
svnadmin dump $repo -q >$backupFile
STDOUT将转到备份文件,但是,我需要在我的Perl脚本中捕获STDERR。
接近这种情况的正确方法是什么?
编辑: 澄清: STDOUT将包含SVN转储数据 STDERR将包含可能发生的任何错误
STDOUT需要以文件结尾,而STDERR需要以Perl结尾。在任何情况下都没有任何东西,但STDOUT的原始内容最终会在该流中转储或转储将被破坏,我会有比没有备份更糟糕的东西,一个糟糕的东西!
答案 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,它就是 最简单的方法是将它们分别重定向到文件,然后从这些文件中读取 程序完成后的文件:
- system(“program args 1&gt; program.stdout 2&gt; program.stderr”);
醇>