Handling Interruption
Imagine your script creates a temporary directory, downloads several large files into it, processes them, and then removes the directory at the end. Now imagine a user presses Ctrl+C halfway through. The script terminates immediately. The cleanup code at the end never runs. You have left gigabytes of temporary files on the system.
The trap command solves this. It registers a piece of code to run when the script receives a specific signal — an asynchronous notification sent to a process by the kernel or another process.
Syntax: trap 'commands' SIGNAL [SIGNAL...]
Common signals you will trap in scripts:
| Signal | Trigger | Common Use |
|---|---|---|
EXIT |
Script exits for any reason | Cleanup (most common) |
INT |
User presses Ctrl+C | Graceful interruption |
TERM |
kill command (default) |
Graceful shutdown |
ERR |
Any command fails (with set -e) |
Error logging |
The EXIT signal is the most important. It fires when the script exits for any reason: normal completion, set -e triggering, Ctrl+C, or an explicit exit call. This makes it the right place for cleanup logic: a script that creates a temp directory and immediately registers a trap to remove it on EXIT guarantees the cleanup runs no matter how the script terminates, without needing to duplicate the cleanup code at every possible exit point.
Define the trap before creating the resource it cleans up. If the temp directory is created before the trap is registered, a failure in that gap leaves the directory behind — the trap can only protect resources that exist after it's already active.
Key Point: Traps are inherited by subshells but not by child processes. If your script calls another script, that child script does not inherit your traps. Also, trap '' SIGNAL (empty command string) ignores the signal entirely — useful for preventing a script from being interrupted during a critical section, though this should be used sparingly.