TL; DR: this is just a workaround for the set -e flag on the specific line where you use it.
Adding the correct and useful answer to hek2mgl .
You have:
set -e ! command
Bash Reference Guide → Piping describes:
Each command in the pipeline is executed in its own subshell. The pipeline exit status is the exit status of the last command in the pipeline (...). If the reserved word '! precedes the pipeline, exit status is a logical negation of exit status , as described above. The shell waits for all commands in the pipeline to complete before returning a value.
This means that ! preceding the command denies its exit status:
$ echo 23 23 $ echo $? 0
Or:
$ echo 23 && echo "true" || echo "fail" 23 true $ ! echo 23 && echo "true" || echo "fail" 23 fail
Exit status is useful in many ways. In the script used with set -e , the script is called when the command returns a non-zero status.
Thus, if you have:
set -e command1 command2
If command1 returns a non-zero status, the script will end and not go to command2 .
However, there is also an interesting point mentioned in 4.3.1 Set Builtin :
-e
Exit immediately if the pipeline (see "Pipelines"), which can consist of one simple command (see "Simple commands"), a list (see Lists), or a compound command (see compound commands), returns a non-zero status. The shell does not exit if the failed command is part of the list of commands immediately after some time or until the keyword, part of the test in the if statement, is part of any command executed in && & &; or || the list, with the exception of the command following the final && or ||, any command in the pipeline, but the last, or if the return status of the commands is flipped with! . If a compound command other than a subshell returns a nonzero status because the command was unsuccessful and -e was ignored, the shell did not exit. The trap in the ERR, if set, runs before the shell exits.
Given all this, when you have:
set -e ! command1 command2
What you do is bypass the set -e flag in command1 . Why?
- If
command1 works correctly, it will return a null status. ! will deny it, but set -e will not cause an exit due to the fact that it returns from the return state inverted with !, as described above. - If
command1 does not work, it will return a non-zero status. ! will deny this, so the string will return a null status, and the script will continue normally.