una todos terminar señales señal que procesos proceso los hace enviar entre detener cont comandos comando administracion bash signals job-control sigterm

bash - todos - ¿En qué orden debo enviar señales a procesos de cierre graciosamente?



señales entre procesos linux (7)

Con toda la discusión aquí, no se ha ofrecido ningún código. Aquí está mi opinión:

#!/bin/bash $pid = 1234 echo "Killing process $pid..." kill $pid waitAttempts=30 for i in $(seq 1 $waitAttempts) do echo "Checking if process is alive (attempt #$i / $waitAttempts)..." sleep 1 if ps -p $pid > /dev/null then echo "Process $pid is still running" else echo "Process $pid has shut down successfully" break fi done if ps -p $pid > /dev/null then echo "Could not shut down process $pid gracefully - killing it forcibly..." kill -SIGKILL $pid fi

En un comment sobre esta respuesta a otra question , el comentarista dice:

¡no use kill -9 a menos que sea absolutamente necesario! SIGKILL no puede quedar atrapado, por lo que el programa inactivo no puede ejecutar ninguna rutina de apagado, por ejemplo, borrar archivos temporales. Primero intente HUP (1), luego INT (2), luego QUIT (3)

Estoy de acuerdo en principio con SIGKILL , pero el resto es nuevo para mí. Dado que la señal predeterminada enviada por kill es SIGTERM , esperaría que sea la señal más comúnmente esperada para el apagado correcto de un proceso arbitrario. Además, he visto que SIGHUP usa por motivos no SIGHUP , como decirle a un daemon "volver a leer su archivo de configuración". Y me parece que SIGINT (la misma interrupción que normalmente obtendrías con Ctrl-C, ¿no?) No es tan ampliamente compatible como debería ser, o termina bastante desvergonzadamente.

Dado que SIGKILL es el último recurso, ¿qué señales y en qué orden debe enviar a un proceso arbitrario para cerrarlo lo más elegantemente posible?

Por favor corrobore sus respuestas con hechos que lo respalden (más allá de las preferencias u opiniones personales) o referencias, si puede.

Nota: Estoy particularmente interesado en las mejores prácticas que incluyen la consideración de bash / Cygwin.

Editar: Hasta ahora, nadie parece mencionar INT o QUIT, y hay una mención limitada de HUP. ¿Hay alguna razón para incluir estos en un proceso ordenado de asesinato?


HUP me suena como basura. Lo enviaría para que un daemon vuelva a leer su configuración.

SIGTERM puede ser interceptado; tus demonios pueden tener código de limpieza para ejecutar cuando recibe esa señal. No puedes hacer eso para SIGKILL. Por lo tanto, con SIGKILL no le estás dando al autor del daemon ninguna opción.

Más sobre eso en Wikipedia


Normalmente enviaría SIGTERM , el valor predeterminado de kill. Es el predeterminado por una razón. Solo si un programa no se apaga en un tiempo razonable debe recurrir a SIGKILL . Pero tenga en cuenta que con SIGKILL el programa no tiene la posibilidad de limpiar las cosas y los datos podrían estar dañados.

En cuanto a SIGHUP , HUP significa "colgar" e históricamente significaba que el módem se desconectó. Es esencialmente equivalente a SIGTERM . La razón por la que los daemons a veces usan SIGHUP para reiniciar o volver a cargar la configuración es que los daemons se separan de cualquier terminal de control ya que un daemon no los necesita y por lo tanto nunca recibirían SIGHUP , por lo que la señal se consideró "liberada" para uso general. ¡No todos los daemons usan esto para recargar! ¡La acción predeterminada para SIGHUP es terminar y muchos daemons se comportan de esa manera! Entonces no puedes ir ciegamente enviando SIGHUP s a daemons y esperando que ellos sobrevivan.

Editar: SIGINT probablemente no sea apropiado para finalizar un proceso, ya que normalmente está vinculado a ^C o lo que sea que la configuración del terminal sea interrumpir un programa. Muchos programas capturan esto para sus propios fines, por lo que es lo suficientemente común como para que no funcione. SIGQUIT generalmente tiene el valor predeterminado de crear un volcado de núcleo y, a menos que desee que los archivos principales estén por ahí, tampoco es un buen candidato.

Resumen: si envía SIGTERM y el programa no muere dentro de su plazo, envíelo SIGKILL .


SIGTERM realidad significa enviar un mensaje a la aplicación: " serías tan amable y te suicidarías ". La aplicación puede atraparlo y manejarlo para ejecutar el código de limpieza y apagado.

SIGKILL no puede ser atrapado por la aplicación. El sistema operativo mata la aplicación sin ninguna posibilidad de limpieza.

Es típico enviar SIGTERM primero, dormir un poco, luego enviar SIGKILL .


Respuesta corta : envíe SIGTERM , 30 segundos después, SIGKILL . Es decir, envíe SIGTERM , espere un poco (puede variar de un programa a otro, puede conocer mejor su sistema, pero de 5 a 30 segundos es suficiente.) Al apagar una máquina, es posible que la vea esperar automáticamente hasta 1''30 s. . ¿Por qué la prisa, después de todo?), Luego envíe SIGKILL .

Respuesta razonable : SIGTERM , SIGINT , SIGKILL Esto es más que suficiente. El proceso probablemente terminará antes de SIGKILL .

Respuesta larga : SIGTERM , SIGINT , SIGQUIT , SIGABRT , SIGKILL

Esto es innecesario, pero al menos no está engañando el proceso con respecto a su mensaje. Todas estas señales significan que desea que el proceso detenga lo que está haciendo y salga.

No importa qué respuesta elijas de esta explicación, ¡tenlo en cuenta!

Si envía una señal que significa algo más, el proceso puede manejarlo de maneras muy diferentes (por un lado). Por otro lado, si el proceso no maneja la señal, no importa lo que envíe después de todo, el proceso se cerrará de todos modos (cuando la acción predeterminada es terminar, por supuesto).

Entonces, debes pensar como tú mismo como programador. ¿ SIGHUP un controlador de función para, digamos, SIGHUP para salir de un programa que se conecta con algo, o lo haría un bucle para intentar conectarse de nuevo? Esa es la pregunta principal aquí! Es por eso que es importante enviar señales que signifiquen lo que pretendes.

Casi estúpida respuesta larga :

La tabla siguiente contiene las señales relevantes y las acciones predeterminadas en caso de que el programa no las maneje.

Los ordené en el orden que sugiero usar (por cierto, sugiero que utilicen la respuesta razonable , no esta aquí), si realmente necesitan probarlos todos (sería divertido decir que la tabla está ordenada en términos de la destrucción que pueden causar, pero eso no es completamente cierto).

Las señales con un asterisco (*) NO son recomendables. Lo importante de esto es que nunca se sabe lo que está programado para hacer. ¡Especialmente SIGUSR ! Puede iniciar apocalipse (¡es una señal gratuita para que un programador haga lo que quiera!). Pero, si no se maneja O, en el caso improbable de que se resuelva, el programa finalizará.

En la tabla, las señales con opciones predeterminadas para terminar y generar un volcado de núcleo se dejan al final, justo antes de SIGKILL .

Signal Value Action Comment ---------------------------------------------------------------------- SIGTERM 15 Term Termination signal SIGINT 2 Term Famous CONTROL+C interrupt from keyboard SIGHUP 1 Term Disconnected terminal or parent died SIGPIPE 13 Term Broken pipe SIGALRM(*) 14 Term Timer signal from alarm SIGUSR2(*) 12 Term User-defined signal 2 SIGUSR1(*) 10 Term User-defined signal 1 SIGQUIT 3 Core CONTRL+/ or quit from keyboard SIGABRT 6 Core Abort signal from abort(3) SIGSEGV 11 Core Invalid memory reference SIGILL 4 Core Illegal Instruction SIGFPE 8 Core Floating point exception SIGKILL 9 Term Kill signal

Entonces sugeriría para esta respuesta larga casi estúpida : SIGTERM , SIGINT , SIGHUP , SIGPIPE , SIGQUIT , SIGABRT , SIGKILL

Y finalmente, el

Definitivamente estúpida larga y larga respuesta :

No intentes esto en casa.

SIGTERM , SIGINT , SIGHUP , SIGPIPE , SIGALRM , SIGUSR2 , SIGUSR1 , SIGQUIT , SIGABRT , SIGSEGV , SIGILL , SIGFPE y si nada funcionó, SIGKILL .

SIGUSR2 debería probarse antes de SIGUSR1 porque estamos mejor si el programa no maneja la señal. Y es mucho más probable que maneje SIGUSR1 si maneja solo uno de ellos.

Por cierto, el KILL : no es incorrecto enviar SIGKILL a un proceso, como se indicó en otra respuesta. Bien, ¿qué pasa cuando envías un comando de shutdown ? SIGTERM y SIGKILL solamente. ¿Por qué cree que es así? ¿Y por qué necesita otras señales si el comando de shutdown utiliza solo estas dos?

Ahora, de vuelta a la respuesta larga , este es un buen oneliner:

for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done

Duerme durante 30 segundos entre las señales. ¿Por qué más necesitarías un oneliner ? ;)

Además, se recomienda: pruébelo con solo señales 15 2 9 de la respuesta razonable .

seguridad : elimine el segundo echo cuando esté listo para comenzar. Lo llamo mi dry-run en dry-run para onliners . Siempre utilízalo para probar.

Script maliciosamente

En realidad, estaba tan intrigado con esta pregunta que decidí crear un pequeño guión para hacer precisamente eso. Por favor, puedes descargarlo (clonarlo) aquí:

Enlace de GitHub a Killgracefully repositorio


SIGTERM le dice a una aplicación que finalice. Las otras señales le dicen a la aplicación otras cosas que no están relacionadas con el apagado, pero a veces pueden tener el mismo resultado. No los uses. Si desea que se cierre una aplicación, dígaselo. No le des señales engañosas.

Algunas personas creen que la forma estándar inteligente de terminar un proceso es enviándoles un montón de señales, como HUP, INT, TERM y finalmente KILL. Esto es ridículo. La señal correcta para la terminación es SIGTERM y si SIGTERM no finaliza el proceso instantáneamente, como usted prefiere, es porque la aplicación ha elegido manejar la señal. Lo que significa que tiene una muy buena razón para no terminar de inmediato: tiene que hacer una limpieza. Si interrumpes ese trabajo de limpieza con otras señales, no hay forma de saber qué datos de la memoria aún no se han guardado en el disco, qué aplicaciones del cliente se dejan colgando o si lo estás interrumpiendo a mitad de frase, lo que efectivamente es corrupción de datos.

Para obtener más información sobre cuál es el significado real de las señales, vea sigaction (2). No confunda "Acción predeterminada" con "Descripción", no son lo mismo.

SIGINT se usa para señalar una "interrupción de teclado" interactiva del proceso. Algunos programas pueden manejar la situación de una manera especial para los usuarios de la terminal.

SIGHUP se utiliza para indicar que el terminal ha desaparecido y ya no está mirando el proceso. Eso es todo. Algunos procesos eligen apagar en respuesta, generalmente porque su operación no tiene sentido sin un terminal, algunos eligen hacer otras cosas como volver a verificar los archivos de configuración.

SIGKILL se usa para eliminar forzosamente el proceso del kernel. Es especial en el sentido de que en realidad no es una señal para el proceso, sino que el kernel lo interpreta directamente.

No envíe SIGKILL. SIGKILL ciertamente nunca debería ser enviado por scripts. Si la aplicación maneja el SIGTERM, puede tomar un segundo para la limpieza, puede tomar un minuto, puede tomar una hora . Dependiendo de lo que la aplicación deba hacer antes de que esté lista para finalizar. Cualquier lógica que " asume " la secuencia de limpieza de una aplicación ha tomado el tiempo suficiente y necesita ser atajo o SIGKILL después de X segundos es simplemente incorrecta .

La única razón por la cual una aplicación necesitaría un SIGKILL para terminar es si algo se interrumpe durante su secuencia de limpieza. En ese caso, puede abrir un terminal y SIGKILL manualmente. Aparte de eso, la única otra razón por la que SIGKILL algo es porque QUIERES evitar que se limpie a sí mismo.

No es porque la mitad del mundo usa SIGKILL después de 5 segundos para que no esté terriblemente mal.


  • SIGTERM es equivalente a "hacer clic en ''X''" en una ventana.
  • SIGTERM es lo que Linux usa primero, cuando se apaga.