iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
If a Bash ERR trap is defined in your script but stays silent inside a function, command substitution, or subshell, enable -E (also written set -o errtrace). -e and -E do different things: -e controls when Bash may exit after a failing command, while -E makes an existing ERR trap inherited in those contexts. Neither setting makes the trap run for every nonzero status.
What does the missing -E do?
In Bash, set -euo pipefail enables three behaviors: errexit (-e), nounset (-u), and pipefail. It does not enable errtrace. Add -E, or its long form -o errtrace, when you want an installed ERR trap inherited by shell functions, command substitutions, and commands run in a subshell environment.
The GNU Bash Reference Manual, Edition 5.3, updated 18 May 2025, states: “If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment.” See the manual’s Shell Builtin Commands section.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How do I add it to the script?
Put -E in the shell options before the code that may call a function or create a command substitution or subshell. For example:
#1 Best Overall
- Used Book in Good Condition
#!/usr/bin/env bash
set -Eeuo pipefail
trap 'printf "ERR: status %s at line %sn" "$?" "$LINENO" >&2' ERR
fail() {
false
}
fail
Here, -E enables inheritance of the parent shell’s trap into fail. The trap is installed before the function call, so the function has a trap to inherit. The example illustrates inheritance; it is not a guarantee that Bash runs an ERR trap for every failure. The command’s syntactic context still matters.
You can use the long option instead: set -euo pipefail -o errtrace. The two forms enable the same errtrace setting.
Why are -e, -E, and pipefail separate?
| Setting | What it changes | What it does not do |
|---|---|---|
-e / errexit |
Makes Bash exit after certain nonzero statuses, subject to documented exceptions. | Does not make an ERR trap inherit into functions, command substitutions, or subshell environments. |
-E / errtrace |
Makes an installed ERR trap inherit into those contexts. |
Does not make the trap run in contexts where Bash suppresses ERR. |
-o pipefail |
Makes a pipeline return the status of its rightmost failing command, or zero if all commands succeed. | Does not enable trap inheritance or change the status of a single command. |
These options address different parts of failure handling. -e affects shell exit behavior, -E affects where the trap exists, and pipefail affects the status Bash assigns to a pipeline.
When does Bash still skip an ERR trap?
Even with -E, Bash does not run ERR for every command that returns nonzero. The manual describes exceptions similar to those for errexit. A failing command generally will not trigger the trap when it is:
- Used as an
iforeliftest. - Used as a
whileoruntilcondition. - Part of an
&&or||list, except for the command whose status determines the list’s result. - A non-final command in a pipeline, subject to the effect of
pipefailon the pipeline’s status. - Inverted with
!.
For example, false in if false; then ...; fi is being used as a condition, so its failure is an expected test result rather than an ordinary unhandled failure. Adding -E does not remove that exception. When debugging a silent trap, check not only whether the failing code runs in a function or subshell, but also how the command is positioned in the surrounding syntax.
Does -E make -e apply inside command substitutions?
No. Trap inheritance and errexit inheritance are distinct. Command substitutions run in subshell environments. Outside POSIX mode, Bash normally clears -e in a command-substitution subshell unless the separate inherit_errexit shell option is enabled. POSIX mode also changes this behavior. The GNU Bash manual explains these rules in Command Execution Environment.
Rank #4
So -E can pass an ERR trap into a command substitution without making -e behave there as it does in the parent shell. If your script depends on both behaviors, configure and test them separately; do not treat errtrace as a substitute for inherit_errexit or POSIX mode.
Recommended Free Tools
Quick Recap
Best Value
How should I diagnose a silent trap?
- Confirm the shell is Bash. These option names and behaviors are Bash-specific; do not assume another shell handles them the same way.
- Check that the trap is installed. A function or subshell can inherit only a trap already set in the relevant parent context.
- Enable inheritance. Use
set -Eorset -o errtracebefore the function, command substitution, or subshell command runs. - Inspect the failing command’s context. Determine whether it is an
iftest, a condition, part of an&&or||list, a pipeline component, or negated with!. - For pipelines, check the returned status.
pipefailchanges how Bash determines pipeline failure; it does not itself propagate the trap. - For command substitutions, check
-eseparately. If you expect errexit behavior to carry over, reviewinherit_errexitand POSIX mode in addition to-E.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

