EK Knowledge

Ubuntu/Debian

systemd-Unit-Dateien

Eine systemd-Unit-Datei ist eine Konfigurationsdatei im INI-ähnlichen Format. Sie legt fest, wie systemd eine Ressource verwaltet. Bei einer Service-Datei (.service) wird beispielsweise konfiguriert, wie ein Dienst gestartet, ausgeführt und beendet wird.

1. Speicherorte

Systemd-Unit-Dateien befinden sich je nach Herkunft und Verwendungszweck in unterschiedlichen Verzeichnissen.

  • /etc/systemd/system/ – für eigene Unit-Dateien und lokale Anpassungen.
  • /usr/lib/systemd/system/ – für Unit-Dateien, die vom System oder von installierten Paketen bereitgestellt werden. Auf älteren Systemen kann dieser Pfad auch /lib/systemd/system/ lauten.

Eigene Service-Dateien sollten vorzugsweise unter /etc/systemd/system/ abgelegt werden.

2. Grundlegender Aufbau

Eine typische Service-Datei sieht beispielsweise so aus:

[Unit]
Description=My Own Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/my-own-service
Restart=on-failure

[Install]
WantedBy=multi-user.target

Eine Unit-Datei besteht aus Abschnitten, deren Namen in eckigen Klammern stehen. Jede Konfigurationsoption gehört zu einem bestimmten Abschnitt.

Abschnitt Zweck
[Unit] Allgemeine Beschreibung, Abhängigkeiten und Startreihenfolge
[Service] Ausführung und Überwachung des Dienstes
[Install] Festlegung, wie der Dienst beim Aktivieren eingebunden wird

Nicht jede Unit-Datei benötigt alle drei Abschnitte. Welche Abschnitte zulässig sind, hängt vom Unit-Typ ab.

3. Syntax der Einträge

Ein Eintrag besteht normalerweise aus einem Schlüssel, einem Gleichheitszeichen und einem Wert:

Schlüssel=Wert

Beispiele:

Description=My Own Service
Restart=on-failure

Dabei gelten folgende Regeln:

  • Groß- und Kleinschreibung: Optionsnamen müssen in der vorgesehenen Schreibweise angegeben werden, beispielsweise ExecStart=.
  • Leerzeilen: Können zur besseren Lesbarkeit verwendet werden.
  • Kommentare: Zeilen, die mit # oder ; beginnen, sind Kommentare.
  • Werte: Die Behandlung von Leerzeichen, Anführungszeichen und Sonderzeichen hängt von der jeweiligen Option und den Syntaxregeln ab.
  • Abschnitte: Eine Option gehört zu dem Abschnitt, in dem sie definiert ist. Abschnittsnamen stehen in eckigen Klammern.

Beispiel mit Kommentaren:

[Service]
# Command to start the service
ExecStart=/usr/local/bin/my-own-service

# Restart the service if it fails
Restart=on-failure

4. Abschnitt [Unit]

Dieser Abschnitt enthält allgemeine Informationen über die Unit sowie ihre Abhängigkeiten und Startreihenfolge.

Option Bedeutung
Description= Beschreibung der Unit
After= Legt die Startreihenfolge gegenüber anderen Units fest
Before= Legt fest, dass diese Unit vor einer anderen gestartet werden soll
Requires= Definiert eine Abhängigkeit von anderen Units
Wants= Definiert eine schwächere Abhängigkeit

Wichtig: After=network.target garantiert nicht, dass eine Netzwerkverbindung verfügbar ist. Die Option legt lediglich die Reihenfolge des Starts fest. Abhängigkeiten und Startreihenfolge sind unterschiedliche Dinge.

5. Abschnitt [Service]

Dieser Abschnitt legt fest, wie der Dienst ausgeführt und überwacht wird.

Option Bedeutung
Type= Legt fest, wie systemd den Start des Dienstes bewertet
ExecStart= Auszuführender Startbefehl
ExecStartPre= Befehl, der vor dem Start ausgeführt wird
ExecStartPost= Befehl, der nach dem erfolgreichen Start ausgeführt wird
ExecStop= Befehl zum Beenden des Dienstes
Restart= Legt fest, unter welchen Bedingungen der Dienst neu gestartet wird
User= Benutzer, unter dem der Dienst ausgeführt wird
WorkingDirectory= Arbeitsverzeichnis des Dienstes
Environment= Setzt Umgebungsvariablen
Häufig verwendete Werte für Type=
  • simple – der Dienst wird als gestartet betrachtet, sobald sein Prozess gestartet wurde.
  • exec – der Dienst wird als gestartet betrachtet, sobald der konfigurierte Prozess erfolgreich ausgeführt wurde.
  • forking – für Programme, die sich beim Start in den Hintergrund abspalten.
  • oneshot – für Aufgaben, die ausgeführt werden und anschließend enden.
  • notify – für Programme, die systemd ihre Bereitschaft ausdrücklich mitteilen.
  • idle – verzögert die Ausführung, bis andere Startaufträge abgeschlossen sind.

Für viele einfache Dienste ist simple oder exec geeignet. Welche Variante sinnvoll ist, hängt vom jeweiligen Programm und der verwendeten systemd-Version ab.

Häufig verwendete Werte für Restart=
  • no – kein automatischer Neustart.
  • on-failure – Neustart bei einem Fehler.
  • on-abnormal – Neustart bei einem abnormalen Ende, beispielsweise durch ein nicht abgefangenes Signal.
  • always – Neustart unabhängig davon, ob der Prozess erfolgreich oder fehlerhaft beendet wurde.

6. Abschnitt [Install]

Dieser Abschnitt beschreibt, wie eine Unit beim Aktivieren mit systemctl enable eingebunden wird.

Option Bedeutung
WantedBy= Definiert das Ziel, in dessen Abhängigkeitsstruktur die Unit beim Aktivieren eingebunden wird
RequiredBy= Definiert ein Ziel, das beim Aktivieren eine stärkere Abhängigkeit von der Unit erhält
Alias= Definiert zusätzliche Namen für die Unit

Ein häufig verwendeter Eintrag ist:

[Install]
WantedBy=multi-user.target

Damit wird der Dienst beim Aktivieren standardmäßig in die Startabhängigkeiten von multi-user.target eingebunden.

Der Abschnitt [Install] wird nicht bei jedem Start ausgewertet. systemctl enable verwendet ihn, um die entsprechenden symbolischen Links anzulegen.

7. ExecStart= ist keine Shell

Ein häufiger Fehler besteht darin, anzunehmen, dass systemd den Inhalt von ExecStart= automatisch durch eine Shell ausführen lässt.

Folgendes Beispiel führt nicht automatisch eine Shell-Pipeline aus:

ExecStart=/usr/bin/command1 | /usr/bin/command2

Das Pipe-Zeichen | wird hier nicht als Shell-Operator interpretiert. Auch Umleitungen wie > und die Hintergrundausführung mit & funktionieren nicht wie in einer Shell.

Wenn eine Shell benötigt wird, muss sie explizit aufgerufen werden:

ExecStart=/bin/sh -c 'command1 | command2'

Die Shell interpretiert in diesem Fall die Pipeline.

8. Unit-Dateien prüfen und Änderungen einlesen

Konfiguration überprüfen

Mit systemd-analyze verify kann eine Unit-Datei auf syntaktische und weitere Konfigurationsfehler geprüft werden:

systemd-analyze verify /etc/systemd/system/my-own-service.service
Änderungen einlesen

Nach dem Erstellen einer neuen Unit-Datei oder nach Änderungen an einer bestehenden Datei muss systemd die Konfiguration neu einlesen:

systemctl daemon-reload
Dienst starten
systemctl start my-own-service
Dienststatus anzeigen
systemctl status my-own-service
Automatischen Start aktivieren
systemctl enable my-own-service
Dienst starten und automatischen Start aktivieren
systemctl enable --now my-own-service

9. Offizielle Dokumentation