The -e option means "if any pipeline ever ends with a non-zero ('error') exit status, terminate the script immediately". Since grep returns an exit status of 1 when it doesn't find any match, it can cause -e to terminate the script even when there wasn't a real "error".
If you want to keep the -e option, but also have a grep command that might validly find no matches, you can append ||. to the grep command. This means "or, if the grep command returns a non-zero exit status, run. (which does nothing)"; so the net effect is to disable -e for the grep command. So:
Edited to add: The above approach discards every error: if grep returns 1 because it found no matches, that's ignored, but also if grep returns 2 because there was an error, that's ignored, and if grep isn't in the path (so Bash returns 127 ), that's ignored — and so on. So, rather than. it's probably better to use a command that checks the result code
and re-issues the error if it's something other than 1. For example:
But this destroys the exit status; usually, when a failed command terminates a Bash script with -e. the script will return the command's exit-status, but in the above example, the script will just return 1. If (and only if) we care about that, we can fix it by write something like this:
(first line c/o dsummersl 's comment).
At this point, it's probably best to create a shell function to handle this for us:
(note the use of return rather than exit ; we'll let -e handle the exiting when appropriate); this way, we can just write:
In fact, since we most likely want to use this function for all occurrences of grep in this script, we can actually just name the function grep :
(note the use of command to bypass the shell function within its own body: we want the function to call the regular program grep. rather than to recurse infinitely).