對於我來說,在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