Einen Prozess sauber beenden

Einen Prozess sauber beenden

Ich muss dafür sorgen, dass die Linux-Ubuntu-Plattform automatisch einen Prozess startet und beendet. Zum Beispiel wird der Prozess um 8 Uhr morgens gestartet und um 19 Uhr beendet. Das muss jeden Tag passieren und sollte völlig in Ordnung sein, wenn das Zeitintervall leicht geändert werden kann.

Ich versuche, einfache Codes in Crontab zu verwenden:

28 12 * * * /home/pi/Desktop/start.sh
50 11 * * * pkill led.py

Schau mal nicht hin, ich habe versucht, sie zu ändern, start.shstartet led.pydas Skript, aber ich kann es nicht stoppen, wenn ich benutze . Der Prozess wird beendet, aber die LEDs gehen nicht aus. Wenn ich das Programm manuell starte und es dann mit + pkill -9 -f led.pybeende , gehen die LEDs aus. Wo ist das Problem? Warum kann ich den Prozess nicht beenden und gleichzeitig die LEDs ausschalten?Ctrlc

Antwort1

Wenn Sie Ctrl+ eingeben c, sendet das dem Prozess normalerweise ein „INT“-Signal. Vonsignal(7):

  Signal     Value     Action   Comment
  ──────────────────────────────────────────────────────────────────────
  ...
  SIGINT        2       Term    Interrupt from keyboard

Normalerweise installieren Prozesse einen Handler für dieses Signal, der ihnen erlaubt, vor dem Beenden einige Bereinigungsarbeiten durchzuführen. Im Fall Ihres led.pySkripts klingt es so, als ob dieser Handler die LEDs ausgeschaltet hätte.

Standardmäßig pkillwird killdas Signal "TERM" (15) gesendet. (Sie haben auch versucht, "KILL" (9) zu senden.) Diese Signale führten dazu, led.pydass der Server weniger elegant abstürzte, ohne die Möglichkeit zu haben, seine Abschlussfunktion auszuführen.

Um led.pyeinen sauberen Abschluss zu ermöglichen, sollten Sie das Signal "INT" (2) senden, mit

pkill -2 [process specifier]

Der pkillBefehl in Ihrem crontabkonnte den Prozess möglicherweise auch nicht finden, weil der von Ihnen angegebene Name nicht der gesuchte war. Vonpkill(1):

-f, --full

DerMusterwird normalerweise nur mit dem Prozessnamen abgeglichen. Wenn-Fgesetzt ist, wird die vollständige Befehlszeile verwendet.

Da Ihr Skript led.pyvermutlich ein Python-Skript war, lautete der Prozessname einfach python(oder python3, oder ähnlich). Die vollständige Befehlszeile würde etwa wie aussehen python led.py, sodass -fSie mit den Optionen danach suchen können.

pkill -2 -f led.py

Antwort2

Ich benutze diese Funktion seit vielen Jahren:

function killit () {
for process in "$@"; do
    kill -0 $process &>/dev/null
    if [[ $? == 0 ]] ; then
        sudo kill $process #(sends a TERM, wait 5 seconds)
        sleep 5
        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
        if [[ $RUNNING ]] ; then
            echo "$0 WARNING: process $process still running, trying kill again"
            sudo kill $process #(yes, try again, wait 5 seconds)
            sleep 5
            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
            if [[ $RUNNING ]] ; then
                echo "$0 WARNING: process $process still running, trying kill -INT"
                sudo kill -INT $process  #(wait for it)
                sleep 5
                RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                if [[ $RUNNING ]] ; then
                    echo "$0 WARNING: process $process still running, trying kill -INT again"
                    sudo kill -INT $process  #(damn, still not dead?)
                    sleep 5
                    RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                    if [[ $RUNNING ]] ; then
                        echo "$0 WARNING: process $process still running, trying kill -KILL"
                        sudo kill -KILL $process #(same thing as -9)
                        sleep 5
                        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                        if [[ $RUNNING ]] ; then
                            echo "$0 WARNING: process $process still running, trying kill -KILL again"
                            sudo kill -KILL $process #(something is wrong)
                            sleep 5
                            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                            if [[ $RUNNING ]] ; then
                                echo "$0 WARNING: Can't kill process $process"
                                logger "$0 WARNING: Can't kill process $process"
                            fi
                        fi
                    fi
                fi
            fi
        fi
    fi
done
}

verwandte Informationen