This page looks best with JavaScript enabled

traps

 ·  🎃 kr0m

Traps are a way to intercept signals in Linux, so we can execute a specific action when receiving a particular signal. This allows us to write scripts with advanced functionalities and better error management.

To see the list of available signals, we run:

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 take as an example that when we press Ctrl+c, we want the command uname -a to be executed. Ctrl+c is the SIGINT(2) signal:

trap 'uname -a' 2

We press Ctrl+c and the desired command is executed:

^CLinux RX4 4.19.44-gentoo-kr0m-AMDGPU-YAMA-ACM-appArmor-KProbes-Docker #3 SMP PREEMPT Thu Jun 6 22:48:45 CEST 2019 x86_64 Intel(R) Core(TM) i3-4170 CPU @ 3.70GHz GenuineIntel GNU/Linux

Now let’s put a script that will create the file /tmp/yy when it receives the SIGUSR1(10) signal:

vi test.sh

#!/bin/bash
trap 'touch /tmp/yy' 10

while true; do
    sleep 1
done

We give it execution permissions:

chmod 700 test.sh

We run the script:

./test.sh

We check that the file does not exist:

ls -la /tmp/yy

ls: cannot access '/tmp/yy': No such file or directory

We locate the PID of the script:

ps aux|grep test.sh

kr0m      9663  0.0  0.0  12576  3192 pts/7    S+   22:50   0:00 /bin/bash ./test.sh

We send the SIGUSR1(10) signal:

kill -s 10 9663

We check that the file has been created:

ls -la /tmp/yy

-rw-r--r-- 1 kr0m kr0m 0 jun 19 22:51 /tmp/yy

Another very useful use is error management:

vi test.sh

#!/bin/bash
err_report() {
    echo "Error detected"
}

trap 'err_report' ERR
ls $1

This script will execute the err_report function when an error occurs.

When we pass an existing file as an argument, it does an ls of it:

./test.sh /tmp/yy

/tmp/yy

If we run it with a non-existent one, it executes the error function:

./test.sh /tmp/y

ls: cannot access '/tmp/y': No such file or directory
Error detected

It can also be useful for cleaning up temporary files in case the script fails.

If you liked the article, you can treat me to a RedBull here