Exit Codes — Understanding Command Success and Failure in Bash¶
Exit Codes are numeric values returned by commands, scripts, and functions to indicate whether an operation succeeded or failed. Every Linux command returns an exit code when it finishes execution. Bash scripts use these codes to detect failures, make decisions, trigger error handling, and integrate with automation tools such as Jenkins, GitLab CI/CD, GitHub Actions, Kubernetes Jobs, and Ansible. Understanding exit codes is essential for writing reliable, production-ready Bash scripts.
Learning Path¶
Course Progress
What You'll Learn¶
After completing this lesson, you'll be able to:
- Understand exit codes
- Interpret command status
- Use the
exitcommand - Check exit codes using
$? - Return exit codes from functions
- Use exit codes in conditional statements
- Apply exit codes in production automation
Prerequisites¶
Complete:
- Modules 1–9
- Module 10 Lessons 1–6
Why Learn Exit Codes?¶
Imagine deploying an application.
Without checking the exit code:
Even if the deployment fails, the script reports success.
Using exit codes:
kubectl apply -f deployment.yaml
if [ $? -eq 0 ]
then
echo "Deployment Successful"
else
echo "Deployment Failed"
fi
The script accurately reports the outcome.
What is an Exit Code?¶
An exit code is a numeric value returned by a command after execution.
The shell stores the exit code of the most recently executed command.
Standard Exit Codes¶
| Exit Code | Meaning |
|---|---|
0 | Success |
| Non-zero | Failure |
1 | General error |
2 | Incorrect command usage |
126 | Command cannot execute |
127 | Command not found |
130 | Script terminated by Ctrl+C |
Viewing the Exit Code¶
Use the special variable:
Example:
Output:
Successful Command¶
Output:
Failed Command¶
Output:
Using Exit Codes in Conditions¶
Better Approach¶
Instead of checking $? separately:
This is cleaner and more readable.
Using the exit Command¶
Terminate a script with a specific exit code.
Success.
Failure.
Example Script¶
Custom Exit Codes¶
You may define custom exit codes for different situations.
Example:
Document custom exit codes clearly so other users understand their meaning.
Exit Codes in Functions¶
Functions return status codes.
Call the function.
Common Commands¶
View exit code.
Exit successfully.
Exit with failure.
Return from function.
Real Production Examples¶
Check deployment.
kubectl apply -f app.yaml
if [ $? -eq 0 ]
then
echo "Deployment Successful"
else
echo "Deployment Failed"
fi
Check backup.
Restart service.
systemctl restart nginx
if systemctl is-active --quiet nginx
then
echo "Service Running"
else
exit 1
fi
Production Perspective¶
Exit codes are heavily used in:
- Bash automation
- CI/CD pipelines
- Kubernetes Jobs
- Ansible playbooks
- Jenkins pipelines
- GitLab CI/CD
- Monitoring scripts
- Deployment automation
Most automation platforms rely on exit codes to determine whether a task succeeded or failed.
Hands-on Lab¶
Task 1¶
Run a successful command.
Display the exit code.
Task 2¶
Run a failed command.
Display the exit code.
Task 3¶
Create a script.
Run it.
Task 4¶
Create a script that fails.
Task 5¶
Check command success.
Task 6¶
Create a function.
Task 7¶
Return a failure code.
Task 8¶
Exit the script when a required file is missing.
Command Deep Dive¶
| Command | Purpose | Production Example |
|---|---|---|
echo $? | Display last exit code | Troubleshooting |
exit | Exit script | Automation |
return | Return function status | Modular scripts |
if | Check command success | Deployment validation |
&& | Execute next command on success | Chained automation |
|| | Execute next command on failure | Error recovery |
Common Exit Code Mistakes¶
| Mistake | Solution |
|---|---|
| Ignoring exit codes | Always check critical commands |
Checking $? too late | Check immediately after the command |
Using return outside a function | Use exit in scripts |
Returning strings with return | Return only numeric values |
| Assuming every non-zero code has the same meaning | Understand common exit codes |
Production Troubleshooting Scenario¶
Scenario
A CI/CD pipeline reports a successful deployment, but the application is unavailable.
Investigation:
The deployment command failed.
The script ignored the exit code and continued.
Solution:
if kubectl apply -f deployment.yaml
then
echo "Deployment Successful"
else
echo "Deployment Failed"
exit 1
fi
The pipeline now correctly reports failures and stops further execution.
Best Practices¶
- Check the exit status of important commands.
- Exit immediately when critical operations fail.
- Use meaningful exit codes.
- Return status codes from functions.
- Prefer
if commandover checking$?separately. - Document custom exit codes.
Common Mistakes¶
❌ Ignoring failed commands.
✅ Always review failed commands.
❌ Checking $? after executing another command.
✅ Avoid this mistake: checking $? after executing another command.
❌ Using return instead of exit in the main script.
✅ Prefer exit in the main script rather than using return.
❌ Returning text instead of numeric status codes.
✅ Prefer numeric status codes rather than returning text.
❌ Continuing execution after critical failures.
✅ Do not continue execution after critical failures.
Interview Questions¶
Beginner¶
- What is an exit code?
- What does exit code
0mean? - How do you display the last exit code?
- What does the
exitcommand do?
Intermediate¶
- What is the difference between
exitandreturn? - Why should you check exit codes in scripts?
- Why is
if commandpreferred over checking$?separately? - What does exit code
127indicate?
Architect Level¶
- How do exit codes improve CI/CD pipeline reliability?
- How would you design Bash scripts to fail safely?
- How should custom exit codes be used in enterprise automation?
Summary¶
In this lesson, you learned:
- Exit codes
- Standard Linux exit codes
- The
exitcommand - The
$?variable - Returning status codes from functions
- Using exit codes in conditions
- Production scripting best practices
Exit codes provide a standardized way for commands, functions, and scripts to communicate success or failure. Proper use of exit codes allows automation tools and other scripts to make informed decisions, improving the reliability and maintainability of production systems.
Key Takeaways¶
- Every Linux command returns an exit code.
0indicates success; non-zero values indicate failure.- Use
echo $?to view the last exit code. - Use
exitto terminate scripts with a status. - Use
returnto return status codes from functions. - Always check exit codes for critical operations.
What's Next?¶
Error Handling — Building Reliable Bash Scripts
You'll explore:
- Handling runtime errors
- Using
setoptions (-e,-u,-o pipefail) - Error messages
- Cleanup operations with
trap - Defensive scripting techniques
- Debugging failures
- Production error handling best practices
By the end of the lesson, you'll be able to build resilient Bash scripts that detect errors, recover gracefully where appropriate, and fail safely when necessary.