Linux Signals and Trap

When we design a large, complicated script, it is important to consider what happens if the user logs off or shuts down the computer while the script is running. When such an event occurs, a signal will be sent to all affected processes. In turn, the programs representing those processes can perform actions to ensure a proper and orderly termination of the program.

Signals are software interrupts sent to a program to indicate that an important event has occurred. The events can vary from user requests to illegal memory access errors.

To list the signal supported on Linux system:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## list all signal and corresponding number
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 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

## output signal name or number
kill -l 9
kill -l usr1

Kill process in command line:

1
2
3
kill -9 <pid>
kill -s 9 <pid>
kill -SIGKILL <pid>

Some commonly use signals:

  • SIGHUP: Many daemons will reload their configuration instead of exiting when receiving this signal, see here for explanation
  • SIGINT: Issued if the user sends an interrupt signal (Ctrl + C), usually will terminate a program
  • SIGQUIT: Issued if the user sends a quit signal (Ctrl + D), it will dump core
  • SIGKILL: If a process gets this signal it must quit immediately and will not perform any clean-up operations, this one cannot be ignored or trapped! (这里提一下,force kill会导致程序,比如Python中finally clauses 和 exit handler 无法工作)
  • SIGTERM: Software termination signal (sent by kill by default)
  • SIGSTOP: Stop process (Ctrl + Z), for example, stop fg mode, see SIGCONT below
  • SIGCONT: Continue if stopped, for example, after stop fg mode by (Ctrl + Z), switch to bg will trigger this signal
  • SIGSTP: Stop typed at terminal
  • SIGCHLD: When a child process stops or terminates, SIGCHLD is sent to the parent process. (这个可以用来trap回收subprocess的资源)

For signal default behavior, see man 7 signal!!

Note that process cannot define handler for SIGKILL and SIGSTOP, the default behavior is in use.

Note that non-init process cannot ignore SIGKILL and SIGSTOP, they are used for root user and kernel for process management. But, remember, process in D state is uninterruptable even with SIGKILL and SIGSTOP.

Note that you cannot kill init process(PID 1) by kill -9 1, this is the exception as described in man 2 kill: “The only signals that can be sent to process ID 1, the init process, are those for which init has explicitly installed signal handlers. This is done to assure the system is not brought down accidentally.” See here for hint.

About trap the signals in script, for example:

1
2
3
4
5
6
7
8
9
## Set a Trap for Signals for graceful shutdown
declare -a SIGNALS_TRAPPED=(INT TERM)
shudown_hook() {
...
(/opt/servers/stop.sh)
echo "Shutdown and Cleanup Successful..."
exit 0
}
trap 'shudown_hook' " ${SIGNALS_TRAPPED[@]}"

The general format is trap command signals, for example:

1
trap "rm -rf /tmp/peek.txt; exit 0" 1 2

To ignore signals, for example:

1
trap "" 2 3 15

If main process ignore a signal, all subshells also ignore that signal. However, if you specify an action to be taken on the receipt of a signal, all subshells will still take the default action on receipt of that signal.

Reset the traps to default:

1
trap 2 3 15
0%