对于我来说,在Perl中通常足以让包含STDOUT和STDERR的单个字符串。我这样做:Perl:与STDOUT分开获取系统调用的STDERR
my $stdout_and_stderr = `$cmd 2>&1`;
但现在我需要它在2个单独的字符串 - 一个用于标准输出和一个用于STDERR。
我该怎么在Perl中做到这一点?
对于我来说,在Perl中通常足以让包含STDOUT和STDERR的单个字符串。我这样做:Perl:与STDOUT分开获取系统调用的STDERR
my $stdout_and_stderr = `$cmd 2>&1`;
但现在我需要它在2个单独的字符串 - 一个用于标准输出和一个用于STDERR。
我该怎么在Perl中做到这一点?
use IPC::Run3 qw(run3);
run3 [ 'sh', '-c', $cmd ], undef, my $stdout, my $stderr;
这里是一个例子。
#!/usr/bin/perl
use warnings;
use strict;
use IPC::Open3;
my $cmd = 'ls -la';
my $pid = open3(\*WRITER, \*READER, \*ERROR, $cmd);
#if \*ERROR is 0, stderr goes to stdout
while(my $output = <READER>)
{
print "output->$output";
}
while(my $errout = <ERROR>)
{
print "err->$errout";
}
waitpid($pid, 0) or die "$!\n";
my $retval = $?;
print "retval-> $retval\n";
其实我发现了一个更简单的方法只捕获STDERR。抓STDERR扔STDOUT远:
$output = `cmd 2>&1 1>/dev/null`;
你也可以做相反的事情 - 扔STDERR远,使得它甚至没有印到shell:
$output = `cmd 2>/dev/null`;
如果您需要捕捉两个他们分开,在这个线程中使用其他答案之一。他们非常好
虽然这并不回答这个问题(因此不应该被接受的答案)。问题是如何分别捕获STDOUT和STDERR。你的回答忽略STDOUT,只捕获STDERR。 – 2015-09-11 23:13:08
你说得对。相应地更改了接受的答案 – SomethingSomething 2015-09-12 18:43:57
谢谢!很棒。另外感谢你的详细和完整的例子 – SomethingSomething 2015-02-10 08:57:25
这个程序患有竞争条件。如果孩子输出很多STDERR,两个程序都会锁定。改为使用IPC :: Run3或IPC :: Run。 – ikegami 2015-02-10 15:43:01
@ikegami,谢谢你的重要提示。你可以在这里写下你的解决方案吗? – SomethingSomething 2015-02-11 08:19:33