Systemd-Timer als Cron-Alternative

Systemd kann sich ähnlich wie Cron auch um die regelmäßige Ausführung von Prozessen kümmern. Die meisten Distributionen machen von dieser Funktion noch recht sparsam Gebrauch. Insofern ist Systemd momentan eher als Ergänzung zu Cron zu sehen.

systemctl list-timers

Die zeitgesteuerte Ausführung von Programmen wird in Systemd durch Timer-Unit-Dateien gesteuert, also durch Dateien mit der Endung .timer. Einen Überblick über aktive Timer gibt systemctl, wobei die folgende, unter Fedora 23 Alpha entstandene Ausgabe aus Platzgründe gekürzt dargestellt ist.

systemctl list-timers
  NEXT             LEFT         LAST              UNIT                        
  2015-08-20 09:33 18min left   2015-08-19 09:33  systemd-tmpfiles.timer
  2015-08-20 09:42 26min left   2015-08-20 08:42  dnf-makecache.timer         
  2015-08-20 11:19 2h 3min left 2015-08-19 11:15  dnf-automatic.timer         
  2015-08-21 00:00 14h left     2015-08-20 00:00  mlocate-updatedb.timer      
  2015-08-21 00:00 14h left     2015-08-20 00:00  unbound-anchor.timer        

.timer-Syntax

Die .timer-Dateien liegen in einem leicht verständlichem Textformat vor. Die folgenden Zeilen zeigen die Datei dnf-automatic.timer, die für den täglichen Start des Scripts dnf-automatic verantwortlich ist. Dieses Script aus dem gleichnamigen Paket aktualisiert die Paketdatenbank und installiert bei entsprechender Konfiguration alle verfügbaren Updates (siehe hier).

# Datei /usr/lib/systemd/system/dnf-automatic.timer
[Unit]
Description=dnf-automatic timer

[Timer]
OnBootSec=1h
OnUnitInactiveSec=1d

[Install]
WantedBy=basic.target

OnBootSec=1h bewirkt, dass das Prozess eine Stunde nach einem Neustart des Rechners erstmalig ausgeführt wird. OnUnitInactiveSec=1d bedeutet, dass der Dienst 24 Stunden nach dem Ende des letzten Ablaufs wieder gestartet werden soll. Wenn die Zeitangabe ohne Einheit erfolgt, sind Sekunden gemeint. Die Syntax der Zeitangaben ist in man systemd.time dokumentiert. Zulässig ist z.B. 2h 15min oder 2weeks oder 4months.

Anstelle dieser etwas vagen Vorgaben können Sie die Zeitangaben im [Timer]-Abschnitt auch absolut vornehmen. Die folgenden Einstellungen bewirken, dass die Aufgabe jeden Tag um 8:15 erledigt wird. Persistent=true bewirkt, das versäumte Jobs beim nächsten Rechnerstart
sofort nachgeholt werden.

# in einer .timer-Datei
[Timer]
OnCalendar=8:15
Persistent=true     

Für absolute Zeitangaben sieht Systemd eine komplexe Syntax vor, die in man systemd.time im Abschnitt Calendar Events ausführlich dokumentiert ist. So bewirkt OnCalendar=Sun 2016-*-* 17:15 beispielsweise, dass ein Job an jedem Sonntag des Jahrs 2016 um 17:15 ausgeführt wird.

Systemd versucht eingerichtete Timer-Jobs standardmäßig in einem Zeitfenster von einer Minute nach der vorgesehenen Zeit auszuführen. Wenn Sie möchten, dass sich Systemd exakter an Ihre Vorgaben hält, geben Sie im [Timer]-Abschnitt mit AccuracySec eine kleinere Zeitspanne an, z.B. von 1s (eine Sekunde) bis hin zu 1us (theoretisch eine millionstel Sekunde, ganz so exakt wird der Start in der Praxis aber nicht immer gelingen).

.service-Dateien

Jeder name.timer-Datei muss eine entsprechende name.service-Datei gegenüberstehen, die Details zum auszuführenden Prozess enthält. Für das obige dnf-automatic-Beispiel sieht die .service-Datei wie folgt aus:

# Datei /usr/lib/systemd/system/dnf-automatic.service
[Unit]
Description=dnf automatic

[Service]
Type=oneshot
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
Environment="ABRT_IGNORE_PYTHON=1"
ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer

Start/Stopp

Neu eingerichtete Timer müssen wie üblich durch systemctl start erstmalig gestartet und durch systemctl enable dauerhaft (also über den nächsten Neustart hinweg) aktiviert werden. Analog beenden Sie den Aufruf durch systemctl stop und systemctl disable. Damit Änderungen in bereits aktiven Timern wirksam werden, führen Sie am einfachsten das folgende Kommando aus:

systemctl reenable --now name.timer

Nach dem Einrichten neuer Timer-Jobs sollten Sie sich immer mit systemctl list-timers vergewissern, dass Systemd Ihre .timer-Angaben korrekt interpretiert hat.

Beispiel

Das folgende Beispiel zeigt, wie Sie mit Systemd ein simples Script zur Überprüfung der Netzwerkverbindung alle 10 Minuten ausführen. Das Script ping-kofler testet durch ein dreimaliges ping, ob und wie schnell der Server kofler.info auf Netzwerkanfragen reagiert. Die gerade aktuelle Zeit und die ping-Ausgaben werden in /var/log/ping-kofler.log protokolliert. &>> bewirkt, dass sowohl die Standardausgabe als auch allfällige Fehler an eine vorhandene Datei hinzugefügt werden. Dieser Operator setzt die bash-Version 4 voraus. Vergessen Sie nicht, das Script mit chmod a+x ausführbar zu machen.

#!/bin/bash
# Datei /usr/local/bin/ping-kofler
date &>> /var/log/ping-kofler.log
ping -c 3 kofler.info &>> /var/log/ping-kofler.log

Für den Aufruf des Scripts ist die folgende .service-Datei zuständig:

# Datei /etc/systemd/system/ping-kofler.service
[Unit]
Description=simpler ping-Test

[Service]
ExecStart=/usr/local/bin/ping-kofler

Die Einstellungen für den automatischen Start befinden sich in dieser .timer-Datei. Das Script soll 30 Sekunden nach systemctl start erstmalig ausgeführt werden, in der Folge alle 10 Minuten. Der [Install]-Abschnitt ist erforderlich, damit der Timer mit systemctl enable dauerhaft aktiviert werden kann.

[Unit]
Description=ping-kofler timer

[Timer]
OnActiveSec=30s
OnUnitActiveSec=10m

[Install]
WantedBy=basic.target

Um die Script-Ausführung zu starten und dauerhaft einzurichten, führen Sie systemctl enable mit der Option --now aus — dann ist start gleich inkludiert:

systemctl enable --now ping-kofler.timer

Für und wider

Das Beispiel macht sofort klar, dass das Einrichten eines Systemd-Timers mit wesentlich mehr Aufwand verbunden ist als die eine crontab-Zeile, die für die periodische Cron-Ausführung erforderlich wäre.

Die Vorteile von Systemd bestehen darin, dass Systemd-Jobs exakter gesteuert werden können (eigenes Environment, siehe man systemd.exec, cgroups-Regeln etc.) und ihr Aufruf im Systemd-Journal protokolliert wird.

Es gibt aber auch Nachteile: So wird bei einem Fehler nicht automatisch eine E-Mail versendet. Außerdem gibt es keine zufällige Verzögerung (RANDOM_DELAY in anacrontab), um die gleichzeitige Ausführung vieler Jobs zu vermeiden.

Quellen

https://wiki.archlinux.org/index.php/Systemd/Timers
http://www.freedesktop.org/software/systemd/man/systemd.timer.html
http://www.freedesktop.org/software/systemd/man/systemd.time.html
http://blog.higgsboson.tk/2013/06/09/use-systemd-as-a-cron-replacement

3 Gedanken zu „Systemd-Timer als Cron-Alternative“

Kommentare sind geschlossen.