[Explained] Bash “trap” Command for Signal Handling

Mastering signal handling in Bash scripting opens doors to enhanced control and reliability in script execution. The trap command stands as the heart of the signal handling in Bash scripting. This article will dive into the intricacies of the trap command in signal handling.

What is “trap” Command in Bash Scripting?

The trap command in Bash scripting is a powerful tool used to handle signals and errors that may happen during script execution. Signals are notifications sent by the operating system or other processes to a running program. The trap command can intercept such events for example: user interruptions or system events. This command allows users to define specific actions or commands to execute when a particular signal is received.

The basic syntax of the trap command is as follows:

trap [COMMANDS] [SIGNALS]
EXPLANATION

Here,

  • trap: Bash command for signal handling.
  • COMMANDS: Actions or functions to be executed when the specified signal is received.
  • SIGNALS: Denotes the signal or signals to trap.

The synopsis of the trap command taken from the official manual page is as follows:

trap [-lp] [[arg] signal_spec ...]
EXPLANATION

Here,

  • trap: Bash command for signal handling.
  • -l: Displays a list of signal names and their corresponding numbers.
  • -p: Displays the trap command associated with each signal.
  • arg: Optional argument that represents the action or command to be executed when the specified signal is received. If no argument is provided then the action associated with the signal will be reset to its default behavior.
  • signal_spec: Name or the associated number of the signal or signals.

How Can “trap” Command Be Used in Signal Handling?

The trap command in Bash is essential for signal handling. It allows the script to intercept signals sent by the operating system or the other processes and define custom actions to execute in response. To trap a signal first specify the signal or signals you want to trap. Then follow the signals with the action or commands to execute when the signal is received.

For example, to handle the SIGINT signal which is sent when the user presses Ctrl+C, you can use the trap command. Using the trap command you can define a custom action such as displaying a message or executing cleanup tasks etc when the signal is received.

To display a custom message when the SIGINT signal is received, execute the following command:

trap ‘echo “SIGINT received. Terminating current task…”; exit’ SIGINT
EXPLANATION

This command sets up a signal handler for the SIGINT. It ensures that when this signal is received, the script responds by displaying “SIGINT received. Terminating current task…” message. Then the trap command terminates the current task.

Bash Signal Handler

The signal handler is a mechanism used to intercept and handle signals received by a Bash script during its execution. When a script receives a signal, instead of allowing the default behavior associated with that signal to occur, a signal handler allows the script to execute custom code in response to the signal. In Bash scripting, the signal handlers are typically defined using the trap command.

5 Examples of Bash Trap Handling

Bash trap signals offer a powerful mechanism for enhancing the robustness and control of Bash scripts. Using signal handlers with the trap command script can gracefully respond to various events such as user interruptions, errors, or external signals from the operating system. This capability ensures scripts can perform cleanup tasks, handle errors, or take actions based on the signals received. This article will discuss how to trap some common signals in Linux.

1. Bash Trap SIGTERM

The SIGTERM signal which is short for “signal termination” is the standard signal sent to a process to request its termination. It is a gentle way of asking a process to shut down, unlike the SIGKILL signal which immediately terminates a process, which allows the process to perform cleanup tasks and then exit gracefully. Typically, the kill command and the system shutdown initiate this signal. The associative number with the SIGTERM signal is 15.

When a process receives the SIGTERM signal, it has the opportunity to handle the signal, typically by executing cleanup actions before terminating. This allows the process to release resources, save data, or perform any other necessary tasks before shutting down.

The following example demonstrates how to run a script in the background and then use the SIGTERM signal to terminate the script execution with proper cleanup gracefully:

First, create a script named “count.sh” with the following command:

#!/bin/Bash

# Function to perform cleanup tasks
cleanup() {
  echo "SIGTERM received. Cleaning up..."
  cat temp.txt  # Echo the contents of temp.txt to the terminal
  rm temp.txt   # Remove the temp.txt file
  exit 0
}

# Trap SIGTERM signal and call cleanup function
trap 'cleanup' SIGTERM

# Infinite loop to count numbers and write it to temp.txt
count=1
while true; do
  echo "$count" > temp.txt  # Write current count to temp.txt
  ((count++))
  sleep 1  # 1 second delay between each count
done
EXPLANATION

The Bash script starts with defining a function named cleanup(). This function prints a message using the echo command, displays the contents of the “temp.txt” file using the cat command, removes the temp.txt file using the rm command, and then exits the script. The script then uses the trap command to intercept the  SIGTERM signal and in response call the cleanup function. In the main part of the script, it initializes a variable named “count” to 1 and enters an infinite loop. Inside the loop, the script writes the value of count to temp.txt, increments the count, and then waits for 1 second before repeating the process.

Then, execute the script in the background using &(background operator) after the command:

./count.sh &

This will allow the script to continue running in the background while you perform other tasks in the terminal.

Now to send the SIGTERM signal to the background process, the process ID (PID) of the process is needed. To check the PID of the task, execute the following command:

pgrep -f count.sh

The pgrep is a command line utility used to search for processes based on certain criteria and print their PID. With the -f option this command searches for process which command line matches the pattern “count.sh” and prints that process’s PID.

Finally, send the SIGTERM signal to the process with the help of the kill command using:

kill -15 <PID>

Here, make sure to replace the <PID> with the actual PID you found in the previous step. The kill command is used to send signals to a process or terminate the process. In this command kill command was sent with signal number 15 which corresponds to the SIGTERM signal to the count.sh script’s background execution process. So this command essentially requests the process to gracefully terminate and perform cleanup tasks before exiting.

run script in background and then send SIGTERM signal to the process

Here the script is executed in the background. After using the pgrep utilities the process’s PID is found. Then a SIGTERM signal is sent to the process for graceful termination.

2. Bash Trap SIGINT

The SIGINT signal which stands for “signal interrupt” is a standard signal sent to a process when the user interrupts it by pressing Ctrl+C. The corresponding signal for the SIGINT signal is 2. When the user presses the Ctrl+C the terminal sends the SIGINT signal to the foreground process running in the terminal. Upon receiving the SIGINT signal the process typically terminates, unless it has a custom signal handler defined to handle the SIGINT signal differently.

The following example demonstrates how to interrupt a script execution with the SIGINT signal:

#!/bin/Bash

# Define the trap command to handle SIGINT
trap 'echo; echo "SIGINT received. Exiting..."; exit' SIGINT

# Infinite loop to simulate a long-running process
while true; do
  echo "Press Ctrl+C to exit"
  sleep 1
done
EXPLANATION

This Bash script sets up a trap to handle the SIGINT signal. When the SIGINT signal is received the trap command executes a command to print a message “SIGINT received. Exiting…” and then exits the script gracefully. Then the script starts an infinite loop. In the loop, the script echoes a message and then waits for 1 second before repeating it.

During script execution, if SIGINT is sent by pressing Ctrl+C then the trap mechanism set with the trap command is triggered, and then the script terminates after echoing a message stating SIGINT is received.

script handling SIGIINT signal in bash

Here first the script is executed. Then the SIGINT signal is sent to the script by pressing the Ctrl+C key from the keyboard which triggers the trap handler. The trap handler then displays a message and then terminates the process.

3. Bash SIGKILL Signal

In the Linux operating system, the SIGKILL signal which stands for “signal kill” is a special signal. Its corresponding signal number is 9. It is used to forcefully terminate a process. Unlike other signals such as SIGTERM, SIGINT, or SIGQUIT which allow processes to catch or handle the signal, the SIGKILL signal can not be intercepted, blocked, or ignored by the process receiving it.

The purpose of the SIGKILL signal is to forcibly terminate a process without giving it a chance to clean up or handle the signal. When a process receives the SIGKILL signal it is immediately terminated by the operating system without the opportunity to do anything. This makes SIGKILL signal a powerful tool for terminating unresponsive or problematic processes that can not be terminated through other means. It is often used as a last resort to terminate processes that are consuming excessive resources, causing instability, or interfering with the system’s operation. However, as it does not allow processes to perform any cleanup or gracefully release the resources, it can lead to unintended data loss or data corruption. So, use the SIGKILL signal with caution.

To send the SIGKILL signal to a process, use the following command:

kill -9 <PID>

Here, the kill command with the -9 option indicates the SIGKILL signal will be sent to the mentioned PID.

Note: To check the PID of a process you can use the ps command or the pgrep utilities:

ps aux | grep process_name

This command will display detailed information about all processes containing the specified name. You can identify the PID from the output:

pgrep process_name

This command will display the PID of the matching process.

4. Bash SIGSTOP & SIGCONT Signals

The SIGSTOP signal which stands for “signal stop” stops a process. When the operating system sends the SIGSTOP signal to a process, it immediately suspends the process and places it into a stopped state. Signal number 19 denotes this signal.

The SIGCONT (signal continue) signal resumes the execution of a stopped process. When a process receives the SIGCONT signal, it resumes execution from where it was previously stopped. The correspondent signal number for this signal is 18.

Both the SIGSTOP and SIGCONT signals are special because processes cannot catch, ignore, or handle them. System administrators often utilize these signals for debugging, troubleshooting, or administrative tasks. The combination of these two signals allows for temporarily halting the execution of a process without terminating it and then resuming the stopped state of the process.

While users can not directly trap or handle the SIGSTOP and the STICONT signals in a Bash script, they can still send these signals to processes using the kill command. To send the SIGSTOP signal to a process to stop a process use any of the following commands:

kill -STOP <PID>
kill -19 <PID>

To send the SIGCONT signal to a process to resume a process use any of the below commands:

kill -CONT <PID>
kill -18 <PID>

5. Bash Trap All Signals

In Bash scripting, it is not possible to directly handle all signals with the trap command. However, it is possible to manually define trap handlers for specific signals or use a loop to set up trap handlers for a range of signals. The following example showcases how to set up trap handlers for a range of common signals:

#!/bin/Bash

# Define a function to handle signals by name
handle_signal() {
  local signal_name="$1"
  echo "Signal $signal_name received."
  exit 
}

# List of signal names
signal_names="HUP INT QUIT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM"

# Trap signals by name and call the handle_signal function
for sig in $signal_names; do
  trap 'handle_signal $sig' $sig
done

# Infinite loop to keep the script running
while true; do
  echo "Script is running..."
  sleep 5
done
EXPLANATION

The script starts with defining a function called handle_signal() that takes the signal name as an argument and then echoes a message indicating the received signal. The script then lists a set of signal names and sets a trap handler for each of the signals using the trap command within a for loop. The trap handler calls the handle_signal function with the signal name as an argument when any of the traps is triggered. Finally, the script enters an infinite loop to keep the script running while displaying a message saying “Script is running” after every 5 seconds.

the script executed in a tmux terminal then SIGSTOP, SIGCONT, SIGKILL, and SIGTERM signals are sent to the process

Here, the tmux terminal multiplexer is used to split the terminal into 2 vertical panes to show all processes. First, the script is executed. Then the the SIGSTOP, SIGCONT, SIGKILL, and SIGTERM signals are sent to the process to showcase different signal behaviors and the script’s trap-handling capabilities.

Conclusion

In conclusion, the trap command stands as a cornerstone in the realm of Bash scripting. From intercepting user interruptions to gracefully terminating processes, the trap command serves as a beacon of control and reliability in Bash scripting. I hope this article was able to help you get a better understanding of signal handling using the trap command in Bash scripting.

People Also Ask

What is the trap command?

The trap command is a tool used to handle signals during script execution in Bash scripting. Signals are notifications sent by the operating system or other processes to a running program indicating events like user interruptions or system events. The trap command allows users to define specific actions or commands to execute when a particular signal is received.

What does trap command do in Bash?

The trap command in Bash is a mechanism that handles signals during script execution. Signals are notifications sent by the operating system or other processes to a running process. The trap command acts as a trigger for intercepting signals and executing commands in response. It allows users to define actions that should be taken when a specific signal is received such as exiting the script gracefully or cleaning up resources. It ensures that scripts execute smoothly and handle unexpected situations effectively.

How do you trap a signal in Linux?

To trap a signal in Linux, users specify the signal they want to catch and the action to perform when it is received. It involves using the trap command in Bash. This command allows users to intercept signals sent to a script or program and define actions to be taken in response. This action could be executing a specific command, ignoring the signal, or performing cleanup tasks.

What is trap handler in Linux?

In linux a trap handler refers to a mechanism used to intercept and handle signals within a script. When a signal is received the trap handler executes predefined actions such as running specific commands or performing cleanup tasks. It allows users to gracefully respond to events like interrupts, errors, or unexpected behavior. Trap handlers enhance the reliability and robustness of scripts by providing a way to manage signal handling effectively. They ensure that scripts can handle various scenarios and continue executing without disruption.

How to ignore signals in Linux?

To ignore signals in Linux you can use the trap command with an empty action. This tells the system to disregard the signal when it is received. For example, to ignore the SIGINT signal which is generated when Ctrl+C is pressed, you can use the command “trap ” SIGINT”. This ensures that the signal is ignored and does not interrupt the execution of the script. Ignoring signals can be useful in scenarios where you want to prevent certain interruptions or gracefully handle specific events without disruptions.

What is signal in Linux?

A signal in Linux is a message or notification about a specific event or condition sent by the operating system or other process to your script or program. These events can range from user input such as pressing Ctrl+C to send a SIGINT signal, to system events like a process terminating or encountering an error. Signals are used to facilitate communication between processes allowing them to respond to various situations dynamically. Each signal has a unique identifier and predefined behavior, influencing how processes react when they receive a signal.

Related Articles


<< Go Back to Bash Signals Handling | Bash Process and Signal Handling | Bash Scripting Tutorial

Rate this post
LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now
icon linux
Ridoy Chandra Shil

Hello everyone. I am Ridoy Chandra Shil, currently working as a Linux Content Developer Executive at SOFTEKO. I am a Biomedical Engineering graduate from Bangladesh University of Engineering and Technology. I am a science and tech enthusiast. In my free time, I read articles about new tech and watch documentaries on science-related topics. I am also a big fan of “The Big Bang Theory”. Read Full Bio

Leave a Comment