Esta pagina se ve mejor con JavaScript habilitado

traps

 ·  🎃 kr0m

Las traps son un modo de interceptar señales en Linux de este modo podemos ejecutar una acción determinada al recibir una señal en concreto. Esto nos permitirá escribir scripts con funcionalidades avanzadas y una mejor gestión de errores.

Para ver la lista de señales disponibles ejecutamos:

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    

Pongamos como ejemplo que cuando se presione Ctrl+c querremos que se ejecute el comando uname -a, Ctrl+c es la señal SIGINT(2):

trap 'uname -a' 2

Presionamos Ctrl+c y efectivamente se ejecuta el comando deseado:

^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

Ahora pongamos un script el cual creará el fichero /tmp/yy cuando reciba la señal SIGUSR1(10):

vi test.sh

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

while true; do
    sleep 1
done

Le damos permisos de ejecución:

chmod 700 test.sh

Ejecutamos el script:

./test.sh

Comprobamos que el fichero no existe:

ls -la /tmp/yy

ls: no se puede acceder a '/tmp/yy': No existe el fichero o el directorio

Localizamos el PID del 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

Le enviamos la señal SIGUSR1(10):

kill -s 10 9663

Comprobamos que se ha creado el fichero:

ls -la /tmp/yy

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

Otro uso muy útil es la gestión de errores:

vi test.sh

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

trap 'err_report' ERR
ls $1

Este script ejecutará la función err_report cuando se produzca un error.

Cuando le pasamos como argumento un fichero existente, hace un ls de este:

./test.sh /tmp/yy

/tmp/yy

Si lo ejecutamos con uno inexistente, ejecuta la función de error:

./test.sh /tmp/y

ls: no se puede acceder a '/tmp/y': No existe el fichero o el directorio
Error detected

También puede resultarnos de utilidad para hacer limpieza de ficheros temporales en caso de que el script falle.

Si te ha gustado el artículo puedes invitarme a un RedBull aquí