Durch Drücken von Strg-C wird das Bash-Skript gestoppt, das vom Skript aufgerufene PHP-Skript wird jedoch nicht gestoppt.

Durch Drücken von Strg-C wird das Bash-Skript gestoppt, das vom Skript aufgerufene PHP-Skript wird jedoch nicht gestoppt.

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.phpenthä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 $$

-Psagt

-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 SIGINTund 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
}

verwandte Informationen