In a bash function, I'm trying to capture the output of a command along with it's exit code. Generally, my form is
some_function() {
local rv=$(some_other_function)
local code=$?
echo "$rv"
return $code
}
but I notice that whenever I use 'local', then $? is ALWAYS 0. Like it's capturing the result of the assignment, not the called function. If I don't use 'local', then it works as expected:
$ foo() { local rv=$(false); echo "code is $?"; }
$ foo
code is 0
$ foo() { rv=$(false); echo "code is $?"; }
$ foo
code is 1
Can someone explain this to me? Obviously something fundamental here I just don't understand.
Can someone explain this to me?
In simple words most of the time $?
has the exit status of last command executed. The last command is local
. The return status of local
is zero - it successfully made rv
a local variable. Stupid example:
echo $(false) $(true) $(false)
^^^^ - this is the last command executed
# $? here has exit status of **echo**
Separate the assignment from local
:
local rv code
# Assignment is not a "command", in the sense it preserves exit status.
# The last command executed in assignment is the one inside `$(...)`.
rv=$(some_other_function)
code=$? # will have the exit status of expression executed inside $(...)
Check your scripts with http://shellcheck.net . Shellcheck warns about such mistakes.