← Back to Bash Course | Chapter 12: Error Handling & Debugging | Lesson 4 of 12

set -e (Exit on Error) and Its Gotchas

set -e tells a script to stop running immediately the moment any command fails, instead of continuing on as if nothing happened.

Basic Exit-on-Error Behavior

With set -e active, a script stops executing as soon as any command returns a non-zero exit status, rather than silently continuing to later lines that might depend on that command having succeeded.

Example: Basic Exit-on-Error Behavior

bash
#!/bin/bash
(
    set -e
    echo "step 1"
    false
    echo "step 2 - never reached"
) || echo "the subshell stopped early because of set -e"

The if-condition Exemption

A command being tested as the condition of if, while, or until is exempt from set -e, because a non-zero status there is expected and meaningful, not a bug.

Example: The if-condition Exemption

bash
#!/bin/bash
(
    set -e
    if false; then
        echo "unreachable"
    else
        echo "set -e did NOT trigger here, because false was an if-condition"
    fi
    echo "the subshell kept running normally"
)

The Pipeline Exemption

Inside a pipeline, plain set -e only reacts to the exit status of the LAST command, so a failure in an earlier stage is silently ignored unless pipefail is also enabled.

Example: The Pipeline Exemption

bash
#!/bin/bash
(
    set -e
    false | true
    echo "reached because only the last command (true) mattered to set -e"
)

(
    set -e -o pipefail
    false | true
    echo "unreachable with pipefail active"
) || echo "with pipefail, the earlier failure was noticed and stopped the subshell"

Catching a set -e Failure Deliberately

Wrapping a risky command in a subshell with its own set -e, and checking the subshell's overall result with ||, lets a script demonstrate or contain a strict failure without letting it kill the whole script.

Note: Test set -e behavior in a small subshell like this before relying on it in a large script; its exemptions are easy to trip over.

Example: Catching a set -e Failure Deliberately

bash
#!/bin/bash
(set -e; false; echo "unreached") || echo "caught: the previous command failed under set -e"
echo "the main script keeps running normally"
Common Mistakes
  1. Assuming set -e catches every possible failure; it does NOT trigger for a failing command inside an if/while condition, before a &&/||, or as any-but-the-last part of a pipeline.
  2. Being surprised a script keeps running after a failing command inside a function call used in a condition, since set -e's exemptions apply there too.
  3. Relying on set -e alone for robust error handling instead of combining it with explicit checks for the specific commands that matter most.
Chapter Summary
  • set -e makes the script exit immediately if a command exits non-zero, instead of continuing to the next line.
  • set -e does NOT apply to a command being tested by if, while, until, or before &&/|| — those are expected to potentially fail.
  • In a pipeline, set -e only reacts to the LAST command's exit status, unless pipefail is also set.
  • set -e is best combined with set -u and set -o pipefail for more predictable strict-mode behavior.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.