Wie macht man einen systemd-Dienst als letzten Dienst beim Booten?

26

Vor vielen Jahren konnten wir unser Startup-Skript schreiben /etc/rc.local. Nachdem alle Systemdienste geladen wurden, wird Ihr Skript ausgeführt.

Jetzt benutzen wir systemd, das haben wir nicht rc.localmehr. Systemd startet den Dienst parallel. Sie können Ihren eigenen Dienst schreiben, um einen rc.local-Befehl auszuführen, können jedoch nicht sicherstellen, dass er ausgeführt wird, nachdem alle Systemdienste geladen wurden.

Gibt es eine Möglichkeit, dies zu tun? Oder müssen wir Beforeund Afterin der systemd-Servicedatei verwenden?

比尔 比尔
quelle
5
Systemd, nicht Upstart !!
比尔 盖子
Name und Version des Betriebssystems angeben?
STTR
Betriebssystem: Arch Linux, Version: N / A
比尔 比尔
1
@ 比尔 比尔 Warum "last", kennen Sie die Abhängigkeiten des Skripts nicht oder möchten Sie, dass es nur als letztes sicher ist?
Paul

Antworten:

27

In systemd ist es empfehlenswert , Ihre Dienste schön um die anderen zu nutzen Before=und After=zu bestellen.

Da Sie jedoch nach einem Weg gefragt haben, ohne Beforeund zu verwenden After, können Sie Folgendes verwenden:

Type=idle

was wie man systemd.servicefolgt erklärt:

Verhalten idleist sehr ähnlich zu simple; Die tatsächliche Ausführung des Serviceprogramms wird jedoch verzögert, bis alle aktiven Jobs abgesetzt sind. Dies kann verwendet werden, um eine Verschachtelung der Ausgabe von Shell-Diensten mit der Statusausgabe auf der Konsole zu vermeiden. Beachten Sie, dass dieser Typ nur zur Verbesserung der Konsolenausgabe nützlich ist, nicht als allgemeines Tool zum Bestellen von Einheiten geeignet ist und die Auswirkung dieses Servicetyps einer Zeitüberschreitung von 5 Sekunden unterliegt, nach der das Serviceprogramm trotzdem aufgerufen wird.

SimonPe
quelle
1
Hallo, würde es Ihnen etwas ausmachen, die Syntax zu erläutern, wenn ich sie vorher oder nachher verwenden würde?
r4ccoon
Etwas anderes Thema, aber wenn jemand Benutzerprozesse getrennt von Systemprozessen ausführen möchte, gibt es askubuntu.com/a/859583/457417
Ben Creasy,
perfekt Set gearbeitet , /proc/sys/kernel/modules_disabledum 1am Ende des Bootprozesses
Stuart Cardall
0

Es hängt wirklich von Ihrer Definition von "gebootet" ab. Ich nehme an, Sie möchten, dass es sofort nach dem Start von getty ausgeführt wird. Dazu müssen Sie Ihren Dienst zum /etc/systemd/system/getty.target.wants/Verzeichnis hinzufügen . Sie sollten auch sicherstellen, dass Ihre Datei ähnlichen Code wie die anderen Dienste in diesem Verzeichnis verwendet. Um einen benutzerdefinierten Dienst beim Booten und Herunterfahren auszuführen (piept einfach meinen Motherboard-Summer), verwende ich das folgende Skript in/etc/systemd/system/getty.target.wants/service_name.service

[Unit]
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
Before=getty.target
IgnoreOnIsolate=yes

[Service]
ExecStart=/usr/bin/myinitscript.sh start
ExecStop=/usr/bin/myinitscript.sh stop
Type=oneshot
RemainAfterExit=true

[Install]
WantedBy=basic.target

/usr/bin/myinitscript.sh ist ausführbar und hat einen Shebang am Start.

Beachten Sie, dass nicht alles an diesem Punkt des Startvorgangs gestartet wird, sondern an diesem Punkt die Anmeldeaufforderung für den Benutzer angezeigt wird

Obwohl dies Before=und verwendet After=, war es für mich viel verständlicher und funktioniert tatsächlich; Ich fand die obige Antwort nicht informativ genug. Auf diese Weise können Sie auch beides verwenden ExecStart=und ExecStop=sind nicht auf einen Type=simpleähnlichen Dienst beschränkt.

Hack5
quelle
-2

Ich kenne die Besonderheiten von ArchLinux nicht, aber hier erfahren Sie, wie man systemd im Allgemeinen verwaltet.

Nun, im Grunde ist systemd eine Sammlung von Skripten in /etc/init.d/, auf die durch Symlinks von /etc/rcX.d verwiesen wird, wobei X die Nummer der Ausführungsebene ist. Symlinks selbst haben das folgende Format:

[K | S] + nn + [string]

woher:

  • nn ist eine Zahl, die die Reihenfolge festlegt, in der diese Skripte ausgeführt werden
  • string ist der Name des Skripts, wie er in /etc/init.d/ angezeigt wird.
  • und schließlich K oder S bestimmen den Befehl, mit dem das Skript aufgerufen wird: stop bzw. start.

Wenn Ihr Skript also als letztes in der Startsequenz ausgeführt werden soll, müssen Sie Folgendes tun:

  1. Stellen Sie Ihr Skript in /etc/init.d/ und machen Sie es ausführbar
  2. Bestimmen Sie den Ziel-Runlevel, auf dem das Skript beginnen soll (normalerweise 2 für die Konsole und 5 für die grafische Benutzeroberfläche). Kann bestimmt mit sowas werdenrunlevel
  3. Schauen Sie sich an, welche Skripte sich bereits in diesem Runlevel befinden, ls /etc/rc<target runlevel>.d/und wählen Sie eine zweistellige Zahl, die größer ist als alle anderen, die sich bereits in diesem Runlevel befinden.
  4. Erstellen Sie mit einem für Ihre Distribution spezifischen Hilfsprogramm, z. B. update-rc.dfür Debian oder chkconfigFedora, oder manuell einen Symlink /etc/rc.d/S zu Ihrem Init-Skript.
Pavel A
quelle
5
Was Sie beschrieben haben, ist eigentlich sysVinit. Obwohl systemd mit der Funktionsweise von sysVinit kompatibel ist, gibt es einen entscheidenden Unterschied: Alles wird parallel ausgeführt. Es gibt auch zwei Arten von Diensten, sysVinit-Dienste und systemd-Dienste. Ihre Antwort kann dazu beitragen, dass etwas nach den sysVinit-Diensten ausgeführt wird, aber nicht unbedingt nach den systemd-Diensten.
Sam
1
Systemd will vom ersten Tag an überhaupt nicht mit sysvinit kompatibel sein.
lzap