bash signals copy-paste kill bash-trap

bash - ¿Cómo propagar una señal a través de una colección de scripts?



signals copy-paste (4)

Tengo una colección de scripts que son controlados por uno principal. Quiero atrapar la señal ctrl + c en el script principal y propagarla a los demás. Los otros scripts también deberían capturar esta señal (del script principal) y realizar una limpieza ...

He intentado enviar kill -s SIGINT a los niños, pero parece que no pueden captar la señal (incluso si la trap ''Cleanup'' SIGINT se define en los scripts de los niños)

¿Alguna pista de cómo realizar esto?


¿Ha intentado: 1) configurar sus trampas en cada script (maestro / niño) donde los necesita 2) enviar al maestro un asesinato con su PID negado, para matar a todo el grupo de procesos, quiero decir:

kill -15 -$PID

hombre mata grep -C1 Negativo


El siguiente ejemplo muestra una secuencia de comandos principal que hace algo ( sleep 5 ) después de que comienza a dos niños que hacen lo suyo (también sleep 5 ). Cuando el padre sale (por cualquier motivo), señala a los hijos que terminen (no SIGINT , la terminación es señalada por SIGTERM , también la señal de interrupción por defecto). Luego los niños hacen lo suyo en la recepción de SIGTERM . Si los niños son sus propios scripts, te recomiendo que cambies la trampa de TERM en una trampa en EXIT para que los niños se limpien sin importar cuál sea la causa de su terminación (siempre que sea trampa).

Note mi uso de la wait . Bash no interrumpe la ejecución de comandos no integrados cuando recibe una señal. En su lugar, espera a que se completen y maneja la señal una vez que se ejecuta el comando. Si usa wait , bash deja de esperar inmediatamente y maneja la señal de inmediato.

#!/usr/bin/env bash trap ''echo parent shutting down; kill $(jobs -p)'' EXIT { trap ''echo child 1 signaled'' TERM; sleep 5 & wait; } & { trap ''echo child 2 signaled'' TERM; sleep 5 & wait; } & sleep 5


No estoy seguro de qué quiere decir con "otros scripts deberían atrapar esta señal del script principal"? ¿Cómo puede un código de subproceso usar código en el script principal para interceptar una señal?

No quiero intentar escribir mucho código para usted porque tampoco sé exactamente a qué se refiere con "guiones controlados por uno principal", pero presumiblemente inicie algunos subprocesos y tendrá un bucle de control que verifica si el otro Los scripts han salido, y pueden tomar su estado de salida? Si ese es el caso, lo que tiene más sentido para mí es que cada script haga su propia captura y limpieza. Cuando el script principal atrapa una señal, puede, si lo desea, transmitir la señal a todos los niños (a través de kill -s <signal> pid ). Cuando un proceso hijo atrapa una señal, puede devolver un estado de salida que indica que fue terminada por esa señal. Entonces, el principal puede manejar ese estado de salida de manera apropiada, tal vez de la misma manera que si hubiera recibido esa señal en particular. (Las funciones de Shell son tus amigas).


PADRE PRINCIPAL DE LAS ESCRITURAS DE PADRES ANTES DE LA BANDERA PRINCIPAL :::

#Catch control-c and clean up testd instances if necessary cleanup () { clear echo "Caught Signal. Shutting Down MAIN." if [ "$MAIN_on" -eq 1 ] then M_shutdown fi exit 1 }

En el cuerpo principal del script, a medida que genera subprocesos, mantiene una matriz con los identificadores de proceso de cada uno. Para cargar el PID en la matriz, establezca el valor en el último proceso generado, por ejemplo, coloque lo siguiente después de cada generación de sub-shell.

proc_id_array[1]=$!

El contenido del M_shutdow sería algo así como ...

M_shutdown () { if [ "$MAIN_on" -eq 1 ] then echo "Stopping Main" echo "shutting down active subscripts" count_proc_id=1 while [ "$count_proc_id" -lt "$max_proc_id" ] do kill ${proc_id_array[$count_proc_id]} > /dev/null 2>&1 DATE=$(date +%m%d%y-%k:%M) echo "$DATE: ${proc_name_array[$count_proc_id]} /(PID: ${proc_id_array[$count_proc_id]}/) stopped." >> $logfile proc_id_array[$count_proc_id]="A" count_proc_id=`expr $count_proc_id + 1` done echo "MAIN stopped" MAIN_on=0 sleep 5 else echo "MAIN already stopped." sleep 1 fi }