Bash Signals and Traps: 7 Smart Tips for Clean Scripts

Bash Signals and Traps are essential for writing resilient shell scripts. Signals notify processes of events like termination, errors, or interrupts. With traps, you can gracefully handle these signals, ensuring your script exits cleanly and performs necessary cleanup tasks.

By mastering Bash Signals and Traps, you can improve script reliability, manage unexpected interruptions, and ensure that temporary files, resources, and states are handled correctly. Let’s explore how signals work and how traps give you fine-grained control over process behavior.

What Are Bash Signals?

Signals in Bash are system-generated notifications sent to processes. They act as interrupts, allowing the operating system or user actions to interact with running scripts.

Some common Bash signals include:

  • INT (Interrupt): Triggered by Ctrl+C, used to stop a process.
  • QUIT (Quit): Triggered by Ctrl+\, often for forceful termination.
  • TERM (Terminate): Requests a process to stop safely.
  • HUP (Hangup): Sent when a terminal closes.
  • USR1/USR2 (User Signals): Custom-defined signals for scripts.

These signals let you manage process flow, making them especially important in automation, servers, and long-running jobs.

The Trap Command in Bash

The trap command is Bash’s built-in way to handle signals. It lets you define actions that run when a script receives specific signals.

Syntax:

trap 'commands' SIGNAL [SIGNAL ...]
  • commands: The action to perform when the signal is received.
  • SIGNAL: The signal name or number (e.g., INT, TERM).

With traps, you gain direct control over how your script responds, from cleanup tasks to logging or even ignoring signals entirely.

Example: Handling Ctrl+C Gracefully

A common use case for Bash Signals and Traps is handling Ctrl+C (SIGINT) interruptions. Instead of stopping abruptly, you can define a cleanup function.

#!/bin/bash

cleanup() {
    echo "Cleaning up temporary files..."
    rm -f /tmp/my_temp_file
}

trap cleanup INT  # Trap Ctrl+C

echo "Script running. Press Ctrl+C to stop."
sleep 10

When you press Ctrl+C, the script doesn’t exit immediately. Instead, it runs the cleanup function first, ensuring a safe exit.

Example: Custom Signal Handling

Bash also supports custom signals like USR1 or USR2. These are handy when you need inter-process communication.

#!/bin/bash

custom_handler() {
    echo "Received USR1 signal!"
}

trap custom_handler USR1

echo "Running script with PID $$"
while true; do
    sleep 2
done

To send a signal:

kill -USR1 <PID>

This approach is useful for monitoring, triggering log writes, or performing periodic checks during execution.

Ignoring Signals with Traps

Sometimes you don’t want a signal to stop your script. For example, ignoring SIGQUIT ensures your script keeps running.

trap '' QUIT

Here, the empty string ('') tells Bash to ignore the signal. This is common in critical automation tasks where accidental interrupts should not terminate execution.

Advanced Trap Usage

Traps in Bash can be dynamic, even nested inside other traps, making scripts more adaptive.

#!/bin/bash
count=1

trap 'echo "First QUIT received!"; count=$((count+1)); trap "echo QUIT trapped $count times" QUIT' QUIT

while true; do
  sleep 1
done

In this script, the first QUIT signal triggers one action, and subsequent signals trigger another. This flexibility makes Bash Signals and Traps powerful for advanced error handling and control.

Using EXIT and ERR Traps

Besides signals, Bash provides EXIT and ERR traps:

  • EXIT: Runs when the script ends, whether normally or due to a signal.
  • ERR: Runs whenever a command fails (non-zero exit code).

Example:

#!/bin/bash

trap 'echo "Script exited!"' EXIT
trap 'echo "Error occurred!"' ERR

ls /nonexistent_dir  # This will trigger ERR

These traps improve debugging and allow you to enforce consistent exit behavior.

Practical Use Cases of Bash Signals and Traps

1. Ensuring Cleanup on Exit

Scripts that create temp files, open sockets, or lock resources should clean up on termination. Traps guarantee no leftover files or zombie processes.

2. Long-Running Background Jobs

Automated scripts or daemons can handle signals gracefully, writing logs or restarting tasks instead of crashing.

3. Logging and Monitoring

Using custom traps like USR1, you can log memory usage, send metrics, or output debug data without stopping the script.

4. Deployment Scripts

Traps help in stopping deployments safely when aborted midway, ensuring resources are rolled back correctly.

Best Practices for Bash Signals and Traps

  • Always use cleanup functions instead of inline commands for clarity.
  • Avoid trapping signals that should always terminate (like KILL or STOP), as they cannot be caught.
  • Combine set -e with ERR traps for robust error handling.
  • Test your traps thoroughly in different scenarios (manual interrupt, kill signals, SSH disconnection).
  • Document which signals your script traps for maintainability.

Key Takeaways

  • Bash Signals and Traps let you handle interruptions, exits, and custom events effectively.
  • Use trap for cleanup, logging, or ignoring signals.
  • Combine built-in traps like EXIT and ERR with user-defined signals for complete control.
  • Following best practices ensures your scripts are reliable, secure, and production-ready.

FAQ on Bash Signals and Traps

1. What is the purpose of traps in Bash?

Traps allow you to intercept signals and define custom actions, such as cleaning up files, logging, or ignoring interruptions.

2. Can Bash traps handle all signals?

No. Signals like SIGKILL and SIGSTOP cannot be trapped or ignored. They are designed to forcefully control processes.

3. What is the difference between EXIT and TERM in Bash?

EXIT is a Bash-specific trap triggered when the script ends. TERM is a system signal requesting process termination.

4. How do I ignore a signal in Bash?

You can ignore a signal by setting an empty trap:
trap '' QUIT

5. Are Bash Signals and Traps useful in automation?

Yes. They make scripts more robust by handling unexpected events, ensuring safe exits, and maintaining system stability in automation workflows.

Scroll to Top