trap Command
Intermediate Shell Scripting man(1)Handle signals and cleanup in shell scripts
📅 Updated: Mar 16, 2026
SYNTAX
trap COMMAND SIGNAL [SIGNAL...]
What Does trap Do?
The trap command sets up signal handlers in shell scripts — executing specified commands when the script receives a signal (like SIGINT from Ctrl+C), exits (EXIT), or encounters an error (ERR). It is one of the most important commands for writing robust, production-quality shell scripts.
The most common use of trap is cleanup on exit — removing temporary files, releasing locks, restoring terminal settings, or sending notifications when a script finishes. Without trap, scripts that are interrupted (Ctrl+C, kill, error) leave behind temporary files, locked resources, and incomplete state.
trap handles several types of events: EXIT (any script exit, normal or abnormal), SIGINT (Ctrl+C), SIGTERM (kill command), ERR (any command returning non-zero with set -e), SIGHUP (terminal hangup), and RETURN (function/source return). You can set multiple traps for different signals.
Understanding trap is essential for system administration scripts, deployment scripts, backup scripts, and any script that creates temporary resources or needs guaranteed cleanup.
The most common use of trap is cleanup on exit — removing temporary files, releasing locks, restoring terminal settings, or sending notifications when a script finishes. Without trap, scripts that are interrupted (Ctrl+C, kill, error) leave behind temporary files, locked resources, and incomplete state.
trap handles several types of events: EXIT (any script exit, normal or abnormal), SIGINT (Ctrl+C), SIGTERM (kill command), ERR (any command returning non-zero with set -e), SIGHUP (terminal hangup), and RETURN (function/source return). You can set multiple traps for different signals.
Understanding trap is essential for system administration scripts, deployment scripts, backup scripts, and any script that creates temporary resources or needs guaranteed cleanup.
Options & Flags
| Option | Description | Example |
|---|---|---|
| trap COMMAND EXIT | Execute command when script exits (any reason) | trap "rm -f /tmp/lockfile" EXIT |
| trap COMMAND SIGINT | Handle Ctrl+C interrupt | trap "echo Interrupted; exit 1" SIGINT |
| trap COMMAND SIGTERM | Handle kill/terminate signal | trap "cleanup; exit" SIGTERM |
| trap COMMAND ERR | Execute on any command error (with set -e) | trap 'echo "Error at line $LINENO"' ERR |
| trap '' SIGNAL | Ignore a signal (empty string handler) | trap '' SIGINT |
| trap - SIGNAL | Reset signal to default handler | trap - SIGINT |
| trap -p | Print current trap settings | trap -p |
Practical Examples
#1 Cleanup temporary files on exit
Remove temp file when script exits — whether normally, by Ctrl+C, or on error. The most common and important trap pattern.
$ #!/bin/bash\ntmpfile=$(mktemp)\ntrap "rm -f $tmpfile" EXIT\n# script work here...\necho "data" > "$tmpfile"#2 Handle Ctrl+C gracefully
Catch Ctrl+C, run cleanup function, then exit with code 130 (128+SIGINT=2).
$ #!/bin/bash\ntrap "echo; echo 'Interrupted. Cleaning up...'; cleanup; exit 130" SIGINT\nfunction cleanup() { rm -f /tmp/lockfile; }\n# long-running work...#3 Error handling with line number
On any error, print the line number and failed command. Combined with set -e for fail-fast behavior.
$ #!/bin/bash\nset -euo pipefail\ntrap 'echo "ERROR at line $LINENO: command \\"$BASH_COMMAND\\" failed with exit code $?"' ERR\n# script continues...#4 Release lock file on exit
Create a lock file and ensure it is always removed, even if the script crashes.
$ #!/bin/bash\nLOCKFILE="/var/run/myscript.lock"\nif [ -f "$LOCKFILE" ]; then echo "Already running"; exit 1; fi\ntouch "$LOCKFILE"\ntrap "rm -f $LOCKFILE" EXIT\n# script work...#5 Multiple signal handlers
Set different handlers for different signals. EXIT trap runs AFTER SIGINT/SIGTERM handlers.
$ #!/bin/bash\ntrap "echo Normal exit" EXIT\ntrap "echo Ctrl+C pressed; exit 130" SIGINT\ntrap "echo Terminated; exit 143" SIGTERM#6 Cleanup function pattern
Define a cleanup function that handles multiple resources. Call it from trap for any exit scenario.
$ #!/bin/bash\ncleanup() {\n echo "Cleaning up..."\n [ -f "$tmpfile" ] && rm -f "$tmpfile"\n [ -f "$lockfile" ] && rm -f "$lockfile"\n docker rm -f test-container 2>/dev/null\n}\ntrap cleanup EXIT\ntmpfile=$(mktemp)\nlockfile="/tmp/deploy.lock"#7 Ignore signals during critical section
Temporarily make script un-interruptible during critical operations like database writes.
$ #!/bin/bash
trap '' SIGINT SIGTERM # ignore during critical section
# critical database update here...
trap - SIGINT SIGTERM # restore default handlersTips & Best Practices
Always use trap EXIT for cleanup: trap EXIT runs on ANY exit — normal, error, Ctrl+C, or kill. It is the most reliable way to ensure cleanup. Use it for temp files, lock files, and resource release.
EXIT trap runs after signal traps: If you have both SIGINT and EXIT traps, on Ctrl+C: SIGINT handler runs first, then EXIT handler. Avoid duplicating cleanup in both handlers.
SIGKILL cannot be trapped: kill -9 (SIGKILL) cannot be trapped or caught by any process. Avoid kill -9 in scripts — use kill (SIGTERM) first to allow clean shutdown.
Use with set -e: Combine trap ERR with set -e (exit on error) for robust error handling: set -euo pipefail; trap 'echo "Error line $LINENO"' ERR
Frequently Asked Questions
How do I clean up temporary files when a script exits?
Use: trap "rm -f $tmpfile" EXIT — this runs the rm command no matter how the script exits (normal, error, Ctrl+C, kill).
How do I handle Ctrl+C in a bash script?
Use: trap "echo Interrupted; cleanup; exit 130" SIGINT. The exit code 130 is the convention for SIGINT (128 + signal number 2).
Can I trap SIGKILL (kill -9)?
No. SIGKILL and SIGSTOP cannot be caught, blocked, or handled. Always use SIGTERM (kill) first to allow scripts to clean up. SIGKILL should be a last resort.
What is the difference between trap EXIT and trap SIGTERM?
EXIT runs on ANY script exit (normal, error, signal). SIGTERM only runs when the script receives a terminate signal. EXIT is more comprehensive — use it for cleanup.
Related Commands
More Shell Scripting Commands
Master Linux with Professional eBooks
Curated IT eBooks covering Linux, DevOps, Cloud, and more
Browse Books →