trap: Usage, Options & Common CI Errors
trap registers a command to run when the shell receives a signal or is about to exit.
trap is how robust CI scripts guarantee cleanup - stop a container, remove a temp dir, kill a background server - even when the script fails partway. The EXIT pseudo-signal is the workhorse.
What it does
trap arranges for a command to run when the shell receives one of the listed signals, or on the special EXIT (always) or ERR (on any failing command) conditions. It is the standard cleanup mechanism.
Common usage
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT # cleanup no matter how we exit
trap 'docker rm -f db || true' EXIT
trap 'echo "failed at line $LINENO"' ERR
trap - EXIT # remove a trap
trap '' INT # ignore Ctrl-COptions
| Item | What it does |
|---|---|
| trap 'cmd' EXIT | Run cmd whenever the shell exits |
| trap 'cmd' ERR | Run on any command failure (bash) |
| trap 'cmd' INT TERM | Run on those signals |
| trap - SIG | Reset a signal to default |
| trap '' SIG | Ignore a signal |
Common errors in CI
Quoting matters: trap "rm -rf $tmp" EXIT expands $tmp NOW (when the trap is set, maybe before it is assigned); use single quotes trap 'rm -rf "$tmp"' EXIT to expand at trap time. An EXIT trap runs on every exit including success and even other traps, so make handlers idempotent and tolerant (|| true). ERR is not POSIX and interacts with set -e and functions; test it. A trap set after the failing command never fires for that failure.