So I like to harden my bash scripts wherever I can (and when not able to delegate to a language like Python/Ruby) to ensure errors do not go uncaught.
In that vein I have a strict.sh, which contains things like:
set -e
set -u
set -o pipefail
And source it in other scripts.
However, while pipefail would pick up:
false | echo it kept going | true
It will not pick up:
echo The output is '`false; echo something else`'
The output would be
The output is ''
False returns non-zero status, and no-stdout. In a pipe it would have failed, but here the error isn't caught. When this is actually a calculation stored in a variable for later, and the value is set to blank, this may then cause later problems.
So – is there a way to get bash to treat a non-zero returncode inside a backtick as reason enough to exit?
Best Answer
Solution
If you are running Bash 4.4 or later, you can use the
shopt
optioninherit_errexit
to do just that. You can check compatibility from within Bash usingecho $BASH_VERSION
.Here is the shebang you would use if Bash 4.4 or later were installed and came before
/bin
in your$PATH
:The
-S
is there to coax Linux’senv
into accepting more than one argument forbash
, as kindly pointed out by @UVV and explained further on StackOverflow.Background
inherit_errexit
is an option toshopt
, while the rest of the arguments are options toset
. In most modern iterations, they can be passed directly tobash
when invoking the shell.Let’s review the options you have already been using:
-u
/-o nounset
, as the name ambiguously hints, disallows dereferencing of variables that have not been set; e.g.,$IJUSTMADETHISUP
.-e
/-o errexit
does some of what you are requesting: it causes directly called shell commands with nonzero return values to cause the shell to exit entirely.-o pipefail
is needed to extend this to commands whose output is redirected with an I/O pipe|
.Now for the options I’ve added:
-O inherit_errexit
further extends this functionality (exiting on nonzero status code) to commands called from within subshells$(...)
.-E
/-o errtrace
and-T
/-o functrace
options are there for the comparatively rare case that you usetrap
to perform an action when the shell receives a signal. These two options extend signal handlers to the inner bodies of shell functions forERR
signals andDEBUG
/RETURN
signals, respectively.See also