Automatic exit from Bash shell script on error
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
The standard way to make a Bash script exit automatically on error is set -e. In production scripts, the stronger pattern is set -euo pipefail, which also catches unset variables and hidden pipeline failures. This article covers all three flags, the important exceptions to set -e behavior, explicit error handling patterns, and a production-ready script template you can use as a starting point.
The Basic Tool: set -e
set -e (also known as errexit) tells Bash to exit immediately when a simple command returns a non-zero exit status.
When cp fails because the source file does not exist, the script exits with the same non-zero status. Without set -e, the script would silently continue to Step 3, potentially operating on incomplete data.
Why set -euo pipefail Is the Industry Standard
Most production Bash scripts use all three flags together:
Each flag addresses a different class of silent failure:
| Flag | Name | What It Catches |
-e | errexit | Commands that return non-zero exit status |
-u | nounset | References to undefined variables |
-o pipefail | pipefail | Failures in any command within a pipeline |
Why -u Matters
Without -u, typos in variable names silently expand to empty strings:
With -u, the script exits immediately with an error message identifying the unset variable.
Why pipefail Matters
Without pipefail, a pipeline's exit status is the exit status of the last command only:
The cat failure is masked because head succeeds. With pipefail, the pipeline inherits the non-zero status from cat, and set -e terminates the script.
Important Exceptions to set -e
set -e does not trigger on every non-zero exit status. Understanding the exceptions prevents confusion:
Commands in Conditional Context
Commands used as conditions in if, while, or until statements are allowed to fail:
Commands Before Logical Operators
Commands on the left side of && or || are exempt:
Commands in Subshells and Command Substitution
The behavior in subshells depends on the Bash version and context. In general, set -e does not propagate into command substitutions in all cases:
Complete Exception Reference
| Context | Does set -e Trigger? | Example |
| Simple command | Yes | false exits the script |
if condition | No | if false; then ... continues |
Left side of && | No | false && echo x continues |
Left side of || | No | false || echo x continues |
| Command substitution | Varies by Bash version | $(false) behavior is inconsistent |
| Functions called in conditional | No | if my_func; then ... continues |
Handling Expected Failures Explicitly
When a command might legitimately fail, suppress it explicitly rather than disabling strict mode:
The || true pattern is the most common. It makes the intent clear: this specific command is allowed to fail. Use it sparingly and only when the failure is genuinely harmless.
Add a Trap for Better Debugging
An ERR trap runs a command whenever a non-zero exit status triggers set -e. This is invaluable for diagnosing failures in CI pipelines and automated deployments:
For scripts that need cleanup regardless of success or failure, trap EXIT instead:
The EXIT trap fires on normal exit, error exit, and most signals, making it the right choice for resource cleanup.
A Production-Ready Script Template
This template combines all the patterns discussed into a reusable starting point:
This gives you automatic failure on unexpected errors, safe variable handling, pipeline failure detection, diagnostic output with line numbers, and a clean structure that separates concerns.
Common Pitfalls
- Assuming set -e is universal. It has documented exceptions for conditionals, logical operators, and subshells. Read the Bash manual section on
errexitto understand the edge cases. - Using set -e without pipefail. A failing command early in a pipeline is silently masked by a successful command at the end. Always pair them.
- Overusing || true. Every
|| trueis a place where errors are intentionally ignored. If you find yourself adding it to many lines, the script may need restructuring rather than more exception suppression. - Forgetting -u and getting silent empty-string expansion. Variable typos are one of the most common causes of destructive Bash bugs, like
rm -rf $UNDEFINED/expanding torm -rf /. - Using set -e in library functions sourced by other scripts. If the calling script does not use
set -e, the behavior is inconsistent. Library functions should validate their own preconditions explicitly. - Not testing trap behavior.
ERRtraps do not fire in the same exception contexts whereset -edoes not fire. Test your error handling with deliberate failures during development.
Summary
set -eexits the script on command failure, but has important exceptions for conditionals and logical operators.set -euo pipefailis the standard strict mode for production scripts, catching errors, unset variables, and pipeline failures.- Handle expected failures explicitly with
|| true, conditional checks, or temporaryset +eblocks. - Use
trap ... ERRfor diagnostic output andtrap ... EXITfor cleanup that must run regardless of outcome. - Structure scripts with a
mainfunction,readonlyconstants, and clear prerequisite validation. - Test error handling deliberately. Do not assume strict mode catches everything without verifying the behavior in your specific Bash version.
Related reading
- AVAudioPlayer throws breakpoint in debug mode
- AVAudioRecorder throws errors
- Avoid reporting Broken Pipe errors to Sentry in a Spring Boot application
- Avoid tensorflow print on standard error
- Avoiding first chance exception messages when the exception is safely handled
- Avro decoding gives java.io.EOFException
- Avro schema with logicalType can't be used with latest confluent-kafka
- await does not return to caller as expected using StreamReader.ReadToEndAsync
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.