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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With