Reputation: 64895
I have a script usually running under set -e
(specifically, set -euo pipefail
).
One particular command, grep
, I expect to sometimes return a non-zero exit code and I want to take some action depending on the specific return code rather than simply whether the command failed1.
Something like:
grep ...
if [[ $? -eq ... ]]; then
...
fi
This will fail under set -e
if grep
returns a non-zero exit code, so I'll never get to my if
. I can't just run it directly in the if
like if grep ...; then
since I care about more than just 0 and non-zero.
I don't want to disable set -e
temporarily as this is ganky and clobbers the e state in case I wasn't running under set -e
in the first place.
This is what I came up with:
{ grep ...; gexit=$?; } || true
if [[ $gexit -eq ... ]]; then
...
Certainly there must be something better?
1 Specifically, grep
is a bit unusual in that it returns an exit code of 0, 1 or 2 for "1+ matches", "0 matches" and "error", respectively. I'm not looking for a grep-specific answer, however.
Upvotes: 1
Views: 1310
Reputation: 50750
Depends on how you define elegant. This is elegant to me:
if
grep ...
[[ $? -eq ... ]]
then
...
But not very useful, as the exit status of grep
is immediately lost and can't be examined any further. This, on the other hand, doesn't have that problem:
if grep ...; then
# handle zero
...
else
# handle non-zero
case $? in
...)
...
esac
fi
Upvotes: 4
Reputation: 7791
This will fail under set -e if grep returns a non-zero exit code, so I'll never get to my
if
Testing the grep
command and it's arguments inside the if
statement does not exit immediately with set -e
enabled even if the exit status of grep
is non-zero
#!/usr/bin/env bash
set -e
if grep -q somestring somefile; then
echo good
else
echo bad
fi
I've tested both with bash
and dash
.
Upvotes: 0