So schreiben Sie eine systemd .service-Datei, in der systemd-tmpfiles ausgeführt werden

16

Ich muss systemd-tmpfiles --createwährend des Bootvorgangs mit einer Systemdistribution laufen . Daher muss ich für diesen Job eine systemd .service-Datei erstellen.

In dieser Frage können Sie alle Details darüber lesen, was ich brauche und warum: Wie funktioniert systemd-tmpfiles?

Ich habe einige Dokumente darüber gelesen und schreibe den folgenden Test:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

Ich bin mir aber nicht sicher, denn es systemd-tmpfilesist kein einfaches Programm, sondern ein Stück systemd selbst. Ich möchte mein System nicht kaputt machen.

Irgendwelche Tipps zu einer korrekten .service-Datei?

eang
quelle
Überprüfen Sie die umfangreiche Dokumentation zu systemd unter freedesktop.org/wiki/Software/systemd . Sie können die Standardeinstellungen des Systems durch Ihre eigenen Dateien überschreiben.
Vonbrand

Antworten:

30

[Damit wird das Problem von systemd-tmpfiles nicht direkt angesprochen, aber ich denke, Sie haben bereits erkannt, dass Sie in diesem speziellen Fall besser nur Echo verwenden sollten.]

Zunächst kann "multi-user.target" das sein, was Sie verwenden möchten oder nicht. Wenn Sie mit dem Konzept von Runlevels aus dem Init-Bereich im SysV-Stil vertraut sind, entspricht Multi-User dem System-Äquivalent von Runlevel 3, einem Multi-User-System, das über eine Konsole und nicht über eine GUI gestartet wird. Das Äquivalent von Runlevel 5, das nach X bootet, ist graphical.target . Der Standardwert wird durch einen Symlink in /etc/systemd/system(und / oder /lib/systemd/system; der in /etcüberschreibt den in /lib) namens default.target bestimmt . Verwenden Sie ls, um herauszufinden, wo er verweist:

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

Für normale Linux-Desktops ist dies graphical.target. Dies ist eigentlich nicht wichtig, wenn Sie möchten, dass der von Ihnen erstellte Boot-Service gestartet wird, unabhängig von dem Standard-Runlevel / -Ziel. In diesem Fall können wir nur default.target verwenden und uns keine Gedanken darüber machen, wofür er ein Alias ​​ist. Wenn Sie jedoch mehrere Benutzer verwenden und Ihre Standardeinstellung grafisch ist, wird Ihr Dienst nicht ausgeführt.

Je nach Dienst gibt es möglicherweise geeignetere und spezifischere Ziele oder Dienste, für die Sie diesen starten möchten. Aufgrund Ihrer anderen Frage ist default.target wahrscheinlich in Ordnung. Der Unterschied zwischen einem "Ziel" und einem "Dienst" besteht darin, dass ein Dienst einen [Service]Abschnitt enthält, in dem tatsächlich ein Prozess ausgeführt wird. Ein Ziel ist nur eine Möglichkeit, Dienste über die verschiedenen "Abhängigkeiten" - und "Erfordernis" -Richtlinien zusammenzufassen. Es tut nichts anderes, als andere Ziele oder Dienste auszulösen.

Wann ein Dienst gestartet wird, hängt davon ab, welche anderen Dienste ausdrücklich davon abhängen. Im Fall eines einfachen, eigenständigen Ereignisses wie dieses, das zu einem späten Zeitpunkt des Startvorgangs ausgeführt werden soll, können wir diese Kombination von Anweisungen verwenden:

[Unit]
After=default.target

[Install]
WantedBy=default.target

Der Abschnitt "Installieren" wird verwendet, wenn der Dienst installiert wird. "WantedBy" gibt ein Ziel an, in dem dieser Service enthalten sein soll (das heißt, es wird ausgeführt, wenn dieses Ziel ausgeführt wird, aber nb. Dies bestimmt nicht, wann es im Verhältnis zu anderen ausgeführt wird ). Da wir diesen Dienst lieber später als früher ausführen möchten, geben wir eine "After" -Klausel an. Dies muss nicht unbedingt mit dem WantedBy-Ziel übereinstimmen (dies ist normalerweise nicht der Fall) und kann vollständig weggelassen werden, wenn Sie sich nicht darum kümmern, wann dies geschieht. Ich benutze es nur, um zu vermuten, dass die meisten anderen Dinge in Bezug auf Dinge ausgeführt werden, die irgendwo an etwas angekettet sind, das spezifiziert wurde Before=default.target(was wir auch hätten verwenden können; die Wünsche eines Ziels werden bewertet, bevor das Ziel ausgeführt wird).

Für das Beispiel werde ich einfach "Hallo Welt" an die Konsole senden. Der Dienst selbst wird im [Service]Abschnitt beschrieben:

[Service]
Type=forking
ExecStart=/usr/local/bin/helloworld

Der Befehl benötigt einen vollständigen Pfad. Der Grund, warum ich nicht nur verwendet habe, /usr/bin/echo "hello world"ist, dass es nicht funktioniert (die Ausgabe geht nach / dev / null, glaube ich), und während ein Dienst einen echo "hello world" > /dev/consoleWillen ausführt, zeigen Experimente, dass die Verwendung der Shell-Umleitung in einer ExecStart-Direktive dies nicht tut . / Usr / local / bin / helloworld ist also ein Shell-Skript mit dieser einen Zeile echo "hello world" > /dev/console.

Beachten Sie das Type=forking, was für ein Shell-Skript notwendig ist.

Unsere komplette, minimale Service - Datei ist nur diese drei Abschnitte ( [Unit], [Service], und [Install]). Zum Installieren platzieren Sie die Datei oder einen Symlink dazu entweder in / etc / systemd / system oder / usr / lib / systemd / system und:

systemctl --system enable helloworld

Es sollte drucken ln -s .... Dadurch wird der Dienst nicht ausgeführt. Er wird lediglich so konfiguriert, dass er beim Start ausgeführt wird, wie oben erläutert.

Das ist alles auf den Punkt gebracht. man systemd.unitund man systemd.servicemehr Details haben.

Goldlöckchen
quelle
1
Vielen Dank, sehr nützliche Antwort und Problem gelöst. Nur eine Anmerkung, in meiner Distribution (Chakra Linux) default.targetist es nicht in /etc/systemd/system, aber es ist nur in/usr/lib/systemd/system
eang
Die Ausgabe von Befehlen wird protokolliert (wohin könnte es sonst gehen)?
Vonbrand
Die / usr / lib / systemd / ... -Dateien sind Ausweichdateien (Standard). Sie sollten Ihre Dateien in / etc / systemd / ...
vonbrand am
Diese Tage default.targetkönnen in/lib/systemd/system/default.target
czerasz
1
@czerasz Ich bemerke auf Fedora 27, wenn ich systemctl set-default ...einen Symlink in lasse /etc/systemd/system, aber es ändert sich nicht der eine in /lib, dh sie zeigen auf verschiedene Ziele, aber Sachen in den ersteren sollten den letzteren außer Kraft setzen. Wenn Sie es selbst eingestellt haben, kann das passieren. Jedenfalls habe ich an beiden Orten bearbeitet.
Goldlöckchen
2

Für den systemd-tmpfiles-Dienst: Er sollte mit Ihrer Distribution geliefert werden, aber Sie können die Servicedatei immer aus dem Upstream-Git-Repository abrufen

SimonPe
quelle