Exit status, && and ||

Bash · Essentials · 7 min

Exit statuses are how shell scripts make decisions and detect errors.

When a command finishes it returns an exit status, an integer 0 to 255. Zero means success, anything else means failure, and programs document what their non-zero codes mean: grep returns 1 for "no match" and 2 for a real error. The status of the last command is in $?; read it immediately, because the next command overwrites it.

Bash lets you chain on that status:

  • a && b runs b only if a succeeded,
  • a || b runs b only if a failed,
  • ! a inverts the status.

So mkdir -p out && cd out changes directory only when the directory exists, and command -v jq || echo "please install jq" is a one-line dependency check. You can combine them, but a && b || c is not a true if/else: c also runs when b fails.

Your own scripts end with the status of the last command run, or the number passed to exit. Use exit 0 for success and a small non-zero number (often 1, or 2 for usage errors) for failure so callers, cron and CI systems can react. true and false are commands that simply return 0 and 1.

Example

grep -q root /etc/passwd
echo $?                       # 0  (found)
grep -q nosuchuser /etc/passwd
echo $?                       # 1  (no match)
ls /nope 2>/dev/null; echo $? # 2  (error)
mkdir -p build && echo "created"     # created
false || echo "fallback ran"         # fallback ran
! true; echo $?               # 1  (! inverts)
true; false; echo $?          # 1  (only the last command counts)
command -v git >/dev/null && echo "git is installed"

Remember

  • 0 = success, 1-255 = failure; $? holds the last status
  • && runs on success, || on failure, ! inverts
  • End scripts with a meaningful exit code

Watch out for

  • Using a && b || c as if/else: c also runs when b fails.

Check yourself

  1. What is printed by `false; true; echo $?`?
  2. In `make && ./app || echo failed`, when is 'failed' printed?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/bash/manual/bash.html#Exit-Status