You only need to use the special variable $?
when you need its value across several invocations of other utilities. For example, you may want to output it in a diagnostic message and then return it from a function. Outputting something with printf
would reset $?
to the exit-status of printf
, so you wouldn't be able to do return "$?"
(or return
) directly afterward to return the original exit-status. Notice that even testing something with [ ... ]
resets $?
. You would probably instead assign $?
to some other variable and use that.
You might want to consider using $?
in an if
statement if that is the style used in the rest of the project. In that case, remember to quote the expansion, as technically, $IFS
might contain digits, which means the unquoted expansion of $?
would potentially disappear entirely or partially.
utility
# shellcheck disable=SC2181
if [ "$?" -eq 0 ]; then
echo ok
else
echo fail
fi
However, this makes for much typing and makes the code slightly obfuscated and a bit unnecessarily tricky to follow. Note that the invocation of utility
above is not connected to the if
statement following it in any immediate way.
There is additionally a bit of extra redundancy here since the if
statement is now examining the exit-status of the [
utility to test whether a variable is zero or not. The variable is the exit-status of another utility, which we could have used with if
directly.
if utility; then
echo ok
else
echo fail
fi
Here it's clear that the invocation of utility
is an integral part of the if
statement.
See also the rationale behind the SC2181
warning in the ShellCheck wiki.
if findmnt /dev/sda1 >/dev/null; then echo 1; else echo 0; fi
would be a more direct equal of the first one. Using!
there flips the sense of the test.findmnt
.