SC2181 – ShellCheck Wiki

See this page on GitHub


Check exit code directly with e.g. if mycmd;, not indirectly with $?.

Problematic code:

make mytarget

if [ $? -ne 0 ]
  echo "Build failed"

Correct code:

if ! make mytarget;
  echo "Build failed"


Running a command and then checking its exit status $? against 0 is redundant.

Instead of just checking the exit code of a command, it checks the exit code of a command (e.g. [) that checks the exit code of a command.

Apart from the redundancy, there are other reasons to avoid this pattern:

To check that a command returns success, use if mycommand; then ....

To check that a command returns failure, use if ! mycommand; then .... Notice that ! will overwrite $? value.

To additionally capture output with command substitution: if ! output=$(mycommand); then ...

This also applies to while/until loops.


The default Solaris 10 bourne shell does not support '!' outside of the test command (if ! mycommand; then ... returns !: not found)

ShellCheck is a static analysis tool for shell scripts. This page is part of its documentation.