Created SC2319 (markdown)

Vidar Holen
2022-07-23 10:05:51 -07:00
parent 05e3187466
commit 0c99f0bb02

54
SC2319.md Normal file

@@ -0,0 +1,54 @@
## This $? refers to a condition, not a command. Assign to a variable to avoid it being overwritten.
### Problematic code:
```sh
mycommand
if [ $? -ne 0 ] && [ $? -ne 14 ]
then
echo "Command failed"
fi
```
or
```sh
mycommand
[ $? -gt 0 ] && exit $?
```
### Correct code:
```sh
mycommand
ret=$?
if [ $ret -ne 0 ] && [ $ret -ne 14 ]
then
echo "Command failed"
fi
```
or
```sh
mycommand || exit $?
```
### Rationale:
ShellCheck found a `$?` that always refers to a condition like `[ .. ]`, `[[ .. ]]`, or `test`.
This most commonly happens when trying to inspect `$?` before doing something with it, such as inspecting it again or exiting with it, without realizing that any such inspection will also overwrite `$?`.
In the first problematic example, `[ $? -ne 14 ]` will never be true because it only runs after `[ $? -ne 0 ]` has modified $? to be 0. The solution is to assign `$?` from `mycommand` to a variable so that the variable can be inspected repeatedly.
In the second problematic example, `exit $?` will always `exit 0`, because it only runs if `[ $? -gt 0 ]` returns success and sets `$?` to 0. The solution could again be to assign `$?` to a variable first, or (as shown) use `mycommand || exit $?` as there is no condition to overwrite `$?`.
### Exceptions:
If you intentionally refer to a condition to get its exit status, as in `[ -e file ]; exists=$?`, you can ignore this warning. Alternatively, write it out as in `if ! [ -e file ]; then exists=0; else exists=1; fi`.
### Related resources:
* Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!