So führen Sie ein Linux-Programm beim Start mit systemd aus

Möchten Sie, dass ein Linux-Programm beim Systemstart automatisch ausgeführt wird? Die systemd-Software bietet eine elegante Methode, dies auf jeder Linux-Distribution, die systemd verwendet, zu bewerkstelligen. Dies trifft auf die meisten modernen Distributionen zu, einschließlich Ubuntu. Wir zeigen Ihnen, wie Sie einen eigenen Dienst erstellen, der sich nahtlos in das System integriert und sogar mit dem Journal kommuniziert.

Dieses Tutorial erklärt, wie Sie einen Dienst konfigurieren, der beim Hochfahren Ihres Rechners aktiviert wird. Um hingegen ein grafisches Programm beim Login zu starten, nutzen Sie bitte den Startmanager Ihrer Desktop-Umgebung.

Programme beim Hochfahren starten

Manchmal installieren sich Programme so, dass sie sich in den Startprozess von Linux einklinken und bei jedem Hochfahren automatisch ausgeführt werden. Sie können dieses Verhalten leicht für Ihre eigenen Programme, Skripte oder jede beliebige Software auf Ihrem Rechner nachbilden.

Die beim Start ausgeführten Programme werden von systemd verwaltet, dem System- und Dienstemanager. systemd ist der erste Prozess, der beim Systemstart gestartet wird und hat immer die Prozess-ID (PID) 1. Jeder andere Prozess auf Ihrem Computer wird entweder von systemd direkt oder indirekt durch einen bereits von systemd gestarteten Prozess initiiert.

Programme, die im Hintergrund laufen, werden als Daemons oder Dienste bezeichnet. Das „d“ am Ende von systemd steht für Daemon. In diesem Artikel erstellen wir einen exemplarischen Dienst. Um alle Anforderungen zu erfüllen, soll unser Dienst:

  • Über eine Service-Unit-Datei in systemd integriert sein
  • Beim Systemstart automatisch starten
  • Über systemctl, die Steuerungsschnittstelle für systemd, steuerbar sein
  • In das Journal schreiben können

Das Dienstprogramm entwickeln

Wir benötigen ein Programm, das systemd starten kann. Wir erstellen ein simples Skript namens „htg.sh“. In dieser Anleitung verwenden wir den Texteditor Gedit, Sie können aber jeden beliebigen Editor verwenden.

touch htg.sh
gedit htg.sh

Der Gedit-Editor öffnet sich. Kopieren Sie den nachfolgenden Text und fügen Sie ihn ein:

#!/bin/bash

echo "htg.service: ## Starting ##" | systemd-cat -p info

while :
do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "htg.service: timestamp ${TIMESTAMP}" | systemd-cat -p info
sleep 60
done

Speichern Sie die Änderungen und schließen Sie den Editor.

Das Skript ist bewusst einfach gehalten, jedoch gibt es einige Punkte, die Erwähnung verdienen:

  • Die beiden Echo-Befehle werden über `systemd-cat` an das Journal weitergeleitet, ein Programm, das die Ausgabe eines Programms entgegennimmt und an das Journal schickt. Einträge im Journal sind priorisiert. Mit der Option `-p` (Priorität) legen wir fest, dass unsere Nachrichten den Informationslevel (info) haben und keine wichtigen Fehler oder Warnungen sind.
  • Es gibt eine endlose `while`-Schleife.
  • Die Variable `TIMESTAMP` wird mit dem aktuellen Datum und der aktuellen Uhrzeit belegt. Diese wird dann in einer formatierten Meldung an das Journal geschickt.
  • Das Skript pausiert anschließend für 60 Sekunden.
  • Nach 60 Sekunden wiederholt sich die Schleife. Somit protokolliert das Skript jede Minute eine Meldung mit Zeitstempel im Journal.

Wir kopieren das Skript in das Verzeichnis `/usr/local/bin`:

sudo cp htg.sh /usr/local/bin

Und wir machen es ausführbar:

sudo chmod +x /usr/local/bin/htg.sh

Erstellung der Service-Unit-Datei

Jedes Programm, das von systemd gestartet wird, hat eine zugeordnete Definitionsdatei, die Service-Unit-Datei genannt wird. Diese Datei enthält Attribute, die systemd verwendet, um das Programm zu finden, zu starten und sein Verhalten festzulegen.

Wir müssen eine Unit-Datei für unseren Dienst erstellen. Es ist aber ratsam, zuerst zu prüfen, dass keine bestehenden Unit-Dateien den gleichen Namen haben, den wir unserem neuen Dienst geben möchten.

sudo systemctl list-unit-files --type-service

Durchblättern Sie die alphabetisch sortierte Liste der Unit-Dateien und suchen Sie nach Duplikaten.

Unser Dienst wird „htg.service“ heißen. Es gibt keine Unit-Dateien mit diesem Namen, also können wir fortfahren.

sudo gedit /etc/systemd/system/htg.service

Der Gedit-Editor öffnet sich. Kopieren Sie den folgenden Text und fügen Sie ihn ein:

[Unit]
Description=etoppc.com Service Example

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/htg.sh
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

Speichern Sie die Änderungen und schließen Sie den Editor.

Die Einträge haben folgende Bedeutungen. Dies sind typische Einträge. Unser einfacher Dienst benötigt die meisten nicht wirklich, aber sie mit einzubeziehen erlaubt uns, sie zu erklären:

  • Beschreibung: Dies ist eine Textbeschreibung Ihres Dienstes.
  • Wants: Unser Dienst *möchte*, aber es ist nicht zwingend notwendig, dass das Netzwerk aktiv ist, bevor unser Dienst gestartet wird.
  • Nachher: Eine Liste von Unit-Namen, die gestartet werden *sollen*, nachdem dieser Dienst erfolgreich gestartet wurde, falls sie noch nicht aktiv sind.
  • Typ: Einfach. systemd betrachtet diesen Dienst als gestartet, sobald der durch `ExecStart` angegebene Prozess abgeteilt wurde.
  • ExecStart: Der Pfad zu dem Prozess, der gestartet werden soll.
  • Neustart: Wann und ob der Dienst neu gestartet werden soll. Wir haben dies auf „bei Fehler“ gesetzt.
  • RestartSec: Wie lange gewartet werden soll, bevor versucht wird, den Dienst neu zu starten. Der Wert wird in Sekunden angegeben.
  • KillMode: Definiert, wie systemd den Prozess beenden soll, wenn wir systemctl bitten, den Dienst zu stoppen. Wir haben dies auf „process“ gesetzt. Dies führt dazu, dass systemd das `SIGTERM`-Signal nur für den Hauptprozess verwendet. Wenn unser Dienst ein komplexeres Programm anstatt eines einfachen Skripts wäre, würden wir „mixed“ setzen, um sicherzustellen, dass alle erzeugten Prozesse beendet werden.
  • WantedBy: Wir haben dies auf „multi-user.target“ gesetzt. Dies bedeutet, dass der Dienst gestartet werden sollte, sobald sich das System in einem Zustand befindet, in dem sich mehrere Benutzer anmelden können, egal ob eine grafische Benutzeroberfläche verfügbar ist oder nicht.

Die Unit-Datei muss nicht ausführbar sein, aber die Zugriffsrechte sollten einschränken, wer die Datei verändern kann. Sie möchten nicht, dass ein böswilliger Benutzer die Unit-Datei so verändert, dass ein anderes Programm ausgeführt wird.

Dieser Befehl gibt dem Besitzer Lese- und Schreibrechte sowie Leserechte für die Gruppe. Andere haben keine Rechte.

sudo chmod 640 /etc/systemd/system/htg.service

Wir können systemctl die Syntax unserer Unit-Datei prüfen lassen, auch wenn der Dienst noch nicht aktiv ist. Eventuelle Fehler werden angezeigt. (Eigentlich ist der Teil „.service“ für die meisten Befehle optional.)

systemctl status htg.service

Es werden keine Fehler gemeldet. Das bedeutet, dass unsere Unit-Datei syntaktisch korrekt ist.

Den Dienst starten

Nach dem Hinzufügen oder Ändern einer Unit-Datei muss systemd aufgefordert werden, die Unit-Datei-Definitionen neu zu laden.

sudo systemctl daemon-reload

Wenn ein Dienst beim Start automatisch geladen werden soll, muss er aktiviert werden:

sudo systemctl enable htg

Das Aktivieren eines Dienstes startet diesen nicht sofort. Es legt den Dienst nur so fest, dass er beim Hochfahren aktiviert wird. Um den Dienst jetzt zu starten, nutzen Sie systemctl mit der Option start.

sudo systemctl start htg

Überprüfung des Dienstes

Nachdem der Dienst manuell gestartet wurde oder nach einem Neustart des Rechners, können wir überprüfen, ob unser Dienst ordnungsgemäß ausgeführt wird.

sudo systemctl status htg.service

Der Status des Dienstes wird angezeigt.

Der grüne Punkt zeigt, dass der Dienst ordnungsgemäß funktioniert.
Der Name des Dienstes ist „htg.service“, und die lange Beschreibung entspricht der, die wir in der Unit-Datei angegeben haben.
Es wird gezeigt, welche Unit-Datei geladen wurde: „/etc/systemd/system/htg.service“.
Der Dienst ist aktiv, und die Startzeit wird angezeigt.
Die PID lautet 7762.
Dem Dienst sind zwei Aufgaben zugeordnet.
Insgesamt werden 928 Kibibyte Speicher vom Dienst verwendet.
Die Kontrollgruppe umfasst das Skript „htg.sh“ und den `sleep`-Befehl, der von „htg.sh“ gestartet wurde. Meistens erledigt der `sleep`-Befehl die Hauptarbeit für diesen Dienst.

Außerdem werden die letzten 10 Journaleinträge dieses Dienstes angezeigt. Es ist wenig überraschend, dass die Einträge im Minutentakt erfolgen.

Dienst stoppen und deaktivieren

Wenn Sie den Dienst stoppen müssen, verwenden Sie folgenden Befehl:

sudo systemctl stop htg.service

Dieser Befehl stoppt den Dienst, verhindert aber nicht, dass er beim nächsten Neustart automatisch wieder gestartet wird. Um zu verhindern, dass der Dienst beim Start aktiv wird, muss er deaktiviert werden:

sudo systemctl disable htg.service

Dieser Befehl stoppt den Dienst nicht, falls er bereits läuft. Er weist systemd nur an, den Dienst beim nächsten Neustart nicht zu starten.

Wenn Sie den Dienst stoppen und verhindern möchten, dass er automatisch beim Start hochfährt, verwenden Sie beide Befehle.

Service-Tipp

Stellen Sie sicher, dass Ihr Programm wie erwartet funktioniert, bevor Sie es als Dienst konfigurieren.