2012-08-02 17 views
5

Tengo un simple script Perl que simplemente imprime una línea de texto a stdout. Lo que quiero lograr es que mientras este script se ejecuta, si yo (u otra persona) emite una señal para que pare el proceso, quiero que atrape esa señal y salga limpiamente. El código que tengo tiene el siguienteSeñales de trapping limpiamente en Perl

#!/usr/bin/perl -w 

$| = 1; 
use sigtrap 'handler' => \&sigtrap, 'HUP', 'INT','ABRT','QUIT','TERM'; 
while(1){ 
print "Working...\n"; 
sleep(2); 
} 
sub sigtrap(){ 
print "Caught a signal\n"; 
exit(1); 
} 

Aunque esto funciona bien cuando en realidad pulse Ctrl-C desde la línea de comandos, si emitir una

kill -9 <pid> 

Sólo muere. ¿Cómo hago para ejecutar algo antes de salir? Mi idea general es utilizar este marco para capturar cuando este script muere en un servidor debido a un reinicio del servidor por mantenimiento o falla.

Gracias de antemano

Respuesta

11

La señal # 9 (SIGKILL) no puede ser atrapada. Así es como está diseñado Unix.

Pero el sistema no envía esa señal cuando se apaga para mantenimiento. Al menos si tu daemon se comporta correctamente. Normalmente enviará la señal TERM (o más exactamente lo que hace tu script de manejo de daemon en /etc/init.d). Solo los procesos que no se cierran correctamente después de un tiempo de espera recibirán SIGKILL.

Por lo tanto, su objetivo debe ser manejar correctamente la señal TERM y escribir la secuencia de comandos contenedora en /etc/init.d que se ejecutará cuando el sistema cambie de nivel de ejecución.

Actualización: Puede utilizar el módulo Daemon::Control para la secuencia de comandos de inicio.

4

va a enviar dos señales muy diferentes para su proceso. Al presionar Ctrl-C en la consola, generalmente se envía al proceso una señal TERM INT que, a juzgar por su código, es interceptada y atendida. kill -9, sin embargo, envía la señal número 9 explícitamente, que se llama KILL. Esta es una de las señales cuyo servicio no se puede redefinir y la entrega de esta señal siempre finaliza inmediatamente el proceso, que es realizado por el núcleo mismo.

+3

Al presionar 'Ctrl-C' se envía la señal' INT' ** no ** 'TERM', aunque la acción predeterminada es la misma para un proceso interactivo. Cualquiera de las señales puede ser capturada, a diferencia de 'kill -9'. Un 'kill -l' listará nombres de señal. Un 'stty -a' mostrará la asignación predeterminada de' INT' a 'Ctrl-C'. – JRFerguson

+0

¡Ay! Gracias por aclarar eso y disculpas por desinformar. –

3

Por lo que yo sé, no puede capturar kill -9. Pruebe kill <pid> en su lugar.

+2

Esto entregará un 'TERM ', que es efectivamente equivalente a presionar' Ctrl-C' en la consola. –

+0

@DanielKamilKozar Gracias, es bueno saberlo. –

+3

@DanielKamilKozar: Al presionar 'Ctrl-C' se envía la señal' INT' ** no ** 'TERM', aunque la acción predeterminada es la misma para un proceso interactivo. Cualquiera de las señales puede ser capturada, a diferencia de 'kill -9'. Un 'kill -l' listará nombres de señal. Un 'stty -a' mostrará la asignación predeterminada de' INT' a 'Ctrl-C'. – JRFerguson

Cuestiones relacionadas