GNU/Linux >> Znalost Linux >  >> Linux

Systemd :Jak spustit skript pouze při vypnutí (ne při restartu)

Konečně jsem našel, jak to udělat.

Je to trochu hackerská myšlenka, ale funguje to.

Použil jsem část tohoto vlákna:https://stackoverflow.com/questions/25166085/how-can-a-systemd-controlled-service-distinguish-between-shutdown-and-reboot

a toto vlákno :Jak spustit skript pomocí systemd těsně před vypnutím?

Vytvořil jsem tuto službu /etc/systemd/system/shutdown_screen.service

[Unit]
Description=runs only upon shutdown
Conflicts=reboot.target
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/bin/bash /usr/local/bin/shutdown_screen
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Který bude proveden při vypnutí/reboot/zastavení/cokoli. (nezapomeňte to povolit)

A v mém skriptu /usr/local/bin/shutdown_screen Vložil jsem následující :

#!/bin/bash
# send a shutdown message only at shutdown (not at reboot)    
/usr/bin/systemctl list-jobs | egrep -q 'reboot.target.*start' || echo "shutdown" | nc 192.168.0.180 4243 -w 1

Který odešle zprávu o vypnutí mému arduinu, kdo vypne mou obrazovku.


Podle systemd.special man-page, měli byste použít Before=poweroff.target .

poweroff.target

A special target unit for shutting down and powering off the system.

Applications wanting to power off the system should start this unit.

runlevel0.target is an alias for this target unit, for compatibility with SysV.

Navíc, jak jsem zmínil ve svém komentáři, měli byste vkládat vlastní skripty do /etc/systemd/system/ . /usr/lib/systemd/system/ adresář je určen k použití pro skripty poskytované systémem.

Takže možná něco takového:

[Unit]
Description=runs only upon shutdown
DefaultDependencies=no
Conflicts=reboot.target
Before=shutdown.target
Requires=poweroff.target

[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/usr/local/bin/yourscript
RemainAfterExit=yes

Z přečtení odpovědí zde se zdá, že existuje mnoho nedorozumění o tom, jak systemd funguje. Za prvé nepoužívejte konflikty k vyloučení cíle. Je důležité zabránit tomu, aby byly konfliktní služby spouštěny současně.

Pokud má jednotka nastavení Conflicts=na jiné jednotce, spuštění první jednotky zastaví druhou a naopak.

Jednotka znamená soubor .service pro spuštění příslušné služby, která není cílem, kterého má být dosaženo. Jinými slovy Conflicts=reboot.target je v nejlepším případě bezvýznamný a v nejhorším vám zabrání v restartu. Nedělej to. Neznamená to, že to při restartu nespouštět. Znamená to zrušit buď tuto službu, nebo reboot.target v závislosti na načasování a na tom, jak systemd interpretuje toto chybné použití konfliktů.

Zde je příklad aktuálně nastavené jednotky (aka soubor .service), která běží pouze při vypnutí, nikoli po restartu:

[Unit]
Description=Play sound
DefaultDependencies=no
Before=poweroff.target halt.target

[Service]
ExecStart=/usr/local/bin/playsound.sh
ExecStop=/usr/local/bin/playsound.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=poweroff.target halt.target 

poweroff.target je ekvivalentní staré systémové úrovni běhu 0, které je dosaženo pouze při vypnutí. halt.target je alternativní cesta k vypnutí, kterou používá systemd, kterou nelze dosáhnout ani restartem. Sekce instalace říká systemd, aby přidal tuto službu do seznamu, který musí být dokončen do poweroff.target nebo halt.target budou považovány za dosažené.

Tato služba je nainstalována a spuštěna v mém systému.


Linux
  1. Jak automaticky spouštět příkazy/skripty během restartu nebo spouštění

  2. Jak vypnout nebo restartovat Linux pomocí příkazového řádku

  3. Jak napsat spouštěcí skript pro Systemd?

  1. Linux – restartovat pouze uživatelský prostor?

  2. Jak vypnout nebo restartovat Linux

  3. Jak spustit soubor bez přípony .sh v shellu

  1. Jak zakázat příkazy vypnutí a restartu v Linuxu

  2. Jak vyčistit pouze cíl v buildroot

  3. Jak spustit bash skript?