GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Richtige Methode zur Verwendung von OnFailure in systemd

Um eine Bereinigung durchzuführen, wenn der Dienst fehlschlägt, können Sie ExecStopPost= verwenden , die unabhängig davon ausgeführt wird, ob der Dienst erfolgreich ist oder nicht.

Im Code, den Sie bei ExecStopPost= ausführen , können Sie einen von $SERVICE_RESULT verwenden , $EXIT_CODE oder $EXIT_STATUS um den Fehlerzustand zu bestimmen und entsprechend zu handeln. Sehen Sie in der Dokumentation zu diesen Umgebungsvariablen nach, um zu prüfen, welche für Sie geeignet ist.

Dann können Sie Restart=on-failure verwenden damit systemd versucht, Ihr Gerät neu zu starten, wenn es fehlschlägt.

Alles zusammengenommen würde es so aussehen. Angenommen, run_program wird mit Status 2 beendet, wenn die Dateien beschädigt sind (hoffentlich können Sie dies an andere Fehlerszenarien aus der obigen Dokumentation anpassen), dies sollte funktionieren:

[Service]
ExecStart=/bin/run_program
ExecStopPost=/bin/sh -c 'if [ "$$EXIT_STATUS" = 2 ]; then rm /file/to/delete; fi'
Restart=on-failure

(HINWEIS :Das doppelte Dollarzeichen $$ ist, dies an systemd zu maskieren, damit die Shell $EXIT_STATUS sieht und greift auf diese Variable zu. Die Verwendung eines einzelnen Dollarzeichens würde auch funktionieren, aber dann würde systemd stattdessen diese Ersetzung vornehmen und die Shell würde [ "2" = 2 ] sehen , was wohl auch funktioniert ... Wie auch immer, Sie können das meiste davon umgehen, indem Sie all diese Logik in ein Shell-Skript einfügen und es mit seinem vollständigen Pfad in ExecStopPost= aufrufen , das wäre wahrscheinlich besser und Sie könnten dem Skript auch problemlos weitere Befehle hinzufügen, z

Hoffentlich gibt Ihnen dies genügend Hinweise, um herauszufinden, wie Sie dies in Ihrer speziellen Situation richtig konfigurieren können!


HINWEIS :Wahrscheinlich möchten Sie ExecStopPost= verwenden statt OnFailure= hier (siehe meine andere Antwort), aber dies versucht zu erklären, warum Ihr OnFailure= Setup funktioniert nicht.

Das Problem mit OnFailure= Das Gerät kann nicht gestartet werden, weil es im falschen Abschnitt ist, es muss in [Unit] sein Abschnitt und nicht [Service] .

Sie können stattdessen Folgendes versuchen:

# software.service
[Unit]
Description=Software
OnFailure=software-fail.service

[Service]
ExecStart=/bin/run_program

Und:

# software-fail.service
[Unit]
Description=Delete corrupt files

[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service

Ich kann es mit diesem Setup zum Laufen bringen.

Beachten Sie jedoch, dass die Verwendung von OnFailure= ist hier nicht ideal, da Sie nicht wirklich sagen können, warum das Programm fehlgeschlagen ist, und einen weiteren Start davon in ExecStop= zu verketten durch Aufruf von /bin/systemctl start direkt ist ziemlich hacky... Die Lösung mit ExecStopPost= und der Blick auf den Exit-Status ist definitiv besser.

Wenn Sie OnFailure= definieren innerhalb von [Service] , systemd (mindestens Version 234 von Fedora 27) beschwert sich mit:

software.service:6: Unknown lvalue 'OnFailure' in section 'Service'

Ich bin mir nicht sicher, ob Sie das in Ihren Protokollen sehen oder nicht ... (Vielleicht wurde dies kürzlich in systemd hinzugefügt?) Das sollte ein Hinweis darauf sein, was dort vor sich geht.


Linux
  1. Verwenden Sie systemd-Timer anstelle von Cronjobs

  2. Verwalten Sie den Start mit systemd

  3. So verwenden Sie den Systemctl-Befehl zum Verwalten von Systemd-Diensten

  4. So erstellen Sie einen Systemd-Dienst unter Linux

  5. Wie verwendet Systemd /etc/init.d-Skripte?

Systemctl-Befehle zum Verwalten des Systemd-Dienstes

10 praktische systemd-Befehle:Eine Referenz

Verwalten von cgroups mit systemd

Korrekte Verwendung von Ubuntu systemctl zur Steuerung von Systemd

Systemd-Socket-Aktivierung vs. xinetd

Verwendung von CPUQuota in systemd