diff --git a/SC2326.md b/SC2326.md new file mode 100644 index 0000000..c1d384f --- /dev/null +++ b/SC2326.md @@ -0,0 +1,36 @@ +## ! is not allowed in the middle of pipelines. Use command group as in `cmd | { ! cmd; }` if necessary. + +### Problematic code: + +```sh +cat | ! tee /dev/full +``` + +### Correct code: + +Either negate the entire pipeline (this is equivalent unless `pipefail` is set): + +```sh +! cat | tee /dev/full +``` + +Or use a command group to negate a single stage: + +```sh +cat | { ! tee /dev/full; } +``` +### Rationale: + +[POSIX specifies](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_02) that a status negation operator `!` is only used to negate the status of an entire pipeline, not individual stages. + +By default the status of a pipeline is that of the last command, so use `!` in front of the pipeline to negate as necessary. + +If you have set the option `pipefail` to OR the status of each stage together, and want to negate the status of only a single stage, you can use negate inside a `{ ! command group; }`. + +### Exceptions: + +Ksh supports `!` in front of individual pipeline stages. ShellCheck does not warn when the shebang declares that the script will run with Ksh. + +### Related resources: + +* Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc! \ No newline at end of file