Exit Codes
Exit codes (also called return codes or exit status) indicate whether a command succeeded or failed. Understanding exit codes is fundamental to error handling.
What Are Exit Codes?
Every command returns a number when it finishes:
- 0 = Success
- 1-255 = Failure (various error types)
#!/bin/bash
ls /home
echo "Exit code: $?" # 0 (success)
ls /nonexistent
echo "Exit code: $?" # 2 (no such file)
The $? Variable
$? holds the exit code of the last command:
#!/bin/bash
grep "pattern" file.txt
RESULT=$?
if [ $RESULT -eq 0 ]; then
echo "Pattern found"
elif [ $RESULT -eq 1 ]; then
echo "Pattern not found"
else
echo "Error occurred"
fi
Common Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Misuse of command |
| 126 | Command not executable |
| 127 | Command not found |
| 128 | Invalid exit argument |
| 128+N | Fatal signal N (e.g., 130 = Ctrl+C) |
| 255 | Exit status out of range |
Exercise: Check Exit Code
Use exit code to check success:
Setting Exit Codes
Use exit to set your script's exit code:
#!/bin/bash
# Exit with success
exit 0
# Exit with error
exit 1
# Exit with specific code
if [ ! -f "$1" ]; then
echo "File not found" >&2
exit 2
fi
The exit Command
#!/bin/bash
check_file() {
if [ ! -f "$1" ]; then
echo "Error: File not found" >&2
exit 1 # Exits the ENTIRE script
fi
}
check_file "missing.txt"
echo "This won't print"
Return vs Exit
exitterminates the scriptreturnexits only the function
#!/bin/bash
validate() {
if [ -z "$1" ]; then
return 1 # Function returns, script continues
fi
return 0
}
if validate ""; then
echo "Valid"
else
echo "Invalid" # This prints
fi
echo "Script continues" # This also prints
Exit on Error
Using set -e:
#!/bin/bash
set -e # Exit on first error
echo "Step 1"
false # This will cause exit
echo "Step 2" # Never reached
Better: control where to exit:
#!/bin/bash
set -e
# Critical section
do_important_thing
set +e # Disable for non-critical
optional_command # Won't exit on failure
set -e
# Back to strict mode
do_another_thing
Exercise: Exit with Code
Set script exit code:
Checking Commands in Conditions
#!/bin/bash
# Direct check in if
if grep -q "pattern" file.txt; then
echo "Found"
fi
# Command success/failure
if command; then
echo "Command succeeded"
else
echo "Command failed"
fi
# Negation
if ! command; then
echo "Command failed"
fi
Conditional Execution
#!/bin/bash
# && = run if previous succeeded
mkdir project && cd project && echo "Created and entered"
# || = run if previous failed
rm file.txt || echo "Could not remove file"
# Combined
command && echo "Success" || echo "Failure"
Exit Code Best Practices
#!/bin/bash
# Define exit codes as constants
readonly EXIT_SUCCESS=0
readonly EXIT_ERROR=1
readonly EXIT_USAGE=2
readonly EXIT_NO_FILE=3
# Main script
main() {
if [ $# -lt 1 ]; then
echo "Usage: $0 <file>" >&2
exit $EXIT_USAGE
fi
if [ ! -f "$1" ]; then
echo "Error: File not found: $1" >&2
exit $EXIT_NO_FILE
fi
# Process file
process "$1" || exit $EXIT_ERROR
exit $EXIT_SUCCESS
}
main "$@"
Key Takeaways
- Exit code 0 means success, non-zero means failure
$?contains the last command's exit code- Use
exit Nto set script's exit code - Use
return Nin functions (doesn't exit script) set -eexits on any command failure&&runs next command only on success||runs next command only on failure- Define meaningful exit codes for your scripts

