`set -e` and `grep` idiom for preventing premature exit from shell script when pattern not found
You can put the grep in an if
condition, or if you don't care about the exit status, add || true
.
Example: grep
kills the shell
$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233
solution 1: throw away the non-zero exit status
$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074
solution 2: explicitly test the exit status
$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074
From the bash man page discussing set -e
:
The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or ││ list except the command following the final && or ││, any command in a pipeline but the last, or if the command’s return value is being inverted with !.
Related videos on Youtube
Comments
-
Yeow_Meng almost 2 years
Help required - in the context of shell scripting on a GNU/LINUX bash:
I always use
set -e
. Often, I would like togrep
and do not always want the script to terminate execution ifgrep
has an exit status of1
indicating pattern not found.Somethings I have tried to solve this problem are as follows:
(Try I)
Ifset +o pipefail
and invoke grep with something likegrep 'p' | wc -l
then I get the desired behaviour until a future maintainer enablespipefail
. Also, I like enablingpipefail
so this does not work for me.(Try II)
Use ased
orawk
and only print lines matching pattern, thenwc
matched lines to test for matched pattern. I don't like this option because usingsed
togrep
seems like a workaround for my true problem.(Try III)
This one is my least favorite - something like:set +e; grep 'p'; set-e
Any insight/idioms would be most appreciated - thank you.
-
schily over 8 yearsGiven that bash for a long time did not implement -e correctly, it may be that the documentation is not yet correct. As the text seems to be identical with the bash-3.x man page, please note: all bash versions before bash4.0 did implement -e incorrectly.
-
schily over 8 yearsAlso note that as the POSIX standard was wrong as well, we changed the POSIX text for error handling with -e in 2009
-
zwol over 8 years@schily Please give pointers to where one may find out what the 'correct' behavior of -e is, what bash < 4 did differently, and what was changed in POSIX.
-
schily over 8 yearsThe bugs in bash-3 basically make it unusable for
make
as it did not always exit on errors. For the related POSIX discussions, you may like to check austingroupbugs.net -
zwol over 8 years@schily Could you please be more specific?
-
Yeow_Meng over 8 yearsA Lesson learned: I had a professor who taught
sh
. He said your scripts will be portable and your understanding of the shell will be pure. A few years later writingBash
in sin, I now understand his insights more clearly.if test -e "$file"; then ...
makes it clear that we are manipulating control flow based on theExit Status
of the commands in theif
guard.