trap
Execute commands upon receiving signals
TLDR
List the commands and the names of the expected events
Execute a command when a signal is received
Remove commands
SYNOPSIS
trap [command] [signal ...]
trap -l
trap -p [signal ...]
trap -r [signal ...]
PARAMETERS
command
A string containing the command(s) to be executed when the specified signal is received or event occurs. If command is an empty string (`""` or `''`), the trap for the specified signal is reset to its default action. If command is `'-'`, the signal is ignored by the shell and its children.
signal
One or more signal names (e.g., SIGINT, TERM, HUP) or signal numbers (e.g., `2` for SIGINT). Special event names include:
* EXIT (or `0`): The command is executed when the shell exits.
* ERR: The command is executed whenever a command exits with a non-zero status.
* DEBUG: The command is executed before every simple command, for command, case command, select command, while command, or until command, or after a function definition.
* RETURN: The command is executed each time a shell function or a sourced script finishes executing.
-l
Displays a list of signal names and their corresponding numbers.
-p
Prints the trap commands associated with each signal, in a format that can be reused as input to trap. If no signal is specified, all current traps are printed.
-r
Resets the action for each specified signal to its default (initial) state. If no signal is specified, all traps are reset. This is similar to setting an empty command string for each signal but specifically resets to default, not just ignores.
DESCRIPTION
The trap command is a powerful shell built-in that allows a script to capture and react to signals or other events. When a specified signal (like SIGINT for Ctrl+C, SIGTERM for termination, or SIGHUP for hangup) is received by the shell, or a special event occurs (like EXIT when the shell exits, ERR when a command exits with non-zero status, DEBUG before each command execution, or RETURN after a shell function/source script returns), trap executes a user-defined command.
This is crucial for robust script design, enabling clean-up operations, graceful shutdowns, or debugging. Without trap, many signals would terminate a script abruptly, potentially leaving temporary files or processes orphaned. It can also be used to ignore signals or reset their default behavior.
CAVEATS
trap is a shell built-in command, meaning its behavior can slightly vary between different shells (e.g., Bash, Zsh, Dash).
Traps are inherited by subshells, but changes made to traps within a subshell are generally not propagated back to the parent shell.
The DEBUG trap can significantly impact script performance due to its frequent execution.
Signal handling can be complex, especially concerning asynchronous events and race conditions. Care must be taken when designing trap handlers, particularly in multi-process or heavily-threaded scripts.
Some signals, like SIGKILL and SIGSTOP, cannot be caught or ignored by trap.
COMMON USE CASES
Clean-up on Exit: trap 'rm -f /tmp/mytempfile' EXIT
Graceful Shutdown: trap 'cleanup; exit' INT TERM HUP
Error Handling: trap 'echo "Error on line $LINENO: $BASH_COMMAND" >&2' ERR
Debugging: trap 'echo "Command: $BASH_COMMAND, Line: $LINENO" >&2' DEBUG
SIGNAL NUMBERS VS. NAMES
While signal numbers can be used, it is generally recommended to use signal names for better readability and portability, as signal numbers can sometimes vary across different systems.
TRAP STACK (BASH SPECIFIC)
Bash supports a trap stack for DEBUG and RETURN traps. Using trap -p and trap - can help manage this, allowing functions to add and remove their own traps without interfering with existing ones.
HISTORY
The trap command has been a fundamental component of Unix shells for decades, providing a robust mechanism for script control and error handling. It was present in early versions of the Bourne shell and has since been incorporated into POSIX standards, ensuring its consistent availability across modern Unix-like operating systems. Its utility in handling script termination, unexpected errors, and debugging has made it an indispensable tool for shell programmers.