set -eo pipefail
commandThatFails || exitFunction
exitFunction
So this script is running the exitMethod twice... I thought set -e
exited immediately on any non zero exit code and set -o pipefail
made sure that during the pipeline any failure is the final exit status code not the most recent command?
Therefore I thought :
In the docs it states:
The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits.
I thought that the exitfunction is the command following the final ||
so therefore would be counted and picked up and exited immediately.
I can resolve the issue with:
commandThatFails || { exitFunction; exit 1; }
but it doesn't seem like the more elegant way to handle this, any thoughts appreciated!
||
is a flow control operator, not a pipeline component. pipefail
has no effect on it.
If set -e
caused flow control operators to exit, then you could never have an else
branch of your script run with it active; it would be completely useless.
For that reason, &&
and ||
suppress set -e
behavior for their left-hand sides, just like if condition; then success; else fail; fi
suppresses that behavior for condition
.
General practice is to make your exitFunction
actually call exit
, so you can write:
die() {
rc=$?
(( $# )) && printf '%s\n' "$*" >&2
exit "$(( rc == 0 ? 1 : rc ))"
}
commandThatFails || die "commandThatFails failed"
...but if you want to call something else first, yes, you need to use a grouping, just as you did in the question.