Cómo modificar el comportamiento de los scripts en las señales usando trampas bash

Cómo modificar el comportamiento de los scripts en las señales usando trampas bash

Objetivo

El objetivo de este tutorial es describir cómo usar el shell bash trampa construido para hacer que nuestros scripts puedan realizar ciertas acciones cuando reciben una señal o en otras situaciones específicas.

Requisitos

  • ningún requerimiento especial

Dificultad

FÁCIL

Convenciones

  • # - requiere que los comandos de Linux dados se ejecuten con privilegios raíz
    directamente como usuario raíz o mediante el uso de sudo dominio
  • ps - Requiere que los comandos de Linux dados se ejecuten como un usuario regular no privilegiado

Introducción

Al escribir scripts que están destinados a ejecutarse durante un tiempo considerable, es muy importante aumentar su robustez al hacer que puedan reaccionar ante las señales del sistema, ejecutando acciones específicas cuando se reciben algunos de ellos. Podemos lograr esta tarea usando la fiesta trampa incorporado.

Que son trampas?

Una trampa es un mecanismo bash que permite personalizar un comportamiento de script cuando recibe una señal. Esto es muy útil, por ejemplo, para asegurarse de que el sistema siempre esté en un estado consistente. Imagine que ha escrito un script que durante su tiempo de ejecución necesita crear algunos directorios: si, por ejemplo, se le enviará una señal Sigint, el script se interrumpirá, dejando atrás los directorios que creó. Usando trampas podemos manejar situaciones como esta.

Sintaxis de trampa

La sintaxis de la trampa es muy simple y fácil de entender: primero debemos llamar a la trampa construida, seguida de las acciones para ser ejecutadas, luego debemos especificar la señal (s) a la que queremos reaccionar:

trampa [-lp] [[arg] sigpec]

Veamos lo que es posible trampa Las opciones son para.

Cuando se usa con el -l Bandera, el comando trampa solo mostrará una lista de señales asociadas con sus números. Es la misma salida que puede obtener ejecutar el matar -l dominio:

$ 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) 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 -1 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 

Es realmente importante especificar que es posible reaccionar solo a las señales que permite que el script responda: el Sigkill y Signo Las señales no pueden ser atrapadas, bloqueadas o ignoradas.

Además de las señales, las trampas también pueden reaccionar a algunos pseudo-firma como salir, err o depurar, pero los veremos en detalle más tarde. Por ahora solo recuerde que una señal puede especificarse por su número o por su nombre, incluso sin el Signo prefijo.

Acerca de -pag opción ahora. Esta opción solo tiene sentido cuando no se proporciona un comando (de lo contrario producirá un error). Cuando la trampa se usa con él, se mostrará una lista de las trampas establecidas anteriormente. Si se especifica el nombre o número de la señal, solo se mostrará la trampa establecida para esa señal específica, de lo contrario no se realizarán distinciones y se mostrarán todas las trampas:

$ TRAP 'ECHO "Sigint atrapado!"'Sigint

Establecemos una trampa para atrapar la señal Sigint: solo mostrará el mensaje "Sigint atrapado" en la pantalla cuando la señal sea recibida por el shell. Si ahora usamos trampa con la opción -p, mostrará la trampa que acabamos de definir:

$ trap -p trampa -'echo "Sigint atrapado!"'Sigint 

Por cierto, la trampa ahora es "activa", por lo que si enviamos una señal Sigint, ya sea usando el comando Kill, o con el acceso directo CTRL-C, el comando asociado en la trampa se ejecutará (^C se imprime porque se imprime porque de la combinación clave):

^Csigint atrapado!

Trampa en acción

Ahora escribiremos un script simple para mostrar trampa en acción, aquí está:

#!/usr/bin/env Bash # # Un script simple para demostrar cómo funciona la trampa # set -e set -u set -o pipefail trampa 'echo "señal capturada, limpieza ..."; rm -i linux_tarball.alquitrán.XZ 'Sigint Sigterter Echo "Descarga de Tarball ..." wget -o linux_tarball.alquitrán.xz https: // cdn.núcleo.org/pub/linux/kernel/v4.x/Linux-4.13.5.alquitrán.xz &> /dev /null
Copiar

El script anterior solo trata de descargar el último tarball de kernel de Linux en el directorio desde lo que se lanza usando wget. Durante la tarea, si se reciben las señales Sigint o Sigterter (observe cómo puede especificar más de una señal en la misma línea), se eliminará el archivo parcialmente descargado.

En este caso, el comando es en realidad dos: el primero es el eco que imprime el mensaje en la pantalla, y el segundo es el RM Comando (le proporcionamos la opción -i, por lo que solicitará la confirmación del usuario antes de eliminar), y están separados por un punto y coma. En lugar de especificar comandos de esta manera, también puede llamar a las funciones: esto le daría más reutilización. Observe que si no proporciona ningún comando, la (s) señal (s) se ignorará!

Esta es la salida del script anterior cuando recibe una señal Sigint:

ps ./fetchlinux.SH Descargar Tarball ... ^Csignal atrapado, limpieza ... RM: Eliminar archivo regular 'Linux_tarball.alquitrán.xz '? 

Una cosa muy importante para recordar es que cuando un script termina por una señal, como arriba, su estado existente será el resultado de 128 + el número de señal. Como puede ver, el script anterior, siendo terminado por un sigint, tiene un estado de salida de 130:

$ Echo $? 130 

Por último, puede deshabilitar una trampa simplemente llamando trampa Seguido por el - signo, seguido del nombre o número de señal (s):

TRAP - SIGINT SIGTERM

Las señales recuperarán el valor que tenían en la entrada al shell.

Pseudofectales

Como ya se mencionó anteriormente, la trampa se puede configurar no solo para las señales que permiten que el script responda, sino también a lo que podemos llamar "pseudo-señales". No son técnicamente señales, sino que corresponden a ciertas situaciones que se pueden especificar:

SALIDA

Cuando SALIDA se especifica en una trampa, el comando de la trampa se ejecutará en la salida del shell.

ERRAR

Esto hará que el argumento de la trampa se ejecute cuando un comando devuelva un estado de salida no cero, con algunas excepciones (lo mismo de la opción de shell errexit): el comando no debe ser parte de un mientras o hasta bucle; no debe ser parte de un si construir, ni parte de un && o || lista, y su valor no debe invertirse utilizando el ! operador.

DEPURAR

Esto hará que el argumento de la trampa se ejecute antes de cada simple comando,
para, caso o seleccionar comandos, y antes del primer comando en las funciones de shell.

DEVOLVER

El argumento de la trampa se ejecuta después de una función o un script obteniendo usando fuente o el . dominio.

Tutoriales de Linux relacionados:

  • Cómo propagar una señal a los procesos infantiles de una fiesta ..
  • Cómo realizar operaciones de administración con Ansible ..
  • Cómo instalar la señal en Linux
  • Cosas para instalar en Ubuntu 20.04
  • Cómo usar el comando killall en Linux
  • Cómo salir del guión Bash
  • Cosas que hacer después de instalar Ubuntu 20.04 fossa focal Linux
  • Comandos de Linux: los 20 comandos más importantes que necesitas ..
  • Virtualbox Aumento del tamaño del disco en Linux
  • Guía de solución de problemas GNU/Linux General para principiantes