I currently have a script that does something like
./a | ./b | ./c
I want to modify it so that if any of a, b or c exit with an error code I print an error message and stop instead of piping bad output forward.
What would be the simplest/cleanest way to do so?
There is no try/catch in bash; however, one can achieve similar behavior using && or || . it stops your script if any simple command fails.
pipefail. If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default.
The bash shell does not have any fancy exception swallowing mechanism like try/catch constructs. Some bash errors may be silently ignored but may have consequences down the line.
In bash you can use set -e
and set -o pipefail
at the beginning of your file. A subsequent command ./a | ./b | ./c
will fail when any of the three scripts fails. The return code will be the return code of the first failed script.
Note that pipefail
isn't available in standard sh.
You can also check the ${PIPESTATUS[]}
array after the full execution, e.g. if you run:
./a | ./b | ./c
Then ${PIPESTATUS}
will be an array of error codes from each command in the pipe, so if the middle command failed, echo ${PIPESTATUS[@]}
would contain something like:
0 1 0
and something like this run after the command:
test ${PIPESTATUS[0]} -eq 0 -a ${PIPESTATUS[1]} -eq 0 -a ${PIPESTATUS[2]} -eq 0
will allow you to check that all commands in the pipe succeeded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With