Understanding Linux Signals
1. Viewing Available Signals
| Signal | Number | Description | Default Action |
|---|---|---|---|
| SIGHUP | 1 |
Terminal hangup | Terminate |
| SIGINT | 2 |
Interrupt from keyboard | Terminate |
| SIGKILL | 9 |
Kill signal (cannot be caught or ignored) | Kill |
| SIGTERM | 15 |
Termination signal (graceful shutdown) | Terminate |
| SIGSTOP | 17 |
Stop signal (cannot be caught or ignored) | Stop |
| SIGTSTP | 20 |
Stop signal from terminal (like Ctrl+Z) | Stop |
| SIGUSR1 | 10 |
User-defined signal 1 | Terminate |
| SIGUSR2 | 12 |
User-defined signal 2 | Terminate |
Example: List all available signals using kill -l
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 ...
2. Sending Signals with kill
| Signal | Name | Description | Default Action |
|---|---|---|---|
| 1 | SIGHUP |
Hang up detected on controlling terminal or death of controlling process | Terminate |
| 2 | SIGINT |
Interrupt from keyboard (Ctrl+C) | Terminate |
| 3 | SIGQUIT |
Quit from keyboard (Ctrl+\) | Core dump |
| 9 | SIGKILL |
Kill signal (cannot be caught or ignored) | Terminate |
| 15 | SIGTERM |
Termination signal (can be caught or ignored) | Terminate |
| 18 | SIGCONT |
Continue process if stopped | Continue |
| 19 | SIGSTOP |
Stop signal (cannot be caught or ignored) | Stop |
Note: The
kill command sends signals to processes. By default, it sends SIGTERM (signal 15), which allows the process to shut down gracefully. Use kill -9 or SIGKILL to forcefully terminate a process.
3. Understanding Common Signals
| Signal | Number | Description | Default Action |
|---|---|---|---|
| SIGHUP | 1 |
Terminal hangup or configuration reload | Terminate |
| SIGINT | 2 |
Interrupt from keyboard (Ctrl+C) | Terminate |
| SIGKILL | 9 |
Force kill signal (cannot be caught or ignored) | Kill |
| SIGTERM | 15 |
Graceful termination request | Terminate |
| SIGSTOP | 17 |
Stop signal (cannot be caught or ignored) | Stop |
| SIGTSTP | 20 |
Terminal stop signal (Ctrl+Z) | Stop |
Example: Sending a Signal to a Process
# Send SIGTERM to process with PID 1234
kill -TERM 1234
# Send SIGHUP to reload configuration
kill -HUP <pid>
# Force kill a process
kill -KILL 1234
Note: The
SIGKILL and SIGSTOP signals cannot be caught, blocked, or ignored by any process.
4. Understanding SIGINT and SIGQUIT
| Signal | Number | Description | Default Action |
|---|---|---|---|
| SIGINT | 2 |
Interrupt from keyboard (Ctrl+C) | Kill |
| SIGQUIT | 3 |
Quit from keyboard (Ctrl+\) | Kill + Core dump |
Example: Handling SIGINT in a Bash Script
#!/bin/bash
trap 'echo "Received SIGINT, exiting..."' INT
while true; do
echo "Running..."
sleep 1
done
Note: SIGINT is typically sent when a user presses Ctrl+C, while SIGQUIT is sent with Ctrl+\ and usually results in a core dump.
5. Handling SIGHUP for Daemons
| Signal | Value | Description | Default Action |
|---|---|---|---|
| SIGHUP | 1 |
Hangup detected on controlling terminal or death of controlling process | Terminate |
Example: Reopening Log Files on SIGHUP
const fs = require('fs');
let logFile;
function reopenLog() {
if (logFile) {
logFile.close();
}
logFile = fs.createWriteStream('/var/log/myapp.log', { flags: 'a' });
}
process.on('SIGHUP', () => {
console.log('Received SIGHUP, reopening log file');
reopenLog();
});
// Simulate daemon running
setInterval(() => {
console.log('Daemon working...');
}, 5000);
Note: Daemons often handle SIGHUP to reload configuration or reopen log files without restarting.
6. Using SIGUSR1 and SIGUSR2
| Signal | Number | Description | Default Action |
|---|---|---|---|
| SIGUSR1 | 10 |
User-defined signal 1 | Kill |
| SIGUSR2 | 12 |
User-defined signal 2 | Kill |
Example: Handling SIGUSR1 in a Bash Script
trap 'echo "Received SIGUSR1"' USR1
echo "PID is $"
sleep 30
Note: SIGUSR1 and SIGUSR2 are commonly used for custom application signaling. They are not reserved by the system and can be used for any purpose defined by the application.
7. Understanding SIGSTOP and SIGCONT
| Signal | Value | Description | Default Action |
|---|---|---|---|
| SIGSTOP | 19 |
Stops the process immediately. Cannot be caught, blocked, or ignored. | STOP |
| SIGCONT | 18 |
Continues a stopped process. Can be caught or blocked. | CONTINUE |
Note: SIGSTOP cannot be caught, blocked, or ignored by any process. It is handled entirely by the kernel.
Warning: SIGCONT will only resume a process if it was previously stopped by SIGSTOP.
Key Points
- SIGSTOP is a non-maskable signal that halts the process immediately.
- SIGCONT is used to resume a stopped process.
- These signals are essential for job control in shells and process management.
8. Trapping Signals in Scripts
| Signal | Description | Default Action | Trap Command |
|---|---|---|---|
| SIGINT | Interrupt from keyboard (Ctrl+C) | Terminate | trap 'echo "Caught SIGINT"' INT |
| SIGTERM | Termination signal | Terminate | trap 'cleanup' TERM |
| SIGUSR1 | User-defined signal 1 | Terminate | trap 'handle_usr1' USR1 |
Example: Basic Signal Trapping
#!/bin/bash
cleanup() {
echo "Cleaning up..."
exit 0
}
trap cleanup TERM INT
echo "PID is $"
while true; do
sleep 1
done
Example: Handling SIGUSR1
#!/bin/bash
handle_usr1() {
echo "Received SIGUSR1"
}
trap handle_usr1 USR1
echo "PID is $, waiting for SIGUSR1"
sleep 30
Note: The
trap command can be used to define custom actions for signals. It is particularly useful in long-running scripts where graceful shutdown or handling of external events is required.
9. Ignoring Signals
| Signal | Description | Default Action | Can Be Ignored? |
|---|---|---|---|
| SIGPIPE | Write to a pipe with no readers | Terminate process | YES |
| SIGALRM | Alarm clock signal | Terminate process | YES |
| SIGUSR1 | User-defined signal 1 | Terminate process | YES |
| SIGUSR2 | User-defined signal 2 | Terminate process | YES |
Example: Ignoring SIGALRM in C
#include <signal.h>
#include <stdio.h>
int main() {
signal(SIGALRM, SIG_IGN);
printf("SIGALRM is now ignored\n");
return 0;
}
Note: While signals like SIGPIPE and SIGALRM can be ignored, some system signals such as SIGKILL and SIGSTOP cannot be caught or ignored.
10. Understanding Signal Propagation
| Signal | Description | Default Action | Propagation |
|---|---|---|---|
| SIGTERM | Termination signal, graceful shutdown | Terminate process | Propagates to child processes |
| SIGKILL | Force kill signal, cannot be caught or ignored | Kill process | Does not propagate to children |
| SIGINT | Interrupt from keyboard (Ctrl+C) | Terminate process | Propagates to child processes |
| SIGCHLD | Child process terminated or stopped | Ignore (default) | Propagates to parent process |
| SIGHUP | Hangup signal, often used for config reload | Terminate process | Can be handled by parent processes |
Example: Signal propagation in a parent-child process
# Start a parent process that spawns a child
parent_pid=$('sleep 30 &')
child_pid=$('echo $')
# Send SIGTERM to parent
kill -TERM $parent_pid
# Child process will receive SIGCHLD when parent exits
Note: Signal propagation behavior can vary depending on how the process handles signals and whether it's a shell script or compiled binary.