Ich muss alle paar Minuten ein paar Skripte ausführen. Die Logik wurde in PHP erstellt und funktioniert hervorragend. Um alles zusammenzuhalten, habe ich das folgende Bash-Skript erstellt, das auch problemlos läuft.
#!/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
Das Skript capturaRelatorio.php
enthält eine Ruhefunktion, da ich es nur alle N Minuten verarbeiten kann. Es wird eine Meldung ausgeben, dass es S Sekunden lang schläft, damit ich es überwachen kann.
Wenn ich das Bash-Skript aufrufe und zu diesem Zeitpunkt, während es schläft, Ctrl+ drücke C, wird das Bash-Skript beendet, das aufgerufene PHP-Skript jedoch nicht. Ich verstehe, dass es von einem anderen Prozess ausgeführt wird.
Gibt es also eine Möglichkeit, das Bash-Skript und alle „untergeordneten“ Elemente zu beenden? Oder sollte ich einen anderen Ansatz wählen, um diese Skripte auszuführen?
Antwort1
Aus dieser Antwort:bash - Wie beendet man alle Unterprozesse der Shell? - Stack Overflow.
Wenn es Ihnen nur darum geht, direkte Kinder zu töten, sollten Sie in der Lage sein,
pkill -P $$
-P
sagt
-P, --parent ppid,...
Only match processes whose parent process ID is listed.
Und $$
bedeutet die PID des aktuellen Prozesses.
Wenn Sie untergeordnete Prozesse und alle Prozesse, die sie möglicherweise starten (Enkelprozesse usw.), beenden müssen, sollten Sie die Funktion verwenden können, die in einer anderen Antwort auf diese Frage steht:
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
}
So was
kill_descendant_processes $$ true
Dadurch wird der aktuelle Prozess und alle Nachkommen beendet. Sie möchten dies wahrscheinlich von einem Trap-Handler aus aufrufen. Das heißt, wenn Sie ctrl+ drücken c, wird Ihr Skript gesendet SIGINT
und Sie können dieses Signal abfangen und verarbeiten. Beispiel:
trap cleanup INT
cleanup() {
kill_descendant_processes $$ true
}
Antwort2
Sie können das Bash-Skript aktualisieren, um Strg+C abzufangen:
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
}