Reputation: 4186
I was under impression that exit
would terminate the current bash script no matter what, and had the following error handler at the top of my script:
function err {
printf "\e[31m$1\e[0m\n" 1>&2
exit 1
}
It worked like a charm for most cases until this line:
item=$(myfunc $1)
Normally, that line works fine, with the STDOUT of myfunc dumped into $item
, as intended. The problem arises when myfunc
throws an error, via the err
function seen above. The $()
ends up swallowing the non-zero return and guarding the exit from exiting the script itself. If I understand correctly, the problem is that $()
actually spawns a new subshell (just like the deprecated backticks), but I know of no other way to capture the output of a function into a variable in bash that allows the exit
to work.
I tried using set -e
as well, and had no luck with that either. Can someone suggest how to build my error handler so that it exits the script even in these cases?
Upvotes: 3
Views: 412
Reputation: 121
for what it's worth you also can't use bash short circuit evaluation to test the exit status of the function. It tests the assignment to the variable instead.
eg. while
[[ $(myfunc "$1") ]] && echo success || echo failure
or
[[ myfunc "$1" ]] && echo success || echo failure
are fairly common and might do what's expected,
[[ item=$(myfunc "$1") ]] && echo success || echo failure
Always returns success even if myfunc returns non zero. You have to use if then else to test the exit status.
Upvotes: 0
Reputation: 753990
You can test the result of the assignment:
if item=$(myfunc "$1")
then : Function worked
else : Function failed
fi
This tests the exit status of the command run in the sub-shell that the $(…)
uses.
Without actually using functions, you can experiment with:
$ if item=$(echo Hi; exit 1); then echo "$item - OK"; else echo "$item - OH"; fi
Hi - OH
$ if item=$(echo Hi; exit 0); then echo "$item - OK"; else echo "$item - OH"; fi
Hi - OK
$
Or, if functions are deemed crucial, then:
$ err() { exit $1; }
$ myfunc() { echo Mine; err $1; }
$ if item=$(myfunc 1); then echo "$item - OK"; else echo "$item - OH"; fi
Mine - OH
$ if item=$(myfunc 0); then echo "$item - OK"; else echo "$item - OH"; fi
Mine - OK
$
Tested using Bash 3.2.57 on Mac OS X 10.11 El Capitan.
Upvotes: 5