← Back to Bash Course | Chapter 1: Setup & Basics | Lesson 12 of 12

Exit Status and $?

Every command that finishes in Bash reports back a small number called its exit status, where 0 means success and anything else means some kind of failure.

Reading $? After a Command

After any command finishes, Bash stores its exit status in the special variable $?. You can inspect it immediately afterward to decide what your script should do next, but it gets overwritten the instant another command runs.

Example: Reading $? After a Command

bash
#!/bin/bash
echo "hello"
echo "Exit status of echo: $?"
grep "zzz" <<< "no match here"
echo "Exit status of grep (1 = no match found): $?"

Success vs Failure Codes

Exit status 0 conventionally means the command succeeded, while any value from 1 to 255 signals failure, though the exact meaning of each non-zero number is defined by that specific command. Many commands only ever return 0 or 1, but some use different numbers to distinguish different kinds of errors.

Example: Success vs Failure Codes

bash
#!/bin/bash
true
echo "true's exit status: $?"
false
echo "false's exit status: $?"

&& and || Based on Exit Status

&& chains a second command to run only if the first one exited with status 0 (success). || does the opposite, running the second command only if the first exited non-zero (failure), which is a common shorthand for simple conditional logic.

Example: && and || Based on Exit Status

bash
#!/bin/bash
mkdir -p /tmp/demo_$$ && echo "Directory created successfully"
grep "missing" <<< "nothing to find" || echo "Pattern not found, handled gracefully"

Setting Your Script's Own Exit Status

A script or function can explicitly set the exit status callers will see using the exit builtin followed by a number. If exit is called with no argument, the script exits with the status of the last command it ran.

Example: Setting Your Script's Own Exit Status

bash
#!/bin/bash
check_value=5
if [ "$check_value" -gt 0 ]; then
    echo "Value is positive"
    exit 0
fi
echo "This line would only run for non-positive values"
exit 1
Common Mistakes
  1. Assuming a non-zero exit status always means a crash; it usually just means the command's own definition of failure, e.g. grep returns 1 simply when it finds no matches, which is not an error condition.
  2. Checking $? after running an unrelated command in between, like echo for debugging; $? always reflects the *most recently* completed command, so any command run after the one you care about overwrites it.
  3. Forgetting that exit status is capped at 0-255; larger values wrap around due to how the value is stored, which can produce surprising results.
Chapter Summary
  • $? holds the exit status of the most recently executed command.
  • By convention, exit status 0 means success, and any non-zero value (1-255) means failure or a specific error condition.
  • && runs the next command only if the previous one exited 0; || runs the next command only if the previous one exited non-zero.
  • A script's own exit status can be set explicitly with the exit builtin, e.g. exit 1.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.