← Back to Bash Course | Chapter 11: Process Management | Lesson 6 of 12

Signals and trap

Signals are short notifications sent to a running program, like "please stop" or "clean up now", and trap lets a script react to them instead of just being killed silently.

Cleanup with an EXIT Trap

trap commands EXIT registers code that runs automatically when the script exits, whether it finished normally, hit exit, or failed, which makes it the standard way to guarantee cleanup (like removing temp files) happens.

Example: Cleanup with an EXIT Trap

bash
#!/bin/bash
trap 'echo "cleanup: removing temp file"; rm -f /tmp/trap_demo_$$.txt' EXIT
echo "work" > "/tmp/trap_demo_$$.txt"
echo "doing some work..."

Handling a Self-Sent Signal Safely

SIGUSR1 is a user-defined signal whose default action, unless trapped, is simply to terminate the process; trapping it lets a script react to a self-sent (or externally sent) signal without the risk of being killed outright, unlike SIGTERM or SIGINT which are riskier to demonstrate.

Warning: Trapping SIGTERM or SIGINT for a demo is riskier: if the handler doesn't explicitly prevent termination, the shell can still exit with a 128+signal status, which is why SIGUSR1 is a safer teaching example.

Example: Handling a Self-Sent Signal Safely

bash
#!/bin/bash
handle_usr1() {
    echo "received SIGUSR1, handling it gracefully"
}
trap handle_usr1 SIGUSR1

kill -SIGUSR1 $$
echo "script continues normally after the signal was handled"

Combining Multiple Traps

A script can register different handlers for different signals, and an EXIT trap will still fire even after a signal-triggered handler runs, letting you separate signal-specific reactions from general cleanup.

Example: Combining Multiple Traps

bash
#!/bin/bash
trap 'echo "final cleanup ran"' EXIT
trap 'echo "custom SIGUSR1 handler ran"' SIGUSR1

kill -SIGUSR1 $$
echo "main script logic continues"

Resetting a Trap

trap - SIGNAL removes a previously set handler and restores the signal's default behavior, which is useful once a risky section of a script that needed special handling is complete.

Example: Resetting a Trap

bash
#!/bin/bash
trap 'echo "handler active"' SIGUSR1
kill -SIGUSR1 $$

trap - SIGUSR1
echo "handler removed, back to default behavior for SIGUSR1"
Common Mistakes
  1. Forgetting the EXIT trap fires on every kind of script exit, including normal completion, not just errors.
  2. Sending SIGTERM or SIGINT to yourself as a teaching example and being surprised the script actually terminates; a trapped signal can still end the process if the handler doesn't prevent it, and the script's exit status becomes 128+signal number.
  3. Setting a trap for a signal after the point where it might occur, missing the window it was meant to guard.
Chapter Summary
  • trap commands EXIT runs commands whenever the script exits, for any reason, making it ideal for cleanup.
  • trap commands SIGNAL runs commands when that specific signal arrives, instead of the signal's default action.
  • kill -SIGNAL $$ sends a signal to the current script's own process.
  • A process that receives a fatal signal and does not fully handle it typically exits with status 128 + the signal number.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.