From this perldoc page,
-
To capture a command’s STDERR and STDOUT together:
$output = `cmd 2>&1`;
-
To capture a command’s STDOUT but discard its STDERR:
$output = `cmd 2>/dev/null`;
-
To capture a command’s STDERR but discard its STDOUT (ordering is important here):
$output = `cmd 2>&1 1>/dev/null`;
-
To exchange a command’s STDOUT and STDERR in order to capture the STDERR but leave its STDOUT to come out the old STDERR:
$output = `cmd 3>&1 1>&2 2>&3 3>&-`;
I do not understand how 3 and 4 work, and I am not too sure what I understand about 1 and 2 is right. Below is what I understand. Please correct me where I am wrong.
I know that 0, 1 and 2 symbolize STDIN, STDOUT and STDERR.
-
redirect 2 to 1, so that both of them use the same stream now (
&escaped1making sure thatSTDERRdoes not get redirected to a file named1instead) -
redirect 2 (STDERR) to null stream, so that it gets discarded
-
I do not understand this one. Shouldn’t it be just
$output = `cmd 1>/dev/null`;
Also, if the aim is to get the
STDERRmessages atSTDOUT, won’t1>/dev/nullredirect everything to/dev/null? -
What is happening here? What is stream
3? Is it like a temporary variable?
Really, none of this is Perl — all of this is handled by the shell that you’re invoking by using the backticks operator. So your best reading is
man sh, or the Shell chapter of the Unix standard.In short, though, for #4:
3>&1: Open FD 3 to point to where stdout currently points.1>&2: Reopen stdout to point to where stderr currently points.2>&3: Reopen stderr to point to where FD 3 currently points, which is where stdout pointed before the previous step was completed. Now stdout and stderr have been succesfully swapped.3>&-: Close FD 3 because it’s not needed anymore.