Generalize "Rationale" section; move pipefail-specific info to a separate section; link to POSIX spec for set

Lawrence Velázquez
2022-03-20 20:59:50 -04:00
parent 663e66dc31
commit 1c2f04e5af

@@ -1,12 +1,20 @@
## In POSIX sh, set option <option> is undefined.
## In POSIX sh, set option *[name]* is undefined.
This applies to any POSIX code: `set -o <option>` is **undefined**.
The value *[name]* may be anything other than `allexport`, `errexit`, `ignoreeof`, `monitor`, `noclobber`, `noexec`, `noglob`, `nolog`, `notify` , `nounset`, `verbose`, `vi`, and `xtrace`.
Examples follow:
<!-- https://github.com/koalaman/shellcheck/blob/3b6972fbf14d98dded7ebfc65af6b73724be4efa/src/ShellCheck/Checks/ShellSupport.hs#L334-L337 -->
----
### Rationale:
### Problematic code:
In a script declared to run with `sh` or `dash`, ShellCheck found `set -o` used with an option that is not defined by POSIX. The option may not be supported by these shells.
### Exceptions:
If the script has already inspected the current shell and determined the option is available, you can [[ignore]] this message.
### `pipefail`
#### Problematic code:
```sh
#!/bin/sh
@@ -17,7 +25,7 @@ then
fi
```
### Correct code:
#### Correct code:
```sh
fail="$(mktemp)"
@@ -30,22 +38,14 @@ fi
rm "$fail"
```
or switch to a shell that supports pipefail, such as Bash.
### Rationale:
ShellCheck found `set -o pipefail` in a script declare to run with `sh` or `dash`. This feature may not be supported on these shells.
As an alternative, each stage in the pipeline such as `cmd1` can be rewritten as `{ cmd1 || echo > file; }` which will behave as before but now also write the exit code into `file` if the command fails.
Each stage in the pipeline such as `cmd1` can be rewritten as `{ cmd1 || echo > file; }` which will behave as before but now also write the exit code into `file` if the command fails.
If the file has been written to when the pipeline is done, it means one of the commands failed. This is demonstrated in the correct example.
This can obviously be extended with e.g. `echo "cmd1=$?" >> file` if the particular exit codes for particular commands are desired.
### Exceptions:
If the script has already inspected the current shell and determined the option is available, you can [[ignore]] this message.
Alternatively, switch to a shell that supports `pipefail`, such as Bash.
### Related resources:
* Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!
* [POSIX.1-2017 - Shell Command Language - `set`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set)