Skip to content
AgileLogics
6 min read

Traps and Cleanup

Prerequisites: Strict mode: set -euo pipefail

Scripts create temporary files, lock files, and background processes. A trap runs code when the script exits or receives a signal, so cleanup happens even if something fails or the user presses Ctrl + C.

trap on EXIT

set -euo pipefail

workdir=$(mktemp -d)
cleanup() {
  rm -rf "$workdir"
  echo "cleaned up temporary folder"
}
trap cleanup EXIT

echo "working..." > "$workdir/data.txt"
echo "wrote $(wc -l < "$workdir/data.txt") line"
false
echo "never reached"
wrote 1 line
cleaned up temporary folder

The script failed at false, but cleanup still ran. EXIT fires however the script ends: normally, through exit, or from an error under set -e.

Safe temporary files

Never use fixed names like /tmp/myscript.tmp — two runs collide, and another user could create the file first. mktemp creates a unique file (or mktemp -d a directory) that only you can access.

Handling Ctrl + C and termination

# illustrative
on_interrupt() {
  echo "Interrupted — stopping workers" >&2
  kill 0          # signal every process in this script's group
  exit 130
}
trap on_interrupt INT TERM

Exit code 130 (128 + signal 2) is the convention for "stopped by Ctrl + C".

Reporting errors with an ERR trap

An ERR trap runs whenever a command fails — useful for showing where a script died:

set -Eeuo pipefail
trap 'echo "Error on line $LINENO: $BASH_COMMAND" >&2' ERR

step_one() { echo "step one ok"; }
step_two() { cp /no/such/file /tmp/ 2>/dev/null; }

step_one
step_two
step one ok
Error on line 5: cp /no/such/file /tmp/ 2> /dev/null

$LINENO is the line number and $BASH_COMMAND the command that failed.

Common mistakes

  • Setting the trap after creating the temporary file, leaving a gap where a failure skips cleanup. Set traps first.
  • Using trap ... EXIT in several places — each call replaces the previous trap. Keep one cleanup function that handles everything.