Necesito ejecutar algunos scripts cada pocos minutos. La lógica se creó en PHP y está funcionando muy bien. Para mantener las cosas juntas, he creado el siguiente script bash, que también funciona bien.
#!/bin/bash
calculaDiff() {
DIFF=0
while [ "$DIFF" -eq "0" ]; do
DIFF=`php calculaDiff.php`
done;
}
# need to calculate pending diffs
calculaDiff
# main loop
while true; do
CAPTURA=`php capturaRelatorio.php`
if [ "$CAPTURA" -eq "0" ]; then
calculaDiff
fi
VERIFICA=`php verificaLimites.php`
done
El script capturaRelatorio.php
tiene un modo de suspensión porque solo puedo procesarlo cada N minutos. Imprimirá un mensaje diciendo que está durmiendo durante S segundos para que pueda monitorearlo.
Si llamo al script bash y presiono Ctrl+ Cen este momento, mientras está inactivo, mata el script bash, pero no mata el script php llamado. Entiendo que hay un proceso diferente ejecutándolo.
Entonces, ¿hay alguna manera de eliminar el script bash y todos los "niño"? ¿O debería optar por otro enfoque para ejecutar estos scripts?
Respuesta1
De esta respuesta:bash - ¿Cómo eliminar todos los subprocesos de Shell? - Desbordamiento de pila.
Si sólo te importa matar niños directos, deberías poder hacerlo.
pkill -P $$
-P
dice
-P, --parent ppid,...
Only match processes whose parent process ID is listed.
Y $$
significa el PID del proceso actual.
Si necesita eliminar procesos secundarios y cualquier proceso que puedan iniciar (nietos, etc.), debería poder usar la función que se encuentra en una respuesta diferente a esa pregunta:
kill_descendant_processes() {
local pid="$1"
local and_self="${2:-false}"
if children="$(pgrep -P "$pid")"; then
for child in $children; do
kill_descendant_processes "$child" true
done
fi
if [[ "$and_self" == true ]]; then
kill "$pid"
fi
}
Como esto
kill_descendant_processes $$ true
Lo que matará el proceso actual y todos los descendientes. Probablemente querrás llamar a esto desde un controlador de trampas. Es decir, cuando presione ctrl+ c, se enviará su script SIGINT
y podrá captar esa señal y manejarla. Por ejemplo:
trap cleanup INT
cleanup() {
kill_descendant_processes $$ true
}
Respuesta2
Puede actualizar el script bash para capturar ctrl+c:
trap control_c SIGINT
function control_c() {
echo "## Trapped CTRL-C"
ps -ef | grep php | grep -v grep | awk '{ print $2 }' > php.kill
for i in $(cat php.kill)
do
kill -9 $i > /dev/null
done
rm php.kill
}