tutorial traduccion tag script lenguaje example español linux bash shell

linux - tag - bash traduccion



Identificando el nombre de la señal recibida en Bash (4)

(Si solo tiene el número de una señal y desea el nombre, kill -l $SIGNAL_NUM imprime el nombre de una señal; puede evitarlo usando los nombres de las señales en lugar de los números de su llamada para trap como se muestra a continuación).

Esta respuesta dice que la única manera de identificar qué señal atrapó en bash es escribir un envoltorio separado para cada señal diferente que desea atrapar. Otra respuesta a esa misma pregunta proporciona una función de envoltorio para que lo haga por usted:

Código:

#!/bin/bash trap_with_arg() { func="$1" ; shift for sig ; do trap "$func $sig" "$sig" done } func_trap() { echo Trapped: $1 } trap_with_arg func_trap INT TERM EXIT read # Wait so the script doesn''t exit.

Si ejecuto eso, entonces puedo enviar señales al proceso y obtengo una salida como

Trapped: INT Trapped: TERM Trapped: EXIT

Cuando se recibe una señal, puedo ejecutar algunos comandos utilizando la trap . Ejemplo:

trap ''echo hello world'' 1 2

Si se recibe alguna de las señales especificadas, se muestra "hola mundo".

Pero, ¿cómo puedo imprimir / identificar el nombre de la señal recibida?


Dentro de la trampa (cuando se dispara a través de una señal), el $? la variable se establece inicialmente en el número de señal más 128, por lo que puede asignar el número de señal a una variable haciendo que la primera declaración de la acción de captura a algo como

sig=$(($? - 128))

A continuación, puede obtener el nombre de la señal utilizando el comando kill

kill -l $sig


Refiriéndose a los $? solución anterior: $? reflejará el código de salida del último comando ejecutado. Considera esto:

#!/bin/bash trap ''echo CODE: $?; exit 1'' 1 2 3 15 sleep 3600

Si ejecuta esto y presiona Ctrl-C , se imprimirá el CODE: 130 . Eso es porque el ejecutable de sleep fue interrumpido por el SIGINT y salió con ese código.

Compara eso con:

#!/bin/bash trap ''echo CODE: $?; exit 1'' 1 2 3 15 read X

Si ejecuta esto y presiona Ctrl-C , se imprimirá el CODE: 0 , presumiblemente porque el comando de read es un código integrado y las reglas del código de salida son diferentes (lo mismo sucede si usted interrumpiera while : ; do : ; done ).

Entonces, $? solo le informa sobre la señal si interrumpió un comando externo, y si ese programa en particular no ha captado la señal y ha salido con su propio código de salida. El punto en el caso es el script de bash anterior: al recibir un SIGINT, saldrá con el código 1 , no 130 .


Una forma sencilla de hacer esto:

_handler() { signal=$1 echo signal was $signal } trap ''_handler SIGTERM'' SIGTERM trap ''_handler SIGINT'' SIGINT