The issue I have with most, and perhaps all the answers here, is that they are losing the true exit code ($?) and mostly returning $? as 0. There is no way to differentiate if there was a match (exit code 0) or no match (exit code 1). This solution addresses that concern:
#!/bin/bash -e
echo "before"
exit_code=0
echo "anything" | grep e || exit_code=$?; if [[ $exit_code -ne 1 ]]; then (exit $exit_code); fi
echo "after"
exit
Explained
grep
's exit status is either 0, 1 or 2:
0
means there was a match
1
means there was no match
2
means an error occurred
Now, with the above solution:
- If
grep
returns 0
, the test
is not run and returns the true $? exit code of 0, and also sets $exit_code=0
.
- If
grep
returns 1
, the test
is run and returns a fake $? exit code of 0, but we also sets $exit_code=1
which can be used by future code to differentiate a match vs no match.
- If
grep
returns any other value, the test
is run and returns the true greater than 1 error exit code that should correctly halt the script, we also set $exit_code
appropriately, but that won't matter because the script will halt.
-e
presupposes you do care: so much so that any problem is catastrophic.var=$(complex command | grep complex_pattern)
which may be null (in which case my program should not terminate). This is just a boiled down script which makes the problem occur. No metaphysical blackhole in the logic here, right? ;)