diff --git a/SC2251.md b/SC2251.md new file mode 100644 index 0000000..a3da814 --- /dev/null +++ b/SC2251.md @@ -0,0 +1,37 @@ +## This ! is not on a condition and skips errexit. Use { ! ...; } to errexit, or verify usage. + +### Problematic code: + +```sh +set -e +! false +``` + +### Correct code: + +```sh +set -e +{ ! false; } +``` + +### Rationale: + +ShellCheck has found a command inverted with `!` that may have no effect. In particular, it does not appear as a condition in an `if` statement or `while` loop, or as the final command in a script or function. + +The most common reason for this is thinking that it'll trigger `set -e` aka `errexit` if a command succeeds, as in the example. This is not the case: `!` will inhibit errexit both on success and failure of the inverted command. + +### Exceptions: + +ShellCheck will not detect cases where `$?` is implicitly or explicitly used to check the value afterwards: + +``` +check_success() { [ $? -eq 0 ] || exit 1; } +! false; check_success +! true; check_success +``` + +In this case, you can [[ignore]] the warning, or optionally wrap them in `{ ! false; }`. + +### Related resources: + +* StackOverflow: [Why do I need parenthesis In bash `set -e` and negated return code](https://stackoverflow.com/questions/39581150/why-do-i-need-parenthesis-in-bash-set-e-and-negated-return-code/39582012) \ No newline at end of file