ShellCheck -- Avoid if [ $? -eq 0 ]

The Problem

A common pattern is:

ping -c 1 10.0.1."$names" >/dev/null 2>&1

if [ $? -eq 0 ]; then
    echo "Host is up"
fi

ShellCheck recommends testing the command directly instead of checking $?.

Why?

Every command sets an exit status.

if already tests that exit status, so there is no need to read $?.

Using $? is also fragile because another command executed before the test will overwrite it.

Preferred Style

Write:

if ping -c 1 10.0.1."$names" >/dev/null 2>&1; then
    echo "Host is up"
else
    echo "Host is down"
fi

More Examples

Instead of:

systemctl is-active nginx >/dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "Running"
fi

Use:

if systemctl is-active nginx >/dev/null 2>&1; then
    echo "Running"
fi

Instead of:

grep -q "^root:" /etc/passwd
if [ $? -ne 0 ]; then
    echo "Not found"
fi

Use:

if ! grep -q "^root:" /etc/passwd; then
    echo "Not found"
fi

Rules to Remember

  • Let if execute the command.
  • Don't test $? unless there is a specific reason.
  • Use ! to invert success/failure.

Quick Mental Model

Think of:

if command; then

as:

"Run the command, and if it succeeds, execute the then block."

No separate exit-code check is needed.