Allgemein | Hermann Apfelböck | 5/2025 | 25. Juli 2025

Systemd in der Praxis

In den meisten aktuellen Linux-Distributionen arbeitet Systemd als primärer Prozess mit der PID „1“ als Boss aller nachfolgenden Systemdienste. Dieser Heftschwerpunkt erläutert Werkzeuge und Techniken dieses Init-Prozesses mit umfassendem Anspruch.

In den meisten aktuellen Linux-Distributionen arbeitet Systemd als primärer Prozess mit der PID „1“ als Boss aller nachfolgenden Systemdienste. Dieser Heftschwerpunkt erläutert Werkzeuge und Techniken dieses Init-Prozesses mit umfassendem Anspruch.

Ein Heftspecial mit 12 Seiten zu Systemd ist ein fragwürdiges Unternehmen: Einerseits ist der Umfang zu schmal, um Konzept, Umfang, Konfigurationsdetails und Werkzeuge auch nur anzudeuten. Andererseits ist der Umfang beträchtlich, wenn man bedenkt, dass Systemd oft nur als Paralleluniversum nebenherläuft. Tatsächlich besteht für Desktopnutzer, die sich in der Fstab wohlfühlen, keine Notwendigkeit, sich mit Mount-Units von Systemd zu beschäftigen. Genau dieses Beispiel zeigt aber, dass sich das Paralleluniversum immer mehr ausbreitet: Die Fstab ist nämlich nur noch freundliche „Legacy“-Kompatibilität von Systemd, das diesen Altbestand einliest und in seine Mount-Units übersetzt. Langfristig werden sich die Methoden von Systemd auch beim Endanwender durchsetzen, sobald quantitativ mehr Anleitungen zu Systemd-Mounts als zur Fstab existieren, mehr zum System-Timer als zu Crontab, mehr zu Systemctl statt zum Tool service, mehr zu Networkctl statt zu Tools wie ip oder vnstat …

Der Init-Daemon Systemd

Die Reichweite des Systemd-Konzepts und die damit einhergehenden Chancen einer Standardisierung von Linux-Systemen sind unbestritten. Systemd hat aber Vorgänger wie Sysvinit und Upstart als Init-Daemon insbesondere deshalb abgelöst, weil er durch Parallelisierung der frühen Startprozesse für schnellere Bootzeiten sorgt. Die Aufgabe des Init-Prozesses ist schnell erklärt: Beim Start der Hardware lädt der Bootloader den Linux-Kernel. Der Kernel startet dann den Init-Prozess aus dem Pfad „/sbin/init“, der die Prozess-ID „1“ erhält. Welches Init-System bei einer Linux-Distribution aktiv ist, erfahren Sie daher am einfachsten durch eine Frage nach Prozess „1“:

cat /proc/1/comm

Die Ausgabe wird in der Regel „systemd“ lauten. Dieser Init-Prozess lädt dann alle erforderlichen Systemdienste, Dateisysteme, Timer. Nachdem Systemd die volle Kontrolle und Übersicht hat, ist es die logische Konsequenz, dass es deren Verwaltung übernehmen muss. Und das macht Systemd umfassend und gründlich. Als wichtigste Benutzerschnittstelle dient das Tool Systemctl, um das es in diesem ersten Artikel ausschließlich gehen soll. Es öffnet nämlich den Zugang zum kompletten Systemd-Kosmos mit seinen diversen Unit-Klassen.

Systemctl und die Systemd-Units

Systemctl wird oft als „Dienste-Manager“ bezeichnet. Das ist zwar wahrscheinlich der häufigste Einsatzzweck, unterschlägt aber, dass Systemctl sämtliche Systemd-Units verwaltet. Dienste, also die Klasse „Service“, ist nur eine dieser Klassen (siehe Tabelle „Systemd: Die Unit-Klassen“). Das einfachste Kommando

systemctl

ohne weitere Filter ist eine Abkürzung für

systemctl list-units

und zeigt alle aktuell aktiven Systemd-Units. In der Regel wird man die Liste zwecks besserer Übersicht auf eine bestimmte Unit-Klasse wie „service“ filtern. Ob hilfreich oder am Ende doch eher verwirrend, liefern alle folgenden Syntaxvarianten exakt dasselbe Resultat:

systemctl list-units --type=service
systemctl --type=service
systemctl -t service

Das Ergebnis ist die Prozessliste aller aktuell geladenen Systemdienste.

Eine anders geartete Abfrage richtet sich an die Systemd-Konfigurationsdateien. Der Befehl

systemctl list-unit-files 
-t service

liefert sämtliche Dienstekonfigurationen aus, die auf dem System vorliegen. Das ist vor allem relevant, um eine schnelle Übersicht über Änderungen aller Art zu ermitteln. Abgeschaltete oder ganz deaktivierte Units erscheinen hier nämlich mit roter Signalfarbe als „disabled“ oder „masked“. Wenn man will, kann man nach solchen Units mit

systemctl list-unit-files 
-t service –-state=disabled

oder „–state=masked“ noch zielgenauer fahnden.

Systemctl ändert Prozesseigenschaften: Das Erstellen der Änderungsdatei ist etwas fummelig, aber um Dateipfade und Abgleich mit der Originaldatei kümmert sich Systemd.
Automount (*.automount)dynamische Dateisystem-Mounts
Device (*.device)Vermittlungsschicht zwischen Hardware und Systemd
Mount (*.mount) statische Dateisystem-Mounts
Path (*.path)Ordnerüberwachung
Scope (*.scope)Anwendungsprogramme als Systemd-Prozesse
Service (*.service)Systemdienste (snapd, ssh, gdm, apache2 etc.)
Snapshot (*.snapshot)Systemd-Sicherungsfunktion (fehlt meistens)
Slice (*.slice)Ressourcensteuerung für Prozessgruppen (user, system)
Socket (*.socket)Netzwerküberwachung und Servicestarts bei Ereignis
Swap (swapfile.swap)Kontrolle und Steuerung
der Auslagerungsdatei
Target (*target)Unit-Sammlungen für
definierte Systemzustände
Timer (*.timer)Zeitsteuerung für Dienste und Autostarts
Pfade der Unit-Scripts
/etc/systemd/system/benutzerdefinierte Units oder Anpassungen (priorisiert)
/lib/systemd/system/Systemstandards
/usr/lib/systemd/system/ Systemstandards

Unit-„Properties“ anzeigen und steuern

Systemctl kann Units nicht nur anzeigen, starten und stoppen (siehe unten), sondern auch im Detail verändern und umkonfigurieren. Der Unterbefehl „show“ von Systemctl (Beispiel)

systemctl show ssh.service

zeigt alle Eigenschaften der angesprochenen Unit – zumeist ziemlich viele, sodass sich oft eine Sortierung (sort) oder ein Grep-Filter empfiehlt:

systemctl show ssh.service 
| grep -i "cpu"

Der aktive Befehl (Beispiel)

systemctl set-property ssh.service CPUWeight=20

kann dann die Eigenschaften interaktiv und für die laufende Sitzung ändern. Ein weiteres Beispiel für Ressourcensteuerung ist unten im Abschnitt „Die Slice-Units“ skizziert. Neben der dort gezeigten CPU-Begrenzung mit „CPUQuota=20%“ gibt es weitere interessante Eigenschaften wie „MemoryMax=500M“ (Limitierung von Services oder Slices) oder „IOWeight=500“ (Standard ist „100“, Maximum ist „1000“ – relevant etwa für die Webserver-Optimierung).

„Property“-Änderungen dauerhaft speichern: Eingriffe mit systemctl set-property gelten sofort, allerdings nur bis zum nächsten Neustart des Dienstes oder des Systems (transient). Dauerhafte Einstellungen benötigen ein korrigierendes „Drop-In-File“. Diese Dateien haben den Vorteil, dass die Originale unter „/usr/lib/systemd/system/“ stets unverändert bleiben (wichtig bei Systemupdates). Erfreulicherweise muss man sich um den korrekten Namen und Speicherort solcher Dateien nicht kümmern, weil Systemctl das nach (Beispiel)

sudo systemctl edit user.slice

selbst am besten weiß. Vorbereitend ist es aber immer zu empfehlen, vorher die gewünschte Änderung mit systemctl set-property interaktiv zu testen. Dabei werden nämlich falsch geschriebene Propertys oder ungültige Werteangaben automatisch abgelehnt. Korrekte, interaktiv angeforderte Änderungen erscheinen hingegen am Ende der Datei, die man danach mit systemctl edit öffnet. Die Property-Angabe am Dateiende kann man aber nicht einfach (und naheliegend) durch Entfernen des Kommentarzeichens (#) aktiv schalten. Sie muss vielmehr nach oben in Zeile 3 oder 4 kopiert werden – vor die Zeile „Edits below […] will be discarded“.

Nach dem Speichern der Datei, die dann
„/etc/systemd/system/[name].d/override.conf“ lauten wird, kann die Aktion mit

sudo systemctl daemon-reload
sudo systemctl restart [Name].service

permanent gesetzt werden – dies zumindest für Service- oder Timer-Units. Für andere Units ist ein Neustart erforderlich.

Die Unit-Klasse „Service“

An der Verwaltung mit Systemdiensten kommt kein Linux-Nutzer vorbei, der zumindest den einen oder anderen Netzwerkdienst wie SSH oder Apache laufen hat. Die wichtigsten Befehle lauten wie folgt (am Beispiel SSH):

systemctl status ssh.service
systemctl stop ssh.service
systemctl start ssh.service
systemctl restart ssh.service

Diese Kommandos funktionieren auch ohne explizite Unit-Bezeichnung:

systemctl stop ssh

„stop“ und „start“ oder einfacher „restart“ sind alltägliche Aktionen, wenn ein Dienst wie Apache, SSH oder Samba eine manuelle Konfigurationsänderung neu einlesen soll. Zum dauerhaften Abschalten eines Dienstes gibt es die folgenden Kommandos:

systemctl disable ssh
systemctl mask ssh

„disable“ deaktiviert einen Dienst an sich dauerhaft, verhindert aber nicht, dass diesen ein anderer Systemdienst unter der Haube neu aktiviert. Erst der „mask“-Befehl macht auch dieses unmöglich und deaktiviert einen Dienst nachhaltig. Dies kann bei Bedarf nur der Systemadministrator (also Sie) mit

systemctl unmask ssh
systemctl start ssh

wieder rückgängig machen.

Ein Eingriff in Systemdienste, vor allem aber das Abschalten von Diensten, ist stets heikel, aber Systemctl kann das nicht nur erledigen, sondern bietet auch gute Kontrolle darüber, was auf dem System verändert wurde. Eine gut lesbare Übersicht mit farbigen Markierungen („disabled“ rot, „enabled“ grün) liefert der folgende Befehl, der nicht die Dienste, sondern die darunterliegenden Konfigurationsdateien abfragt:

systemctl list-unit-files 
-t service

Zusätzlich zur Farbmarkierung erscheint in der rechten Spalte die Distributionsvorgabe als „Preset“ oder „Vendor Preset“. Somit erkennt man die Vorgaben der Distribution und was am System manuell geändert wurde. Beachten Sie bei dieser Ausgabe der Unit-Dateien auch den Statuseintrag „static“. Die damit ausgezeichneten Dienste sind systemrelevant und lassen sich nicht deaktivieren.

Die Statusabfrage einer Unit macht unter anderem sofort ersichtlich, ob deren Konfiguration geändert wurde („Drop-in“).

Die Unit-Klasse „Target“

Systemd-Targets sind keine aktiven Prozesse, sondern definierte Sammlungen von Device-, Service-, Mount-, Path- und Timer-Units, die dann in der Summe einen bestimmten Systemzustand erzielen. Dieser Zustand kann maximal (graphical.target) oder minimal ausfallen (etwa rescue.target). Solche Unit-Kombinationen kann man mit einem einzigen Kommando neu definieren oder ab dem nächsten Systemstart als Standard vorgeben.

Um alle vordefinierten Targets aufzulisten, ist dieser Befehl geeignet:

systemctl -t target

Hier erscheinen dann unter anderem „basic“, „emergency“, „graphical“, „multi-user“, „rescue“ oder „shutdown“. Welche Unit-Sammlung ein Target konkret enthält, ist auf Dateiebene („/lib/systemd/system“) schwer zu ermitteln, weil Target-Konfigurationsdateien nur die speziellen Units des Targets direkt auflisten und ansonsten auf integrierte Targets verweisen. Der Befehl

systemctl list-dependencies
basic.target

macht das anschaulicher.

Der praktische Einsatz dieser Targets sieht so aus, dass man mit einem einzigen „isolate“-Befehl alles abschalten kann, was nicht in der Unit-Sammlung des angesprochenen Targets enthalten ist. Der am Desktop gestartete Befehl

sudo systemctl isolate rescue.target

führt sofort in die Wiederherstellungskonsole. Was immer am System läuft oder noch nicht gespeichert ist, wird weggeschossen. Zurück zur Anmeldung geht’s mit Strg-D (Abbruch der Konsole) oder mit diesem Befehl:

sudo systemctl isolate graphical.target

Die Aktion „isolate“ ist nicht für jedes Target erlaubt. Verantwortlich dafür ist die Eigenschaft „AllowIsolate“ der Target-Unit.

Dauerhaftes Umschalten: Was der Unterbefehl „isolate“ interaktiv ausführt, kann „set-default“ ab dem nächsten Systemstart dauerhaft als Standard setzen. Dafür kommen aber nur zwei Targets ernsthaft in Betracht – das umfangreichste „graphical.target“ und das Target „multi-user.target“ für Server ohne Desktop. Der Wechsel dieser beiden Targets ist vor allem für Platinenrechner interessant. Dort ist es typisch, dass der Desktop zwar zur ersten Einrichtung willkommen, danach aber überflüssig ist. Wer nur noch die Serverdienste braucht (Samba, SSH, Apache), kann mit

sudo systemctl set-default multi-user.target

die Oberfläche abschalten. Mit

sudo systemctl set-default graphical.target

ist der Desktop wieder zu aktivieren.

Achtung: Anders als bei „isolate“ ist Systemd beim Setzen des Default-Targets indifferent. Wenn Sie mit

sudo systemctl set-default rescue.target

die Wiederherstellungskonsole zum Systemstandard machen, sehen Sie den Desktop erst mal nicht wieder, solange Sie auf der Notfallkonsole nicht wieder das „graphical.target“ als Standard setzen. Auch destruktive Aktionen sind nicht untersagt. Nach

sudo systemctl set-default basic.target

geht gar nichts mehr. Aber da das Grub-Menü über „Erweiterte Optionen“ und den „Recovery Mode“ das rescue.target einschalten kann, gibt es von hier über die root-Konsole und

systemctl set-default graphical.target

wieder einen Weg zurück.

Listen und KontrolleErklärung
systemctl [list-units]
Liste aller geladenen Units
systemctl [list-units] -allListe aller geladenen Units (auch inaktive)
systemctl -t service Liste geladener Units einer bestimmten Klasse
systemctl -t service –allListe geladener Units einer bestimmten Klasse (auch inaktive)
systemctl list-dependencies ssh.servicealle Abhängigkeiten einer Unit anzeigen
systemctl list-unit-fileskeine Prozessliste: Liste der Systemd-Konfigurationsdateien
systemctl list-unit-files -t servicekeine Prozessliste: Konfigurationsdateien einer bestimmten Klasse
Unit-Steuerung (am Beispiel SSH)
systemctl status ssh.serviceStatusabfrage
systemctl start ssh.serviceDienst starten
systemctl stop ssh.serviceDienst starten
systemctl restart ssh.serviceDienst-Neustart nach Konfigurationsänderung
systemctl disable ssh.serviceDienst deaktivieren
systemctl enable ssh.serviceDienst aktivieren
systemctl mask ssh.serviceDienst endgültig verbergen
systemctl unmask ssh.serviceverborgenen Dienst wieder aktivieren
Unit-Änderungen (am Beispiel user.slice)
systemctl show user.sliceEigenschaften einer Unit auflisten
systemctl set-property user.slice CPUQuota=50%Eigenschaft einer Unit interaktiv (sofort) ändern
systemctl edit user.sliceEigenschaft einer Unit dauerhaft ändern
systemctl revert user.sliceÄnderungen an einer Unit wieder löschen
systemctl preset user.sliceUnit-Konfiguration auf Distributionsstandard setzen
systemctl preset-all (VORSICHT!)komplettes Zurücksetzen auf Distributionsstandard
Spezielle Befehle für Targets
systemctl -t targetListe aktiver Target-Units
systemctl get-defaultStandard-Target ermitteln
systemctl set-default graphical.targetStandard-Target setzen
systemctl isolate rescue (VORSICHT!)interaktiv (sofort) Target wechseln
Generelle Systemkommandos
systemctl daemon-reloadNeustart von Systemd (nach Änderungen)

Die Unit-Klasse „Slice“

Slices sind Sammlungen aktiver Prozesse, die zu einer Verwaltungseinheit gebündelt werden (auf der Basis von Linux-Control-Groups). Das klingt verkopft, eröffnet aber in der Praxis großes Optimierungspotenzial. Die Nachfrage mit

systemctl -t slice

wird eine Reihe von Slice-Units anzeigen, unter anderem je eine Slice („Scheibe“) für jedes Benutzerkonto. Die Eigenschaften sind dann wie auch sonst mit

systemctl show user-1000.slice

zu erfragen. Daher können Ressourcenlimits auf Slice-Ebene gesetzt werden, die alle darin enthaltenen Prozesse begrenzen:

sudo systemctl set-property user-1000.slice CPUQuota=20%

Der Befehl muss tatsächlich so lauten, obwohl die Eigenschaft eigentlich „CPUQuotaPerSecUSec“ heißt. Auf einem Serversystem mit bescheidener Hardware könnte man daher nicht nur einen einzelnen Benutzer, sondern die komplette User-Scheibe mit

sudo systemctl set-property user.slice CPUQuota=20%

deutlich limitieren, um die Systemdienste zu priorisieren.

Interaktiv, sofort und gravierend: Limitierende Eingriffe in die Ressourcenverteilung von Slice-Units sind unmittelbar spürbar (hier für Konto-UID 1001).

Die Unit-Klasse „Scope“

Die Klasse der Scopes („Erweiterungen“) ist technisch interessant, aber für die meisten Nutzer wahrscheinlich zu akademisch. Es geht darum, beliebige externe Programme (etwa Browser oder Bildbearbeitung) in die Systemd-Verwaltung zu integrieren. Das ist nur interaktiv und temporär während einer Sitzung möglich und benötigt den Befehl „systemd-run“. Der gehört eigentlich in den nachfolgenden Beitrag („Die Armee der Systemd-Tools“), ist aber hier notwendig, um die Scope-Klasse zu erklären. Nachdem eine temporäre Scope-Unit mit

systemd-run --scope --unit=ff.scope /usr/bin/firefox

erstellt ist, lassen sich

systemctl show ff.scope

die Eigenschaften wie bei Systemd-Prozessen abfragen und mit

systemctl set-property ff.scope MemoryLimit=400M

auch nach Bedarf steuern.

Weitere Units: Timer, Path & mehr

Systemd kennt eine Reihe weiterer Unit-Klassen wie Device, Mount, Path, Timer, Snapshot, Socket. Praxisrelevante Optionen dazu kommen im dritten Beitrag dieses Specials noch zu Wort. Dieser Artikel zeigt Beispiele, wie man eigene Dienste anlegt und wie die dafür nötigen Konfigurationsdateien strukturiert sind. Für Anwender kaum ergiebig sind die Klassen Device, Snapshot und Swap. Für Swap (Auslagerungsdatei) bleibt Systemctl auf die übliche „status“-Abfrage mit

systemctl status swapfile.swap

beschränkt, die Pfad und aktuelle/maximale Größe der Datei anzeigt, ferner kann mit

sudo systemctl stop swapfile.swap

das Swapping interaktiv abgeschaltet, mit „start“ wieder aktiviert werden. Weitere Zugriffe mit „enable“ und „disable“ (dauerhaft abschalten) funktionieren auf vielen Systemen nicht.

Die Unit-Klasse Snapshot fehlt bei der Mehrzahl der Distributionen. Es handelt sich um eine interne Systemd-Sicherungsfunktion (etwa sudo systemctl snapshot 2025_Juni), die den Systemd-Zustand speichert und später mit „isolate“ restauriert.