Pages

Sunday, June 30, 2019

Linux - Trapping Signals

It is a general practice to interrupt a running program by passing a signal to the program or some times there may be situations that you don’t want users of your script to interrupt or exit in between by passing signals. 

A signal is a message to a process from the kernel to notify that some condition has occurred. For example, When you press the “ctrl + c” while running a program we are basically sending a signal to that program to terminate. When a signal is issued to a process, the process is interrupted and signal handler is executed. If no signal handler is available, then the default signal handler is called instead. Just run the “man -k signal” command to see the list of signals available. 

Some of the common signal types are:
SIGINT: user sends an interrupt signal (Ctrl + C). this is sent when user press the ctrl +c .

SIGKILL - The SIGKILLsignal is used to cause immediate program termination. It cannot be handled or ignored, and is therefore always fatal. It is also not possible to block this signal.

SIGTERM : this is the most generic signal used to cause program termination. Unlike SIGKILL, this signal can be blocked, handled, and ignored. It is the normal way to politely ask a program to terminate.

SIGQUIT: user sends a quit signal (Ctrl + C)

Note - the SIGKILL and SIGSTOPsignals cannot be caught, blocked or ignored.

Handling a signal is crucial for programs since they need to perform some cleanup of resources like file deletion etc before the process getting shut completely. Bash provides a simple utility called trap by which we can customize a script behavior when the script receives a signal. This is very useful, for example, to make sure that the system is always in a consistent state

[root@ansible ~]# trap -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

Let's write a simple program to understand how we can trap signals,
[root@ansible ~]# cat traptest.sh 
#!/bin/bash
#
# A simple script to demonstrate how trap works
#
set -e
set -u
set -o pipefail

trap 'echo "  signal caught, cleaning..."; rm -irf /tmp/hello' SIGINT SIGTERM

echo "Going to Sleep..."

while true
do 
  sleep 10000
done

In the above script, we used trap to catch the SIGINT and SIGTERM signals. The program goes to an infinite sleep loop and when i press Ctrl + C, the program terminals but it also executes the command that we defined in the trap condition.
[root@ansible ~]# sh traptest.sh 
Going to Sleep...
^C  signal caught, cleaning...

In this case the command are actually two, the first is the echo and second is the removal of the files in /tmp location. Instead of specifying command this way we can define a function and call it with whatever actions we want to do

Hope this short introduction helps in understanding signals and how they can be trapped in bash.

No comments :

Post a Comment