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 -INT
tambié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
kill
comando 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
-INT
como una opción y envíaSIGINT
a0
(0
es 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 usaSIGTERM
de forma predeterminada. Y envía que al grupo de proceso actual, lo mismo que si lo hizo(que también intente enviar
SIGTERM
a-INT
, lo que provocaría un error de sintaxis, pero envíaSIGTERM
a0
la primera, y nunca llega tan lejos.)Por lo tanto, su script principal está obteniendo un
SIGTERM
antes de ejecutar elwait
yecho 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ánSIGINT
de forma predeterminada.En cualquier caso, creo que enviar
SIGTERM
tendría más sentido.Finalmente, no estoy seguro de si
kill -process group
se 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_name
lugar de laps
declaració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 lastmux
pestañ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