Haz tus scripts de bash más robustos con traps

Ícono Terminal

Imagina que tienes un script de bash que se ejecute cada cierto tiempo y que en algún momento falle o que ese mismo script se ejecute dos veces simultáneamente. Estas dos situaciones son bastante incómodas ya que requieren de la intervención humana para ser corregidas, o en ciertos momentos no pueden ser atendidas dejando la tarea en un estado inconsistente.

trap es una manera sencilla y efectiva de controlar la salida de scripts de bash. Volvamos a la misma situación inicial, si el script es detenido manualmente, por ejemplo con ctrl-c, se interrumpe devolviendo la señal de salida INT y si se termina con kill entonces la salida sería TERM. Todos los códigos de salida posibles se pueden ver con kill -l, sin embargo los más utilizados son precisamente INT, TERM y EXIT. Si el script consiste, por ejemplo, en la sincronización de archivos con rsync lo más sensato es apoyarse en un archivo lock que no permita que el script se ejecute simultáneamente:

En español plano, el script anterior comprueba si existe el archivo /var/run/rsync.lock y si este no existe, lo crea y posteriormente ejecuta el comando correspondiente; por último elimina el archivo lock al terminar la ejecución de los comandos. Si existe el archivo, el script simplemente envía un mensaje al usuario indicándole que ya el comando se está ejecutando.

Sin embargo, pudiera ocurrir, por una situación inesperada, que el archivo lock no se elimine pudiendo dejar efectos indeseados. La solución es bien sencilla:

La particularidad de esta solución es que el comando está encerrado en un trap, de modo que cuando se recibe una señal INT, TERM o EXITel script se detiene y elimina el archivo lock.

Vale la pena decir que pudiera darse una situación de competencia entre el tiempo en que se verifica el archivo lock y el tiempo en que este se crea. Una posible solución sería usar una redirección y el modo noclobber de bash el cual no redirige a un archivo existente:

La particularidad de este último es que se usa como ya se había dicho, el modo noclobber y que el archivo lock contiene el PID del proceso que se ejecuta.

También vale la pena mencionar que existen otras soluciones como flock o solo, sin embargo en esta entrada quise compartir las soluciones con recursos propios de bash.

(Visited 69 times, 1 visits today)

Sé el primero en comentar

Dejar una contestacion

Tu dirección de correo electrónico no será publicada.


*