Ich habe einen Dienst, der Software ausführt, die einige Konfigurationsdateien generiert, wenn sie nicht existieren, und sie liest, wenn sie existieren. Das Problem, mit dem ich konfrontiert war, ist, dass diese Dateien manchmal beschädigt werden, wodurch die Software nicht gestartet werden kann und somit der Dienst fehlschlägt. In diesem Fall möchte ich diese Dateien entfernen und den Dienst neu starten.
Ich habe versucht, einen Dienst zu erstellen, der im Fehlerfall ausgeführt werden soll, indem ich Folgendes mache:
[Service]
ExecStart=/bin/run_program
OnFailure=software-fail.service
wo dieser Dienst ist:
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=systemctl --user start software.service
Das Problem ist jedoch, dass dieser Dienst nicht gestartet wird, selbst wenn der Dienst fehlgeschlagen ist.
Ich habe es versucht.
systemctl --user enable software-fail.service
aber dann startet es jedes Mal, wenn das System startet, genau wie jeder andere Dienst.
Meine vorübergehende Lösung ist die Verwendung von
ExecStopPost=/bin/rm /file/to/delete
aber dies ist keine zufriedenstellende Lösung, da die Datei immer gelöscht wird, wenn der Dienst beendet wird, egal ob es sich um einen Fehler handelt oder nicht.
Ausgabe bei Fehler:
● software.service - Software
Loaded: loaded (/home/trippelganger/.config/systemd/user/software.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-05-04 09:05:26 CEST; 5s ago
Process: 1839 ExecStart=/bin/run_program (code=exited, status=1/FAILURE)
Main PID: 1839 (code=exited, status=1/FAILURE)
May 04 09:05:26 trippelganger systemd[595]: software.service: Main process exited, code=exited, status=1/FAILURE
May 04 09:05:26 trippelganger systemd[595]: software.service: Unit entered failed state.
May 04 09:05:26 trippelganger systemd[595]: software.service: Failed with result 'exit-code'.
Die Ausgabe von systemctl –user status software-fail.service
lautet:
● software-fail.service - Delete corrupt files
Loaded: loaded (/home/trippelganger/.config/systemd/user/software-fail.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Akzeptierte Antwort:
HINWEIS :Wahrscheinlich möchten Sie ExecStopPost=
verwenden statt OnFailure=
hier (siehe meine andere Antwort), aber dies versucht zu beheben, warum Ihr OnFailure=
Setup funktioniert nicht.
Das Problem mit OnFailure=
Wenn Sie die Unit nicht starten, kann dies daran liegen, dass sie sich im falschen Abschnitt befindet, sie muss sich in [Unit]
befinden 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.
Verwandte:Unterschied zwischen ‚>‘ und ‚-gt‘?