Preciso executar alguns scripts a cada poucos minutos. A lógica foi feita em PHP e está funcionando muito bem. Para manter tudo sob controle, criei o script bash abaixo, que também funciona bem.
#!/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
O script capturaRelatorio.php
está suspenso porque só consigo processá-lo a cada N minutos. Ele imprimirá uma mensagem dizendo que está dormindo por S segundos para que eu possa monitorá-lo.
Se eu chamar o script bash e pressionar Ctrl+ Cneste momento, enquanto ele está dormindo, ele mata o script bash, mas não mata o script php chamado. Entendo que há um processo diferente executando-o.
Então, existe uma maneira de matar o script bash e todas as “crianças”? Ou devo adotar outra abordagem para executar esses scripts?
Responder1
Desta resposta:bash - Como matar todos os subprocessos do shell? - Estouro de pilha.
Se você só se preocupa em matar crianças diretas, você deveria ser capaz de fazer
pkill -P $$
-P
diz
-P, --parent ppid,...
Only match processes whose parent process ID is listed.
E $$
significa o PID do processo atual.
Se você precisar eliminar processos filhos e quaisquer processos que eles possam iniciar (netos e assim por diante), você poderá usar a função que está em uma resposta diferente para essa pergunta:
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
}
Assim
kill_descendant_processes $$ true
O que matará o processo atual e todos os descendentes. Você provavelmente desejará chamar isso de um manipulador de trap. Ou seja, ao pressionar ctrl+ c, seu script será enviado SIGINT
e você poderá captar esse sinal e tratá-lo. Por exemplo:
trap cleanup INT
cleanup() {
kill_descendant_processes $$ true
}
Responder2
Você pode atualizar o script bash para interceptar 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
}