Regelmäßige Aufgaben mit Systemd anstoßen

Aus LinuxUser 07/2018

Regelmäßige Aufgaben mit Systemd anstoßen

© olegdudko, 123RF

Eingebauter Wecker

Systemd startet bei Bedarf Timer, die wiederum zu vorgegebenen Zeiten automatisch Aufgaben ausführen. Die Einrichtung erfolgt dabei über Timer Units genannte Konfigurationsdateien.

Mitunter soll ein Linux-System jeden Abend automatisch ein Backup erstellen und in regelmäßigen Abständen die Logfiles rotieren. Um solche zeitgesteuerten Aufgaben kümmert sich in den meisten Distributionen der im Hintergrund laufende Dienst Cron. Eine interessante Alternative stellt mittlerweile die Software Systemd, die eigentlich den Startvorgang der meisten Distributionen kontrolliert: Auch sie kann zeitgesteuert und wiederholt Aufgaben anstoßen. Die Einrichtung erfolgt dabei in zwei Schritten.

Dienstleister

Zunächst müssen Sie Systemd mitteilen, welche Aufgabe es ausführen soll. Dazu erstellen Sie eine entsprechende Konfigurationsdatei, die sogenannte Service Unit. Ein Beispiel zeigt Listing 1.

Eine Service Unit besteht aus einer Textdatei und gliedert sich in mehrere Abschnitte. Zumindest existieren muss der Abschnitt [Service]. Dort steht hinter ExecStart= das von Systemd auszuführende Kommando. In Listing 1 würde Systemd einfach ein Skript starten, das ein Backup des Systems im Verzeichnis /mnt ablegt. Der Abschnitt [Unit] ergänzt noch ein paar Metadaten. Im einfachsten Fall steht hinter Description= eine Beschreibung der zu erledigenden Aufgabe.

Listing 1

[Unit]
Description=Erstelle ein Backup des Systems
[Service]
ExecStart=/usr/bin/backup.sh /mnt

Service Units teilen Systemd normalerweise mit, welche Dienste es beim Systemstart hochfahren soll. Systemd kennt deshalb noch weitere Abschnitte und Einstellungen. Da Systemd die Aufgabe gleich zeitgesteuert aufrufen soll, sind diese jedoch nicht (zwingend) erforderlich. Insbesondere dürfen Sie den kompletten Abschnitt [Install] auslassen.

Die neu erstellte Service Unit speichern Sie im Verzeichnis /etc/systemd/system. Der Dateiname entspricht dem (internen) Name der Service Unit. Er muss unter allen Service Units eindeutig sein und auf .service enden, wie etwa backup.service. Systemd kann auch bereits bestehende beziehungsweise von der Distribution mitgelieferte Service Units zeitgesteuert anwerfen. In diesem Fall merken Sie sich einfach den Dateinamen der Service-Datei.

TIPP

Nähere Informationen zum Aufbau der Service Units finden Sie unter anderem im Artikel “Durchstarten” aus LU 10/2015 [2].

Tick-Tack

Damit der Kuchen im Ofen nicht zu viele schwarze Röstaromen erhält, stellen sich die meisten Hobbybäcker einen Küchenwecker. Analog müssen Sie auch für die von Systemd zu erledigende Aufgabe einen eigenen Wecker einrichten, den Systemd als Timer bezeichnet.

Dazu erstellen Sie im Unterverzeichnis /etc/systemd/system eine neue Textdatei. Sie besitzt denselben Dateinamen wie die vorhin angelegte Service Unit, endet aber auf .timer. Im Beispiel hieße die Datei folglich backup.timer. Die Datei mit der Endung .timer bezeichnet Systemd als Timer Unit. In ihr beschreiben Sie, wann der Timer “klingeln” und somit Systemd das Backup starten soll.

Der Aufbau einer Timer Unit ähnelt stark dem der Service Units. Wie das Beispiel aus Listing 2 zeigt, besteht sie typischerweise aus drei Abschnitten: Unterhalb von [Unit] folgen zunächst allgemeine Informationen über den Timer. In Listing 2 wäre das hinter Description= eine Beschreibung, die vor allem als Gedächtnisstütze für Sie dient. Dort sollten Sie vor allem notieren, warum der Timer existiert und welche Aktionen er auslöst.

Listing 2

[Unit]
Description=Erstelle täglich ein Backup des Systems
[Timer]
OnCalendar=*-*-* 18:15:00
Persistent=true
RandomizedDelaySec=2h
[Install]
WantedBy=timers.target

Zeitgeschehen

Im nächsten Abschnitt [Timer] verraten Sie Systemd, wann es die Aufgabe starten soll. Den entsprechenden Zeitpunkt notieren Sie hinter OnCalendar= in der Notation Wochentag Jahr-Monat-Tag Stunde:Minuten:Sekunden. Mit der Einstellung OnCalendar=Fr 2018-11-30 12:00:00 würde Systemd folglich das Backup am Freitag, den 30.11.2018 um genau 12 Uhr anlegen. Nicht benötigte Angaben dürfen Sie weglassen, wie etwa den Wochentag oder die Sekunden.

In der Regel soll Systemd die Aufgabe nicht nur zu einem einzelnen Zeitpunkt ausführen, sondern wiederholt. Dazu können Sie zunächst einfach die entsprechenden Tage, Daten und Uhrzeiten per Kommata getrennt auflisten. Im Beispiel aus der ersten Zeile von Listing 3 stößt Systemd das Backup am 30.11.2018 um 1 Uhr nachts und um 12 Uhr mittags an.

Zahlenbereiche dürfen Sie zudem mit zwei Punkten .. abkürzen, womit Sie beispielsweise nicht alle Monate auflisten müssen. Mit der Angabe aus der zweiten Zeile von Listing 3 würde Systemd am ersten Tag eines jeden Monats aktiv. Sofern die Anweisung alle Monate betrifft, bietet sich alternativ auch der Platzhalter * an (dritte Zeile).

Die Angabe *-*-* aus Listing 2 weist Systemd folglich an, das Backup jeden Tag um 18:15 Uhr in jedem Monat und in jedem Jahr auszuführen.

Listing 3

OnCalendar=2018-11-30 01,12:00:00
OnCalendar=2018-01..12-01 01,12:00:00
OnCalendar= 2018-*-01 01,12:00:00

Äußerst zögernd

Läuft der Rechner zum gewählten Zeitpunkt nicht, kann Systemd kein Backup erstellen. In Listing 2 sorgt deshalb die Einstellung Persistent=true dafür, dass Systemd die Aufgabe in einer solchen Situationen schnellstmöglich nachholt. Starten allerdings mehrere Aktionen gleichzeitig, können sie das System verlangsamen oder sich sogar gegenseitig stören.

Damit das nicht passiert, verzögert Systemd die Ausführung bei Bedarf nach dem Zufallsprinzip um ein paar Sekunden. Wie viele Sekunden es maximal mit der Ausführung warten darf, notieren Sie hinter RandomizedDelaySec=. Die Zahl interpretiert Systemd bei einem nachgestellten m als Minuten, bei einem h als Stunden. In der Tabelle “Von Systemd verwendete Einheiten” finden Sie alle weiteren möglichen Zeiteinheiten, die Sie zudem kombinieren dürfen. So würde Systemd das Backup mit RandomizedDelaySec="1m 30s" höchstens um 90 Sekunden hinauszögern.

Einheit

Langformen

Bedeutung

Beispiel

s

seconds, second, sec

Sekunde

5s

m

minutes, minute, min

Minute

10m

h

hours, hour, hr

Stunde

2h

d

days, day

Tag

7d

w

weeks, week

Woche

2w

M

months, month

Monat

6M

y

years, year

Jahr

4y

Wiederkehr

Systemd erlaubt nicht nur, eine Aufgabe automatisch zu ganz bestimmten Zeiten anzuwerfen, sondern auch beispielsweise alle 15 Minuten oder einmal pro Woche. Für den letzten Fall gibt es die Abkürzung OnCalendar=weekly. Neben weekly stehen noch minutely, hourly, daily, monthly, yearly, quarterly und semiannually bereit.

Möchten Sie eine Aufgabe 15 Minuten nach dem Systemstart ausführen, verwenden Sie anstelle von OnCalendar=... die folgenden Einstellungen:

OnBootSec=15m
OnUnitActiveSec=1w

OnBootSec= legt dabei fest, wie viele Sekunden nach dem Systemstart Systemd die Aufgabe ausführen soll. Im Beispiel klingelt der Timer 15 Minuten nach dem Systemstart. Die zweite Einstellung OnUnitActiveSec= verrät Systemd anschließend noch, in welchen weiteren Zeitabständen es die Aufgabe wiederholen soll. Im Beispiel würde Systemd also das Backup 15 Minuten nach dem Systemstart und dann jede Woche erneut ausführen.

Bei beiden Einstellungen können Sie wieder die Einheiten aus Tabelle “Von Systemd verwendete Einheiten” verwenden und die Angaben kombinieren. Die Einstellung OnBootSec="5m 30s" würde beispielsweise die Aufgabe fünfeinhalb Minuten nach dem Systemstart ausführen.

Basiert ein Timer wie in Listing 2 auf einem (Kalender-)Datum, spricht man von einem “Calendar Timer”. Startet ein Timer dagegen nach einer vorgegebenen Zeitspanne relativ zu einem Ereignis, wie etwa dem Systemstart, bezeichnet ihn Systemd als “Monotonic Timer”. Solche Timer arbeiten unabhängig von der Zeitzone.

Der Timer aktiviert sich nicht nur kurz nach dem Systemstart, sondern reagiert alternativ auch auf andere Ereignisse, die Tabelle “Monotonic Timers” auflistet. Wie im obigen Beispiel lassen sich mehrere Einstellungen miteinander kombinieren, wobei Sie jeder von ihnen eine eigene Zeile spendieren müssen.

Einstellung

Bezieht sich auf den Moment, in dem …

OnActiveSec=

… der Timer aktiviert wurde.

OnBootSec=

… der Computer gebootet wurde.

OnStartupSec=

… Systemd gestartet ist.

OnUnitActiveSec=

… die Unit, die den Timer aktiviert, zum letzten Mal aktiviert wurde.

OnUnitInactiveSec=

… die Unit, die den Timer aktiviert, zum letzten Mal deaktiviert wurde.

Beziehungshelfer

Beim Ausknobeln der korrekten Zeitangaben hilft das Werkzeug Systemd-analyze. Übergibt man ihm den Parameter calendar, rechnet es die relativen Zeitangaben in andere Formate um (Abbildung 1). Der folgende Befehl verrät beispielsweise, welchem Wochentag weekly konkret entspricht:

$ systemd-analyze calendar weekly
Abbildung 1: Hier würde ein wöchentlich startender Timer immer Montags um Mitternacht ausgeführt. Dies wäre in genau fünf Tagen wieder der Fall.

Abbildung 1: Hier würde ein wöchentlich startender Timer immer Montags um Mitternacht ausgeführt. Dies wäre in genau fünf Tagen wieder der Fall.

Standardmäßig garantiert Systemd eine Ganggenauigkeit der Timer von einer Minute. Sie müssen folglich damit rechnen, dass das Backup nicht pünktlich um 18:00 Uhr, sondern erst um 18:01 anläuft. Sollten Sie eine höhere Genauigkeit benötigen, fügen Sie dem Abschnitt [Timer] noch die Zeile AccuracySec=30s hinzu. Die Zeitangabe legt die gewünschte Genauigkeit fest, im Beispiel würde die Aktion auf keinen Fall später als 30 Sekunden über dem eigentlich festgelegten Termin liegen. Bei solchen Zeitangaben dürfen Sie wieder die Einheiten aus Tabelle “Von Systemd verwendete Einheiten” nutzen.

Timer erlauben es zudem, den Rechner zeitgesteuert aus dem Suspend-Modus aufzuwecken. Dazu fügen Sie dem Abschnitt [Timer] die Zeile WakeSystem=true hinzu. Systemd weckt das System allerdings nur dann auf, wenn es sich gerade im Schlafzustand befindet und die Hardware sowie das BIOS/UEFI des Computers den Vorgang unterstützen. Den Rechner zeitgesteuert schlafen legen kann Systemd derzeit nicht.

Anhand der Dateinamen ordnet Systemd gleich die Timer Unit der passenden Service Unit zu. Im Beispiel startet der Timer backup.timer automatisch den Befehl aus der Service Unit backup.service. Alternativ geben Sie im Abschnitt [Timer] über die Einstellung Unit= explizit den Namen der Service Unit an, die Systemd ausführen soll. Das erweist sich vor allem dann als praktisch, wenn Sie eine bereits existierende Service Unit über einen neuen Timer anwerfen möchten.

Aufziehen

Wenn Systemd den Timer direkt beim Systemstart scharf schalten soll, benötigen Sie in der Timer Unit noch den Abschnitt [Install]. Dort verrät die Einstellung WantedBy=, mit welchen anderen Units der Timer starten soll. In Listing 2 sorgt die Einstellung WantedBy=timers.target dafür, dass Systemd den Timer beim regulären Systemstart zusammen mit allen anderen Timern anwirft.

Sofern Systemd den Timer schon beim Systemstart loslaufen lassen soll, müssen Sie ihn noch explizit aktivieren (Listing 4, erste Zeile). Alternativ starten Sie den Timer manuell (zweite Zeile). Alle derzeit eingerichteten Timer listet der Befehl systemctl list-timers auf (Abbildung 2).

Listing 4

$ systemctl enable backup.timer
$ systemctl start backup.timer
Abbildung 2: <code>systemctl</code> zeigt auf Wunsch alle derzeit laufenden Timer an. Die Darstellung verlangt ein m&ouml;glichst breites Terminal, alternativ geben Sie mit <code>systemctl list-timers --no-pager</code> die Informationen auf der Standardausgabe aus.

Abbildung 2: systemctl zeigt auf Wunsch alle derzeit laufenden Timer an. Die Darstellung verlangt ein möglichst breites Terminal, alternativ geben Sie mit systemctl list-timers --no-pager die Informationen auf der Standardausgabe aus.

In der Tabelle lesen Sie unter Next ab, wann Systemd-timer die Aufgabe das nächste Mal ausführt. Die bis dahin noch verbleibende Zeit steht in der Spalte Left. Analog erfahren Sie unter Last, wann Systemd-timer die Aufgabe zum letzten Mal ausgeführt hat. Wie lange das her ist, zeigt die Spalte Passed. Unter Unit steht der Name des entsprechenden Timers und somit seine Konfigurationsdatei.

Sie beenden die Anzeige mit [Q]. Systemctl präsentiert standardmäßig nur Timer, die auch gerade scharf geschaltet sind. Die inaktiven Timer holen Sie auf den Schirm, indem Sie noch den Parameter --all anhängen.

Schlummertaste

Bei Bedarf lässt sich jeder Timer später per Hand stoppen (Listing 5, erste Zeile) und deaktivieren (zweite Zeile). Erklärungen zu allen vorgestellten Einstellungen liefert die entsprechende Manpage [1], die man systemd.timer auf den Schirm holt. Zum Format von Datums- und Zeitangaben hält hingegen man systemd.time weitere Informationen bereit, und vor allem auch zahlreiche zusätzliche Beispiele.

Listing 5

$ sudo systemctl stop mein.timer
$ sudo systemctl disable mein.timer

Kurzzeitwecker

Soll Systemd in genau 30 Minuten ein einziges Mal ein Backup anfertigen, beauftragen Sie Systemd-run mit dieser Aufgabe. Das sieht dann so aus wie in der ersten Zeile von Listing 6. Den dort hinten angehängten Befehl /usr/bin/backup.sh /mnt führt Systemd zum genannten Zeitpunkt aus, über den Parameter --on-active teilen Sie ihm die Wartezeit mit.

Die Zeiteinheiten entsprechen wieder denen aus der Tabelle “Von Systemd verwendete Einheiten”. Im Beispiel interpretiert Systemd die 30m als eine halbe Stunde. Alternativ geben Sie via --on-calendar= ein konkretes Datum vor. Die Angaben erfolgen dabei ebenfalls wie in der Timer Unit. Mit den passenden Zeitangaben wie weekly lässt sich zudem die Aktion wiederholt ausführen.

In jedem Fall erstellt Systemd-run im Hintergrund einen neuen Timer, ohne dass Sie dafür eine Service-Datei anlegen müssen (Abbildung 3). Sollte bereits eine passende Service Unit existieren, können Sie alternativ auch diese von Systemd-run starten lassen. Dazu übergeben Sie einfach den Namen der Service Unit über den Parameter --unit. Das Beispiel aus der zweiten Zeile von Listing 6 startet jede Woche die in der Service Unit backup.service hinterlegte Aufgabe.

Die von Systemd-run erzeugten Timer existieren allerdings nur vorübergehend. Verwenden Sie den Parameter --on-active, verschwindet der Timer direkt nach dem Ausführen der Aktion, in jedem Fall löst er sich spätestens nach einem Neustart des Systems in Wohlgefallen auf. Systemd-run erstellt zudem nur dann für eine Service Unit einen Timer, wenn keine passende Timer Unit existiert.

Listing 6

$ systemd-run --on-active=30m /usr/bin/backup.sh /mnt
$ systemd-run --on-calendar=weekly --unit backup.service
Abbildung 3: Die von Systemd-run erzeugten Timer besitzen kryptische Namen, die in der Regel nicht auf die vom Timer zu l&ouml;sende Aufgabe hinweisen.

Abbildung 3: Die von Systemd-run erzeugten Timer besitzen kryptische Namen, die in der Regel nicht auf die vom Timer zu lösende Aufgabe hinweisen.

Fazit

Gegenüber dem guten alten Cron bieten die Timer aus Systemd einige Vorteile. So liegt Systemd mittlerweile den meisten Distributionen bei. Die Aktionen lassen sich zudem bei Bedarf unabhängig vom Timer starten, in einer ganz bestimmten Umgebung ausführen, Cgroups zuordnen und zu anderen Units in Abhängigkeit setzen.

Wie jedoch schon das einfache Beispiel aus Listing 2 zeigt, liegt der Konfigurationsaufwand bei Systemd-timer deutlich höher: Während bei Cron eine kurze Zeile genügt, muss man bei Systemd zunächst erst eine komplette Timer Unit schreiben. Darüber hinaus kann Systemd im Gegensatz zu Cron bei einem Fehler keine E-Mail verschicken und so auf sich aufmerksam machen. Die Systemd-Timer dürften daher zumindest in der nahen Zukunft Cron nicht ablösen, sondern lediglich ergänzen.

Infos

  1. Manpage der Systemd Timer Units: https://www.freedesktop.org/software/systemd/man/systemd.timer.html
  2. Systemd und SysVinit: Harald Zisler, “Durchstarten”, LU 10/2015, S. 68, https://www.linux-community.de/35092
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 07/2018 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben