Unix / Linux - Signals and Traps
Hello there, future computer wizards! Today, we're diving into the fascinating world of Unix/Linux signals and traps. Don't worry if you're new to programming - I'll guide you through this adventure step by step, just like I've done for countless students over my years of teaching. So, let's embark on this exciting journey together!
What are Signals?
Imagine you're in a busy restaurant kitchen. The chef (let's call him Chef Unix) needs to communicate with his staff quickly. Instead of shouting over the noise, he uses a system of hand signals. That's pretty much what signals are in the Unix/Linux world - a way for processes to communicate quickly and efficiently.
Signals are software interrupts sent to a program to indicate that an important event has occurred. These events can range from user requests to exceptional runtime occurrences.
List of Signals
Just like Chef Unix might have different hand signals for "more salt," "hurry up," or "take a break," Unix/Linux systems have a variety of signals for different purposes. Let's look at some of the most common ones:
Signal Name | Signal Number | Description |
---|---|---|
SIGHUP | 1 | Hangup detected on controlling terminal or death of controlling process |
SIGINT | 2 | Interrupt from keyboard (Ctrl+C) |
SIGQUIT | 3 | Quit from keyboard (Ctrl+) |
SIGKILL | 9 | Kill signal (cannot be caught or ignored) |
SIGTERM | 15 | Termination signal |
SIGSTOP | 17, 19, 23 | Stop the process (cannot be caught or ignored) |
Default Actions
When a signal is sent to a process, the process will take a default action unless instructed otherwise. These default actions are like the instinctive responses of our kitchen staff. For example:
- Terminate the process
- Ignore the signal
- Dump core
- Stop the process
- Continue a stopped process
Sending Signals
Now, let's learn how to send these signals. In Unix/Linux, we use the kill
command to send signals to processes. Don't let the name fool you - kill
doesn't always terminate processes; it's just a way to send signals.
Here's how you can use it:
kill -signal_name process_id
For example, to send a SIGTERM signal to process 1234:
kill -SIGTERM 1234
Or, using the signal number:
kill -15 1234
Trapping Signals
What if our kitchen staff could decide how to respond to Chef Unix's signals instead of always following the default reaction? That's what signal trapping allows in programming.
In shell scripts, we use the trap
command to catch signals and specify what to do when they're received. Here's the basic syntax:
trap command signal(s)
Let's look at an example:
#!/bin/bash
trap "echo Bonjour!" SIGINT SIGTERM
echo "It's a trap!"
while true
do
sleep 60
done
In this script, if it receives either SIGINT or SIGTERM, it will print "Bonjour!" instead of terminating. It's like telling our kitchen staff, "When the chef signals to stop, say 'Bonjour!' instead of actually stopping."
Cleaning Up Temporary Files
One common use of traps is to clean up temporary files before a script exits. Here's an example:
#!/bin/bash
# Create a temporary file
temp_file=$(mktemp)
# Set up a trap to remove the temporary file on exit
trap "rm -f $temp_file" EXIT
# Use the temporary file
echo "Hello, World!" > $temp_file
cat $temp_file
# The temporary file will be automatically removed when the script exits
This script creates a temporary file, writes to it, reads from it, and then automatically removes it when the script exits, thanks to the trap.
Ignoring Signals
Sometimes, you might want to ignore certain signals. In our kitchen analogy, this would be like telling a chef, "No matter how many times you signal for more salt, I'm not adding any more!"
Here's how you can ignore a signal:
trap "" SIGINT
This tells the script to do nothing when it receives a SIGINT signal.
Resetting Traps
What if you want to go back to the default behavior after trapping a signal? You can reset a trap like this:
trap - SIGINT
This removes the trap for SIGINT, reverting to the default behavior.
Here's a more complete example:
#!/bin/bash
# Initially, trap SIGINT
trap "echo You can't stop me!" SIGINT
echo "Try to stop me with Ctrl+C..."
sleep 10
# Now, reset the trap
trap - SIGINT
echo "Okay, now you can stop me with Ctrl+C..."
sleep 10
echo "If you see this, you didn't stop me!"
This script first traps SIGINT, then resets it after 10 seconds. It's like telling our kitchen staff, "Ignore the stop signal for 10 seconds, then go back to normal."
And there you have it, folks! We've journeyed through the land of Unix/Linux signals and traps. Remember, practice makes perfect. Try writing your own scripts, play around with different signals, and soon you'll be conducting your own orchestra of processes like a true maestro. Happy coding!
Credits: Image by storyset