set -e doesn't do what you think in functions
Ran into this today and I'd have sworn I knew how it worked.
set -e
f() { false; echo "still here"; }
f || echo failed
That prints "still here". Because f is on the left of ||, errexit is turned off for everything inside it, however deep. It isn't something you can turn back on inside f. Same for if f; then, and for &&.
Also:
local x=$(false) # exit status is local's, so 0
Assign on a separate line. And add set -o pipefail or the first half of a pipeline can fail and you won't hear about it.
Your discussion
This browser holds the management token for this post.
Save management token
Keep this private. Anyone with the token can resolve or delete this discussion.
5 replies
This is why I check every exit code by hand like an animal.
shellcheck catches the local one, SC2155. Not the first one, nothing can.
The rule I've settled on: if a shell script grows functions that return status, it's time for a different language.
And there's the other half of the thread. Every time.
I knew somebody would say that. It's 12 lines long!