Ejecute el comando o la función cuando SIGINT o SIGTERM se envían al script primario en sí, no los procesos secundarios


11

Digamos que tengo esto script.sh

#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

echo "Some other text"
#other commands here
sleep infinity

Quiero script.shejecutar la función exit_scriptsiempre que reciba SIGINTo SIGTERM Por ejemplo:

killall script.sh # it will send SIGTERM to my script

y quiero que mi script ejecute esto

exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

Traté de implementar esta característica usando trap

trap exit_script SIGINT SIGTERM

La persona que respondió mi pregunta demostró que estaba equivocado.
pero no funcionó porque trapparece reaccionar solo a las señales enviadas a los procesos secundarios / secundarios. Como principiante no pude descifrar trapla página de manual, así que probablemente me perdí la solución.

Supongo que eso es lo que hacen los programas "reales" como Chromium cuando los envías SIGTERM

Desde https://major.io/2010/03/18/sigterm-vs-sigkill/

La aplicación puede determinar qué quiere hacer una vez que se recibe un SIGTERM. Si bien la mayoría de las aplicaciones limpiarán sus recursos y se detendrán, algunas no.


2
en general, los juramentos se consideran inapropiados para un discurso respetuoso
cat

editar sugerencia aprobada ok, ok done, no es divertido Lo entiendo
bosa djo

no es que no se permita la diversión, es solo que se considera ofensivo
gato el

1
@cat He pensado en tu argumento y tienes razón, perdón por mi tontería
bosa djo

Respuestas:


15

trapreacciona al proceso de llamada se señala a sí mismo. Pero debe llamarlo antes de recibir la señal. Quiero decir, al comienzo de tu guión.

Además, si desea usar kill -- -$$, que también envía la señal a su script, debe borrar la trampa antes de ejecutar kill o finalizará con un ciclo infinito kill && trap .

Por ejemplo:

#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    trap - SIGINT SIGTERM # clear the trap
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

trap exit_script SIGINT SIGTERM

echo "Some other text"
#other commands here
sleep infinity

Como se explica en los comentarios, el problema es que el script recibe la señal pero está esperando que el programa de suspensión finalice antes de procesar la señal recibida. Por lo tanto, debe eliminar los procesos secundarios (el proceso de suspensión en este caso) para ejecutar la acción de captura. Puede hacerlo con algo como lo siguiente:

kill -- -$(pgrep script.sh)

O como se indica en los comentarios:

killall -g script.sh

1
Probablemente me estoy perdiendo algo porque no funciona, esto es lo que hago. script.sh &; killall script.sh pero no hace nada.
bosa djo

Ejecuto el script.sh &; # entonces hago mi negocio; killall script.sh y no mata script.sh
bosa djo

1
El problema probablemente es que el script recibe la señal pero está esperando que el programa de suspensión finalice antes de procesarlo. Intente ./script.sh & sleep 1 && kill -- -$(pgrep script.sh)enviar una señal de interrupción también a los procesos secundarios de su script.
zuazo

@zuazo Debería agregar esta información interesante e importante a su respuesta :)
cat

1
Bonito, bosa djo.
Agregué
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.