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

Systemd:So führen Sie das Skript nur beim Herunterfahren aus (nicht beim Neustart)

Endlich habe ich herausgefunden, wie das geht.

Es ist ein bisschen hackish gedacht, aber es funktioniert.

Ich habe einen Teil dieses Threads verwendet:https://stackoverflow.com/questions/25166085/how-can-a-systemd-controled-service-distinguish-between-shutdown-and-reboot

und dieser Thread:Wie führe ich ein Skript mit systemd direkt vor dem Herunterfahren aus?

Ich habe diesen Dienst /etc/systemd/system/shutdown_screen.service erstellt

[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

Welches beim Herunterfahren/Neustarten/Halten/was auch immer ausgeführt wird. (Vergessen Sie nicht, es zu aktivieren)

Und in meinem Skript /usr/local/bin/shutdown_screen Ich habe folgendes eingefügt:

#!/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

Dadurch wird eine Shutdown-Nachricht an mein Arduino gesendet, das meinen Bildschirm herunterfährt.


Gemäß systemd.special man-page, sollten Sie Before=poweroff.target verwenden .

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.

Außerdem sollten Sie, wie ich in meinem Kommentar erwähnt habe, benutzerdefinierte Skripte in /etc/systemd/system/ einfügen . Die /usr/lib/systemd/system/ Verzeichnis soll für vom System bereitgestellte Skripte verwendet werden.

Also vielleicht so etwas:

[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

Beim Lesen der Antworten hier scheint es viele Missverständnisse darüber zu geben, wie systemd funktioniert. Verwenden Sie erstens keine Konflikte, um ein Ziel auszuschließen. Es soll verhindern, dass widersprüchliche Dienste gleichzeitig ausgeführt werden.

Wenn eine Unit eine Conflicts=-Einstellung auf einer anderen Unit hat, wird das Starten der ersteren die letztere stoppen und umgekehrt.

Einheit bedeutet eine .service-Datei zum Starten eines bestimmten Dienstes, nicht eines zu erreichenden Ziels. Mit anderen Worten Conflicts=reboot.target ist bestenfalls bedeutungslos und verhindert im schlimmsten Fall einen Neustart. Tu das nicht. Dies bedeutet nicht, dass Sie dies beim Neustart nicht ausführen. Es bedeutet, entweder diesen Dienst oder reboot.target abzubrechen, abhängig vom Timing und davon, wie Systemd diese fehlerhafte Verwendung von Konflikten interpretiert.

Hier ist ein Beispiel einer aktuell eingerichteten Einheit (auch bekannt als .service-Datei), die nur beim Herunterfahren und nicht beim Neustart ausgeführt wird:

[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 entspricht dem alten Systemv-Runlevel0, der nur beim Herunterfahren erreicht wird. halt.target ist ein alternativer Shutdown-Pfad, der von systemd verwendet wird und auch nicht durch einen Neustart erreichbar ist. Der Installationsabschnitt weist systemd an, diesen Dienst zur Liste hinzuzufügen, die vor poweroff.target vervollständigt werden muss oder halt.target gilt als erreicht.

Dieser Dienst ist auf meinem System installiert und wird dort ausgeführt.


Linux
  1. Wie schreibe ich ein Startskript für Systemd?

  2. Linux – Nur Userspace neu starten?

  3. Wie man Linux herunterfährt oder neu startet

  4. Wie führe ich ein Python-Skript von Java aus aus?

  5. So führen Sie eine Datei ohne die Erweiterung .sh in der Shell aus

So starten (rebooten) Sie Linux von der Befehlszeile aus

So vermeiden Sie ein versehentliches Herunterfahren oder Neustarten unter Linux

So richten Sie die automatische Ausführung eines Python-Skripts mit Systemd ein

So führen Sie Shell-Skript als SystemD-Dienst in Linux aus

Wie führe ich einen Befehl in einem Shell-Skript aus?

Wie man Debian 11 herunterfährt oder neu startet