LinuxCommandLibrary

trap

Execute commands upon receiving signals

TLDR

List the commands and the names of the expected events

$ trap
copy

Execute a command when a signal is received
$ trap 'echo "Caught signal [SIGHUP]"' [HUP]
copy

Remove commands
$ trap - [HUP] [INT]
copy

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.

SEE ALSO

kill(1), set(1), wait(1), nohup(1)

Copied to clipboard