Say I have the following (pointless) Bash function:
myfunc() {
ls
failfailfail
uptime
}
I run it as follows:
myfunc || echo "Something is wrong."
What I want to happen is ls
runs (as it should), failfailfail
does not work (since it doesn't exist), and uptime
doesn't run. The return value of the function would be nonzero, and the error message would be shown. The return value doesn't have to be the exact exit status of the failed command, it just shouldn't be zero.
What actually happens is I get the output of ls
, followed by "-bash: failfailfail: command not found", followed by the output of uptime
. The error message is not shown, because the failed exit status is getting eaten.
set -e
has no useful effect, either within the function or in the scope where the function is called. The only way I can get this to work the way I want is:
myfunc() {
ls || return $?
failfailfail || return $?
uptime || return $?
}
But this seems awfully repetitive and ugly. Is there another way to clean this up?
Best Answer
Under
set -e
, the non-existence offailfailfail
causes the whole script to exit (or the subshell, if the function is executed in a subshell).If you don't need to modify the shell state from the function, you can run it in a subshell.
Another approach in bash is to set an
ERR
trap to executereturn
. If you want to make it a local setting, you need to restore the old trap value, which is a little cumbersome.