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
Inzwischen gibt es eine zufällige Verzögerung:
RandomizedDelaySec=
siehe http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.timer&sect=5
Dort stehen auch noch einige ergänzende Informationen zu AccuracySec=.