I have a bash script like this


do-this parm someotherparam
do-something-else $varz $(commands)
and-also-do-this -something
finally-do-something-different -yes

I want this script to return exit status of 0, if all the individual commands above returned 0. I want it to return non-zero if any of the individual commands returned non-zero. I do not care what non-zero value is as long as it is, well, not 0.

Obviously, if we check status after each line, we can achieve our objective easily if only verbose. Since I'm new to bash, I was wondering if there is an idiomatic way of writing this.

Note: I want all the commands to run regardless of their exit status, otherwise something like this would work



do-this parm someotherparam             ; (( err |= $? ))
do-something-else $varz $(commands)     ; (( err |= $? ))
and-also-do-this -something             ; (( err |= $? ))
finally-do-something-different -yes     ; (( err |= $? ))

This will initialize the variable err to zero and then, after each command, set err to $err | $? (a bitwise OR). This will set err to a non-zero number if any of the commands exit with a non-zero exit status, and it will remain non-zero to the end of the script.

You may exit "$err" at the end of the script if you wish.

A less manual way of getting the same result:

trap '(( err |= $? ))' ERR

# (rest of original script)

This sets an error trap that will set err in the same manner as above whenever a command exits with non-zero exit status. The trap will be executed under the same circumstances under which the errexit shell option (set -e) would have terminated the script. For simplicity, you may have the trap just set err=1 if you want.

To unset the trap after a section of code, use

trap - ERR

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.