So I have a script like this:
somecommad | grep --invert-match somethingI'd like to be able to conditionally run a different command if somecommand fails. Here's what I tried:
somecommand | grep --invert-match something || { echo 'Oops'
}But that didn't work (the grep wasn't executed). What is the proper way to do this?
2 Answers
@steeldriver mentioned in the comments that PIPESTATUS might work. I tried it, and it worked well. Here's what I did:
somecommand | grep --invert-match something
if [ "${PIPESTATUS[0]}" != "0" ]; then echo 'Oops'
fiIt runs the command as before, but then I have an if statement to look at the PIPESTATUS array. I only care about the first element, so that is the one I look at. I check it it failed (if the exit code is not 0), and it it did fail, run echo 'Oops'
Another way, depending on the exact behaviour needed, is to use the pipefail option:
The exit status of a pipeline is the exit status of the last command in the pipeline, unless the
pipefailoption is enabled (see The Set Builtin). Ifpipefailis enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
So, if you don't care which of somecommand or grep failed, as long as one of those did fail:
set -o pipefail
if ! somecommand | grep --invert-match something; then echo 'Oops'
fi