Estoy tratando de configurar un script de shell para que ejecute procesos en segundo plano, y cuando uso Ctrlcel script de shell, mata a los hijos y luego sale.
Lo mejor que he logrado hacer es esto. Parece que kill 0 -INTtambién mata el script antes de que ocurra la espera, por lo que el script de shell muere antes de que los niños completen.
¿Alguna idea sobre cómo puedo hacer que este script de shell espere a que los niños mueran después de enviar INT?
#!/bin/bash
trap 'killall' INT
killall() {
echo "**** Shutting down... ****"
kill 0 -INT
wait # Why doesn't this wait??
echo DONE
}
process1 &
process2 &
process3 &
cat # wait forever

Respuestas:
Tu
killcomando está al revés.Al igual que muchos comandos de UNIX, las opciones que comienzan con un signo menos deben aparecer primero, antes que otros argumentos.
Si tú escribes
ve el
-INTcomo una opción y envíaSIGINTa0(0es un número especial que significa todos los procesos en el grupo de procesos actual).Pero si escribes
ve el
0, decide que no hay más opciones, por lo que usaSIGTERMde forma predeterminada. Y envía que al grupo de proceso actual, lo mismo que si lo hizo(que también intente enviar
SIGTERMa-INT, lo que provocaría un error de sintaxis, pero envíaSIGTERMa0la primera, y nunca llega tan lejos.)Por lo tanto, su script principal está obteniendo un
SIGTERMantes de ejecutar elwaityecho DONE.Añadir
en la parte superior, justo después
y ejecutarlo nuevamente para probar esto.
Como señala Stephane Chazelas, sus hijos en segundo plano (
process1, etc.) ignoraránSIGINTde forma predeterminada.En cualquier caso, creo que enviar
SIGTERMtendría más sentido.Finalmente, no estoy seguro de si
kill -process groupse garantiza ir primero a los niños. Ignorar las señales mientras se apaga puede ser una buena idea.Así que prueba esto:
fuente
Desafortunadamente, los comandos iniciados en segundo plano son configurados por el shell para ignorar SIGINT, y peor aún, no pueden ignorarlo
trap. De lo contrario, todo lo que tendría que hacer esPorque process1 y process2 obtendrían el SIGINT cuando presiona Ctrl-C ya que son parte del mismo grupo de procesos que es el grupo de procesos en primer plano del terminal.
El código anterior funcionará con pdksh y zsh que, en ese sentido, no son compatibles con POSIX.
Con otros shells, tendría que usar algo más para restaurar el controlador predeterminado para SIGINT como:
o use una señal diferente como SIGTERM.
fuente
Para aquellos que solo quieren matar un proceso y esperar a que muera, pero no indefinidamente :
Espera un máximo de 60 segundos por tipo de señal.
Advertencia: esta respuesta no está relacionada de ninguna manera con atrapar una señal de muerte y enviarla.
Selecciona la aplicación para matar por nombre o argumentos. Mantenga los corchetes para la primera letra del nombre de la aplicación para evitar coincidir con grep.
Con algunos cambios, puede usar directamente el PID o un simple en
pidof process_namelugar de lapsdeclaración.Detalles del código: grep final es obtener el PID sin los espacios finales.
fuente
Si lo que desea es administrar algunos procesos en segundo plano, ¿por qué no utilizar las funciones de control de trabajos bash?
fuente
Así que también jugué con esto. En Bash, puedes definir funciones y hacer cosas elegantes con ellas. Mis compañeros de trabajo y yo usamos
terminator, por lo que para las ejecuciones por lotes normalmente generamos un montón de ventanas de terminación si queremos ver la salida (menos elegante que lastmuxpestañas, pero puede usar una interfaz más similar a la GUI jaja).Aquí está la configuración que se me ocurrió, así como un ejemplo de cosas que puede ejecutar:
Corriendo
Edite @Maxim, acabo de ver su sugerencia, ¡eso lo hace mucho más simple! ¡Gracias!
fuente