Every command in Linux returns an exit code when it finishes.
0 means success. Any nonzero value means "something went
wrong".
some-command
echo $? # 0 if success, nonzero if failure
$? is a special variable that holds the exit code of the
most recent command. It changes with every command, so capture
it into a variable if you need it later:
some-command
code=$?
# ... other things ...
if (( code != 0 )); then
echo "earlier command failed with $code"
fi
exit 0 # succeed
exit 1 # generic failure
exit 2 # convention: misuse (invalid arguments)
exit N ends the script and returns exit code N to whoever
called it. Without an argument, exit returns the last
command's exit code.
Every automation tool you'll ever use (cron, systemd, CI pipelines, monitoring probes) decides "did this succeed?" by looking at the exit code. Getting them right is the difference between "backup succeeded" and a silently broken pipeline.
Standard exit codes worth recognizing:
0 success1 general failure2 misuse (bad arguments, missing config)126 command found but not executable127 command not found130 killed by Ctrl+C (SIGINT)137 killed by SIGKILL (often OOM)143 killed by SIGTERMYou don't have to memorize them, but recognizing 127 as "not
found" saves time when debugging.