systemd-timer

Das in RHEL 7 eingeführte Systemd hat das Potential, mit seinen systemd timer units das altehrwürdige cron aus den 1970er-Jahren abzulösen. Eine Systemd-Timer Unit ist erstmal mit einem Eintrag in die crontab vergleichbar: die Timer-Unit ruft immer die gleichnamige Systemd-Unit auf. Letzteres kann von einem beliebigen Type sein, beispielsweise eine Service-Unit oder ein Mount.

Einige der Vorteile der Systemd Timer-Units sind:

  • Konsistente Protokollierung im Systemd-Journal (journalctl).

  • Da Systemd-Timer auch gleichzeitig Systemd-Services sind, sind sie in der Lage, Features wie User/Group IDs, Nice Values, CPU Scheduling etc. zu nutzen.

  • Es lassen sich Abhängigkeiten definieren. Beispielsweise lässt sich mit OnBootSec=60sec der zum Timer gehörende Service 60 Sekunden nach dem Boot starten.

  • Zufällig verzögerter Start eines Events definierbar.

  • Einfacherer Umgang mit Kalendern und verschiedenen Zeitzonen (Monotonic Times).

  • Timer-Events bis in den Millisekunden-Bereich (Cron: minimal minütlich).

  • Wesentlich freiere und einfachere Definition und damit bessere Lesbarkeit der Kalender-Direktive (z.B. *-02~03 ist „der drittletzte Tag im Februar“).

  • Kommunikation mit anderen Programmen über Status des Timers.

  • Übersicht über die nächsten Ausführungszeiten per systemctl list-timers

Eine Timer-Unit endet immer auf .timer. Ein einfaches Beispiel:

/etc/systemd/system/aide-check.timer
[Unit]
Description=aide-check Timer

[Timer]
OnCalendar=05:07:00
Unit=aide-check.service

[Install]
WantedBy=timers.target

Anschliessend nicht vergessen:

systemctl daemon-reload
systemctl enable --now aide-check.timer

Ein

systemctl list-timers

ergibt:

NEXT                         LEFT     LAST                         PASSED      UNIT                         ACTIVATES
Wed 2020-12-23 05:07:00 CET  14h left Tue 2020-12-22 05:07:00 CET  9h ago      aide-check.timer             aide-check.service

Bemerkung

Niemals die Unit-Files in /usr/lib/systemd/system editieren, da sie beim nächsten Update überschrieben werden könnten. Statt dessen das Unit-File nach /etc/systemd/system kopieren und dort anpassen - Systemd sucht hier zuerst.

Eine Sammlung gültiger OnCalendar-Statements, die Systemd für sich in die normalisierte Form wday yyyy-mm-dd H:i:s TZ überführt:

+3h30min
-5s
11min ago
2 months 5 days ago

03-23                       # mm-dd
03-23 08:05:40
05:40
05:40:23.4200004/3.1700005
05:40:40
12,14,13,12:20,10,30        # hh
12..14:10,20,30

12-11-30                    # yy-mm-dd
2012-11..04-05
2012-11-23
2012-11-23 05:40
2012-11-23 05:40 UTC
2012-11-23 05:40:13
2012-11-23 05:40:13 UTC

Fri 2012-11-23 11:12:13
Mon,Fri *-*-3,1,2 *:30:45
mon,fri *-1/2-1,3 *:30:45
Mon,Sun 12-*-* 2,1:23
monday *-12-* 17:00
Sat,Sun 08:05:40
Sat,Sun 12-05 08:05:40
Sat,Thu,Mon..Wed,Sat..Sun
Wed *-1
Wed, 17:48
Wed..Sat,Tue 12-10-15 1:2:3
Wed..Wed,Wed *-1

@1395716396                 # UNIX-Epoch

annually
daily
daily UTC
hourly
minutely        # *-*-* *:*:30
monthly
now
quarterly
semiannually
today
today UTC
tomorrow Pacific/Auckland
weekly
weekly Pacific/Auckland
yearly
yesterday

Mit systemd-analyze calendar und systemd-analyze timestamp können die Kalender und Zeitspannen analysiert und nachvollzogen werden.

Gebräuchliche Angaben in den einzelnen Sektionen einer .timer-Unit:

[Unit]
After=network.target
ConditionKernelCommandLine=!rd.live.image
ConditionPathExists=!/run/ostree-booted
ConditionUser=!@system
ConditionVirtualization=!container
Conflicts=sys-devices-virtual-block-%i.device
DefaultDependencies=no
Description=Daily Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
Requires=corosync.service
Wants=network-online.target

[Timer]
AccuracySec=100ms
OnActiveSec=2min
OnBootSec=15min
OnCalendar=*-*-* 6,18:00
OnStartupSec=5min
OnUnitActiveSec=1w
OnUnitInactiveSec=1h
Persistent=true
RandomizedDelaySec=12h
Unit=zfs-fuse-scrub.service

[Install]
WantedBy=timers.target

Built on 2022-06-03