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 STD开发者_开发技巧ERR:
$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 (
&
escaped1
making sure thatSTDERR
does not get redirected to a file named1
instead)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
STDERR
messages atSTDOUT
, won't1>/dev/null
redirect 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.
Though documented in the perldocs, the redirection is all standard linux redirection. You understand 1 and 2 correctly.
3) Only STDOUT is normally caught by a basic redirect (>
), so the original STDOUT must be discarded, and STDERR must be send to STDOUT.
4) cmd 3>&1 1>&2 2>&3 3>&-
is equivalent to
var tmp = STDOUT;
STDOUT = STDERR;
STDERR = tmp;
delete tmp;
Normally we have this:
1-->STDOUT
2-->STDERR
2>&1
redirects file descriptor fd2
to fd1
1-->STDOUT
/
2./
2>/dev/null
redirects fd2
to /dev/null
.
1-->STDOUT
2-->/dev/null
2>&1 1>/dev/null
redirects fd2
to fd1
, and then redirects fd1
to /dev/null
/dev/null
/
1./ STDOUT
/
2./
3>&1 1>&2 2>&3 3>&-
- first directs a new fd 3 to wherever fd 1 is currently pointing (STDOUT).
- then redirects fd1 to wherever fd2 is current pointing (STDERR),
- then redirects fd 2 to wherever fd 3 is currently pointing (STDOUT)
- then closes fd3 (3>&- means close file descriptor 3).
The whole thing effectively swaps fd1 and fd2. fd3 acted as a temporary variable.
1 --STDOUT
X
2 `-STDERR
See the docs for more information on IO redirection.
3.Nope. The ordering matters, so it gets rid of the original stdout, then it moves stderr to stdout.
4.3
is just another file descriptor, same as the first 3. Most processes can use a total of 256 different file descriptors.
精彩评论