🎓 A1Learner
🔍
0 of 45 lessons completed

Bash Trap Inheritance

Trap inheritance decides which traps a function or subshell sees. The rules differ for plain traps, ERR traps, and DEBUG traps.

A function sees the caller's trap

trap -p inside the function prints the parent's handler. The function shares the caller's trap table.

trap 'echo "handler"' USR1
work() { trap -p USR1; echo "inside function"; }
work

A trap change inside a function outlives the function

The function installs a new handler, then returns. The caller's listing shows the new handler, not the old one.

trap 'echo "first handler"' USR1
change() { trap 'echo "second handler"' USR1; }
change
trap -p USR1

A trap change inside a subshell never reaches the parent

The subshell listing shows its own handler. The parent listing after it still shows the parent handler.

trap 'echo "parent handler"' USR1
( trap 'echo "subshell handler"' USR1; trap -p USR1 )
trap -p USR1

Example

trap 'echo "ERR caught"' ERR
set -E
work() { false; echo "work continues"; }
work
echo "script done"

Key points

  • Functions share traps: a function runs in the same shell, so it sees the caller's traps.
  • Function changes persist: a trap set inside a function stays set after the function returns.
  • Subshell changes stay local: a trap set inside parentheses never reaches the parent.
  • Parent EXIT waits: a parent EXIT trap does not fire when a subshell ends.
  • Subshell EXIT works: a trap set inside a subshell fires when that subshell ends.
  • ERR needs errtrace: a function inherits the ERR trap only with set -E.
  • Ignored stays ignored: a signal ignored in the parent stays ignored in a subshell.
  • DEBUG needs functrace: a function inherits the DEBUG trap only with set -T.

In this example, an ERR trap is set first, then set -E turns on errtrace. The function work fails on false, so the inherited ERR trap prints its line. Work then continues, and the script prints its final line.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A function sets a new USR1 trap and returns. What does the caller see afterwards?