Traps & Cleanup

trap ensures cleanup runs regardless of how a script ends — success, failure, or Ctrl+C. Essential for temp files, background processes, and state changes.

Traps and Cleanup

The Problem

Scripts create temp files, start background processes, or modify state. If the script fails midway or the user hits Ctrl+C, cleanup never runs. trap solves this.

Basic Trap Pattern

Clean up temp files on exit — regardless of how the script ends
#!/usr/bin/env bash
set -euo pipefail

TMPFILE=$(mktemp /tmp/mywork.XXXXXX)
trap 'rm -f "$TMPFILE"' EXIT

# ... do work with $TMPFILE ...
echo "processing" > "$TMPFILE"
cat "$TMPFILE"

# EXIT trap fires when script ends — success, failure, or Ctrl+C
# $TMPFILE is always cleaned up
Multiple cleanup actions
#!/usr/bin/env bash
TMPDIR=$(mktemp -d /tmp/build.XXXXXX)
LOGFILE="$TMPDIR/build.log"

cleanup() {
    echo "Cleaning up $TMPDIR..."
    rm -rf "$TMPDIR"
}
trap cleanup EXIT

# ... do work in $TMPDIR ...

Signals

Trap specific signals
trap 'echo "Caught Ctrl+C"; exit 1' INT      # Ctrl+C
trap 'echo "Caught SIGTERM"; exit 1' TERM     # kill
trap 'echo "Script finished"' EXIT            # any exit

# EXIT always fires — even after INT or TERM
# Use EXIT for cleanup, INT/TERM for custom messages
Ignore a signal
trap '' INT    # Ignore Ctrl+C entirely
# Useful for critical sections that must not be interrupted
trap - INT     # Reset to default behavior

Real-World Pattern

Safe script template with temp dir and trap
#!/usr/bin/env bash
set -euo pipefail

WORK=$(mktemp -d /tmp/codex-build.XXXXXX)
trap 'rm -rf "$WORK"' EXIT

# Stage work in temp dir
grep -rl 'pattern' docs/ > "$WORK/matches.txt"
wc -l < "$WORK/matches.txt"

# If script fails here, trap still cleans up $WORK
process_files < "$WORK/matches.txt"

See Also