GNU/Linux >> Znalost Linux >  >> Linux

Správný způsob použití OnFailure v systemd

Chcete-li provést nějaké vyčištění, pokud služba selže, můžete použít ExecStopPost= , který se provede bez ohledu na to, zda je služba úspěšná nebo ne.

V kódu spustíte na ExecStopPost= , můžete použít jeden z $SERVICE_RESULT , $EXIT_CODE nebo $EXIT_STATUS určit poruchový stav a podle toho jednat. Podívejte se do dokumentace k těmto proměnným prostředí a zjistěte, která z nich je pro vás vhodná.

Pak můžete použít Restart=on-failure takže systemd se pokusí restartovat vaši jednotku, když selže.

Když to dáme dohromady, tak by to vypadalo takto. Za předpokladu, že run_program skončí se stavem 2, kdykoli jsou soubory poškozeny (doufejme, že to můžete přizpůsobit jiným scénářům selhání z dokumentace výše), mělo by to fungovat:

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

(POZNÁMKA :Dvojitý znak dolaru $$ je to uniknout do systemd, takže shell vidí $EXIT_STATUS a přistupuje k této proměnné. Použití jediného znaku dolaru by také fungovalo, ale pak by toto nahrazení provedl systemd a shell by viděl [ "2" = 2 ] , což pravděpodobně také funguje... Většinu z toho můžete obejít tak, že veškerou tuto logiku vložíte do skriptu shellu a zavoláte ji úplnou cestou v ExecStopPost= , to by bylo pravděpodobně lepší a také byste mohli do skriptu snadno přidat další příkazy, jako je protokolování akce provedené k zotavení z chybového stavu.)

Doufejme, že vám to poskytne dostatek ukazatelů, abyste zjistili, jak to správně nakonfigurovat ve vaší konkrétní situaci!


POZNÁMKA :Pravděpodobně budete chtít použít ExecStopPost= místo OnFailure= zde (viz moje další odpověď), ale toto se snaží vyřešit, proč vaše OnFailure= nastavení nefunguje.

Problém s OnFailure= nespuštění jednotky může být způsobeno tím, že je ve špatné sekci, musí být v [Unit] sekce a ne [Service] .

Místo toho můžete zkusit toto:

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

[Service]
ExecStart=/bin/run_program

A:

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

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

S tímto nastavením to zvládnu.

Všimněte si však, že pomocí OnFailure= zde není ideální, protože nemůžete skutečně říct, proč program selhal a zřetězení dalšího jeho spuštění v ExecStop= voláním /bin/systemctl start přímo je dost hackery... Řešení pomocí ExecStopPost= a pohled na výstupní stav je rozhodně lepší.

Pokud definujete OnFailure= uvnitř [Service] , systemd (alespoň verze 234 z Fedory 27) si stěžuje:

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

Nejste si jisti, zda to vidíte ve svých protokolech nebo ne... (Možná to bylo přidáno v nedávném systemd?) To by měl být náznak toho, co se tam děje.


Linux
  1. Jak používat příkaz Systemctl ke správě služeb Systemd

  2. Jak vytvořit službu Systemd v Linuxu

  3. Jak Systemd používá skripty /etc/init.d?

  1. Jaký způsob použití Xargs napříč potrubím?

  2. Debian – správný způsob použití Onfailure v Systemd?

  3. Ke správě služeb použijte Systemctl

  1. Spravujte spouštění pomocí systemd

  2. Jak použít Systemd k restartování služby, když je vypnutá?

  3. Jak zastavit službu systemd