Bash by Example: Exit Codes
Understanding exit statuses through the $? special variable that holds the return code of the last executed command, controlling script success and failure with the exit built-in command, using exit codes for error handling and conditional logic, following conventions where 0 means success and non-zero indicates errors, and implementing proper exit code propagation in functions and scripts.
Code
#!/bin/bash
# Run a command that succeeds
ls / > /dev/null
echo "ls / exit code: $?"
# Run a command that fails
ls /non_existent_folder 2> /dev/null
echo "ls fail exit code: $?"
# Custom function with exit codes
check_number() {
if [ "$1" -gt 10 ]; then
return 0 # Success
else
return 1 # Failure
fi
}
check_number 15
if [ $? -eq 0 ]; then
echo "Check 15: Success"
fi
check_number 5
# Directly using the exit code in 'if'
if ! check_number 5; then
echo "Check 5: Failed (as expected)"
fi
# Exiting the script with a specific code
# exit 127Explanation
In the Unix world, every command returns a numeric Exit Code (or return status) when it finishes. This code tells the system whether the command succeeded or failed. The convention is strict: 0 means Success, and any non-zero value (1-255) means Failure. This is the opposite of many programming languages where "true" is often 1.
The special variable $? holds the exit code of the most recently executed command. You must check $? immediately after the command runs, because running another command (even a simple echo) will overwrite it with its own exit code.
You can control your own script's exit code using the exit N command. If your script encounters a critical error (like a missing dependency or invalid input), you should exit 1 (or another non-zero number) to signal to any parent process that the script failed. This allows your script to be part of larger pipelines and automation workflows.
Code Breakdown
$? captures the result of ls /. Since the root directory exists, ls returns 0.return 0 in a function sets $? to 0 for the caller. This mimics the behavior of standard commands.if ! command; then. The if statement implicitly checks exit codes. ! inverts it, so "if exit code is NOT 0 (failure), then execute block".
