问题
I need to capture the output and error of a command in my bash script and know whether the command succeeded or not.
At the moment, I am capturing both like this:
output=$(mycommand 2>&1)
I then need to check the exit value of mycommand. If it failed, I need to do some stuff with the output, if the command succeeded, I don't need to touch the output.
Since I am capturing the output, checking $? is always a 0 since bash succeeded at capturing the output into the variable.
This is a very time sensitive script, so we are trying to avoid any slower solutions like outputting to a file and re-reading it in.
If I could capture stdout to one variable and stderr to another, that would solve my problem because I could just check if the error variable was empty or not.
Thanks.
回答1:
What version of bash
are you using? The capture of the output has zero effect on the return code with my version, 4.1.5
:
pax> false; echo $?
1
pax> echo $?
0
pax> x=$(false 2>&1) ; echo $?
1
It's not always a good idea to rely on standard error being non-empty to detect errors. Many programs don't output errors but rely solely on the return code.
回答2:
The problem only seems to manifest when the output is captured to a local variable within a function:
$ echo $BASH_VERSION
3.2.48(1)-release
$ false; echo $?
1
$ echo $?
0
$ x=$(false 2>&1) ; echo $?
1
$ function f {
> local x=$(false 2>&1) ; echo $?
> }
$ f
0
$ function g {
> x=$(false 2>&1) ; echo $?
> }
$ g
1
Notice that only function f, which captures x to a local, can express the behavior. Particularly, function g which does the same thing, but without the 'local' keyword, works.
One can therefore not use a local variable, and perhaps 'unset' it after use.
EDIT NVRAM points out that the local declaration can be made beforehand to avoid the issue:
$ function h {
> local x
> x=$(false 2>&1) ; echo $?
> }
$ h
1
来源:https://stackoverflow.com/questions/3632603/bash-variable-capture-stderr-and-stdout-separately-or-get-exit-value