systemd bietet die Möglichkeit, Timer Units zu erstellen. In einer Timer Unit kann hinterlegt werden, dass eine Service Unit zu einem bestimmten Zeitpunkt ausgeführt wird. Damit bietet systemd eine Alternative zu cron.
Woraus besteht ein systemd-Timer?
für einen systemd-Timer benötigt man 2 Dateien:
.timer .service
und beide Dateien sollten unter /etc/systemd/system
zu finden sein.
Aufbau einer .timer Datei
Der Aufbau einer .timer Datei ähnelt einer .service Datei.
Im Regelfall beginnt die .timer Datei mit [Unit]
. In diesem Abschnitt können Metadaten festgelegt werden, z.B. eine Beschreibung was der Timer auslöst.
[Unit]
Description=Erstelle ein Backup des Bilder-Ornders
Der nächste Abschnitt wird per [Timer]
eingeleitet und beschreibt die entsprechenden Einzelheiten des Timers. z.B. wann soll der Dienst gestartet werden, welche Verzögerung beim Start ist möglich, etc…
Wann der Timer gestartet wird legt die Option OnCalendar
im entsprechenden [timer]
Abschnitt fest.
Das Format für ein festzulegendes Datum sieht wie folgt aus:
Wochentag Jahr-Monat-Tag Stunde:Minute:Sekunde
Um nun an einem bestimtmen Tag einen entsprechenden Dienst zu starten lautet die entsprechende Option z.B.:
OnCalendar=Fr 2018-08-03 10:00:00
Hierbei wird die Zeit der Ausführung auf Freitag, den 03.August 2018 um 10 Uhr festgelegt.
Zeitrahmen (von-bis) können per ..
angegeben werden, z.B. OnCalendar=2018-01..06-01
.
Hier wird nur in den Monaten Januar bis Juni der entsprechende Dienst gestartet.
Einzelne Zeitpunkte lassen sich auch per Komma auflisten, z.B.: OnCalendar=2018-10-01 01,12:00:00
Hier wird der entsprechende Dienst am 01.10.2018 jeweils um 1 und um 12 Uhr gestartet.
Soll ein Dienst regelmäßig gestartet werden (z.B. jeden tag, Monat oder Jahr) kann man statt einer Auflistung der Monate auch einfach ein *
an die entsprechende Stelle setzen (ähnlich wie bei Cron).
OnCalendar=*-*-* 05:00:00
startet dann täglich um 5 Uhr den entsprechenden Dienst.
Die *
können natürlich auch für die Uhrzeit verwendet werden.
eine vollständige .timer Datei sieht z.B. wie folgt aus:
[Unit]
Description=Erstelle ein Backup des Bilder-Ornders
[Timer]
OnCalendar=*-*-* 08:32:00
Persistent=true
RandomizedDelaySec=10m
Auflisten aktiver Timer
Welche Timer aktuell schon auf dem System aktiv sind erfährt man mit dem Befehl systemctl list-timers
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2018-08-03 09:00:00 CEST 45min left Fri 2018-08-03 08:00:33 CEST 13min ago snapper-timeline.timer snapper-timeline.service
Sat 2018-08-04 00:00:00 CEST 15h left Fri 2018-08-03 07:30:22 CEST 44min ago logrotate.timer logrotate.service
Sat 2018-08-04 00:07:44 CEST 15h left Fri 2018-08-03 07:30:23 CEST 44min ago backup-sysconfig.timer backup-sysconfig.service
Sat 2018-08-04 00:57:49 CEST 16h left Fri 2018-08-03 07:30:22 CEST 44min ago backup-rpmdb.timer backup-rpmdb.service
Sat 2018-08-04 01:23:31 CEST 17h left Fri 2018-08-03 07:30:22 CEST 44min ago check-battery.timer check-battery.service
Sat 2018-08-04 08:02:53 CEST 23h left Fri 2018-08-03 08:02:53 CEST 11min ago snapper-cleanup.timer snapper-cleanup.service
Sat 2018-08-04 08:07:25 CEST 23h left Fri 2018-08-03 08:07:25 CEST 7min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Mon 2018-08-06 00:00:00 CEST 2 days left Fri 2018-08-03 07:30:22 CEST 44min ago btrfs-balance.timer btrfs-balance.service
Mon 2018-08-06 00:00:00 CEST 2 days left Fri 2018-08-03 07:30:22 CEST 44min ago fstrim.timer fstrim.service
Sat 2018-09-01 00:00:00 CEST 4 weeks 0 days left Fri 2018-08-03 07:30:22 CEST 44min ago btrfs-scrub.timer btrfs-scrub.service
Um sich alle Timer, auch die inaktiven, anzeigen zu lassen hängt man noch ein --all
an den Befehl…
$ systemctl list-timers --all
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2018-08-03 09:00:00 CEST 44min left Fri 2018-08-03 08:00:33 CEST 15min ago snapper-timeline.timer snapper-timeline.service
Sat 2018-08-04 00:00:00 CEST 15h left Fri 2018-08-03 07:30:22 CEST 45min ago logrotate.timer logrotate.service
Sat 2018-08-04 00:07:44 CEST 15h left Fri 2018-08-03 07:30:23 CEST 45min ago backup-sysconfig.timer backup-sysconfig.service
Sat 2018-08-04 00:57:49 CEST 16h left Fri 2018-08-03 07:30:22 CEST 45min ago backup-rpmdb.timer backup-rpmdb.service
Sat 2018-08-04 01:23:31 CEST 17h left Fri 2018-08-03 07:30:22 CEST 45min ago check-battery.timer check-battery.service
...
Starten und Stoppen von Timern
Um einen systemd-Timer zu starten verwedet man:
systemctl start <Dienst>.timer
Stoppen:
systemctl stop <Dienst>.timer
Aktivieren eines Timers:
systemctl enable <Dienst>.timer
Deativieren eines Timers:
systemctl disable <Dienst>.timer
Besondere Startzeiten
systemd-Timer bieten noch ein paar Besonderheiten an, welche, meines Wissens nach, so in Cron nicht möglich sind…
Verzögerter Start
Läuft das System nicht zum eingestellten Zeitpunkt, kann der entsprechende Dienst natürlich nicht gestartet werden.
Fügt man in den [Timer]
Abschnitt der .timer Datei noch die Option Persistent=true
ein, ist systemd angehalten den entsprechenden Dienst so schnell wie möglich zu starten wenn das System wieder läuft.
Damit nun nicht gleich alle Dienste auf einmal starten und das System dadurch vielleicht in die Knie geht, kann man noch eine entsprechende Verzögerung mithilfe der Option RandomizedDelaySec=
angeben.
Hierbei wird eine zufällige Zeit (in Sekunden) gewartet bis der Dienst tatsächlich gestartet wird. Das Maximum der zu wartenden Zeit wird als Parameter bei RandomizedDelaySec=
angegeben.
Z.B.: RandomizedDelaySec=20
legt fest, dass zwischen 1-20 Sekunden gewartet wird bis der Dienst gestartet wird.
Auch hier kann man RandomizedDelaySec=5m
angeben und das Maximum liegt nun bei 5 Minuten.
Mögliche Zeitangaben sind:
- s (Sekunde)
- m (Minute)
- h (Stunde)
- d (Tage)
- w (Wochen)
- M (Monate)
- y (Jahre)
Bestimmte Zeitpunkte
weitere Möglichkeiten wann ein Dienst gestartet werden soll sind:
OnActiveSec=
(Zeit nach dem der Timer gestartet wurde)OnBootSec=
(Zeit nach dem das System gebootet ist)OnStartupSec=
(Zeit nach dem systemd gestartet ist)OnUnitActiveSec=
(Zeit nach dem die Unit, die den Timer aktiviert, zum letzten Mal aktiviert wurdeOnUnitInactiveSec=
(Zeit nach dem die Unit, die den Timer aktiviert, zum letzten Mal deaktiviert wurde)
Beispiele:
OnBootSec=15m
startet einen Dienst 15 Minuten nach dem das System gebootet ist.
Um eine Verzögerung von 10 Minuten und 30 Sekunden einzurichten verwendet man:
OnBootSec="10m 30s"
Dienst ohne .timer Datei starten lassen
Wenn man einen Dienst nur einmal zeitlich starten will und weder .service und .timer Dateien anlegen will, kann man die Ausführung folgendermaßen einrichten:
systemd-run --on-active=30m /opt/backup.sh
alternativ kann man hier auch mit OnCalendar=
ein spezielles Datum angeben oder auch mit weekly oder ähnlichem einen Timer einrichten.
Allgemein legt systemd hierbei im Hintergrund einen neuen Timer an, auch ohne das eine entsprechende .service Datei existiert.
Sollte eine .service Datei existieren, kann diese mit der --unit
Option angegeben werden.
Bsp: systemd-run --on-calendar=weekly --unit backup.service