[[Vorlage(Getestet, jammy, focal)]] {{{#!vorlage Wissen [:Terminal: Ein Terminal öffnen] [:sudo: Root-Rechte erlangen] [:Editor:einen Editor öffnen] }}} [[Inhaltsverzeichnis()]] [:systemd:] bietet die Möglichkeit, Timer Units zu erstellen. In einer Timer Unit kann hinterlegt werden, dass eine [:systemd/Service_Units:Service Unit] zu einem bestimmten Zeitpunkt ausgeführt wird. Timer Units können also Aufgaben übernehmen, welche traditionell von [:Cron:] ausgeführt werden. Aber Timer Units können nicht nur Befehle zu einem festen Zeitpunkt ausführen (z.B. "um Mitternacht"), sondern auch relativ zum Systemstart (z.B. "5 Minuten später"). = Installation = Da systemd ab Ubuntu 15.04 integraler Bestandteil des Systems ist (und dieses ohne systemd nicht lauffähig ist), sind alle benötigten Komponenten bereits installiert. = Benutzung = Timer Units werden als einfache Textdateien angelegt[2], mit einer Syntax und einem Aufbau ähnlich [wikipedia:Initialisierungsdatei:INI-Dateien]. Der Dateiname kann frei gewählt werden, muss aber auf '''.timer''' enden. Selbsterstellte Timer werden im Verzeichnis '''/etc/systemd/system''' abgespeichert, wozu Root-Rechte[3] erforderlich sind. Eine Timer Unit hat z.B. folgenden Aufbau: {{{#!code ini [Unit] Description=Eine kurze Beschreibung des Timers [Timer] OnBootSec=2min OnUnitActiveSec=5min Unit=name_der_zu_startenden_unit.service [Install] WantedBy=multi-user.target }}} Es gibt drei Sektionen: * ''"[Unit]"'' * ''"[Timer]"'' und * ''"[Install]"'' Die Bedeutung der Sektionen ''"[Unit]"'' und ''"[Install]"'' ist identisch mit der von [:systemd/Service_Units#Eigene-Service-Units-anlegen:Service Units]. Die Sektion ''"[Timer]"'' enthält dabei die Informationen, wann die im Schlüssel `Unit` hinterlegte Unit ausgeführt werden soll. Im obigen Beispiel würde die Unit namens '''name_der_zu_startenden_unit.service''' wie folgt ausgeführt: * `OnBootSec=2min` - erste Ausführung 2 Minuten nach Beginn des Bootvorgangs * `OnUnitActiveSec=5min` - weitere Ausführungen jeweils 5 Minuten, nachdem die Service Unit zu letzten Mal gestartet wurde Timer Units kennen fünf verschiedene Schlüssel für relative Ausführungszeitpunkte: {{{#!vorlage Tabelle Schlüssel Erklärung +++ `OnActiveSec` relative Zeit bezogen auf den Zeitpunkt, als die Timer Unit zuletzt aktiviert wurde +++ `OnBootSec` relative Zeit bezogen auf den Zeitpunkt, als der Rechner gestartet wurde +++ `OnStartupSec` relative Zeit bezogen auf den Zeitpunkt, als systemd gestartet wurde +++ `OnUnitActiveSec` relative Zeit bezogen auf den Zeitpunkt, als die Service Unit zuletzt aktiviert wurde +++ `OnUnitInactiveSec` relative Zeit bezogen auf den Zeitpunkt, als die Service Unit zuletzt deaktiviert wurde }}} Außerdem kennen Timer Units noch absolute Zeitangaben. Diese werden im Schlüssel `OnCalendar` angeben. So würde z.B. die folgende Timer Unit: {{{#!code ini [Unit] Description=Eine kurze Beschreibung des Timers [Timer] OnCalendar=Mon-Fri *-*-* 12:00:00 Unit=name_der_zu_startenden_unit.service [Install] WantedBy=multi-user.target }}} die Service Unit '''name_der_zu_startenden_unit.service''' an jedem Tag von Montag bis Freitag um 12 Uhr ausführen. == Zeitangaben == Die Timer von systemd kennen eine Vielzahl von Zeiteinheiten. Die kleinste Zeiteinheit sind Mikrosekunden, die größte Jahre. Eine komplette Übersicht inklusive der Einheiten ist in der [http://www.freedesktop.org/software/systemd/man/systemd.time.html#Parsing%20Time%20Spans Dokumentation] {en} von systemd zu finden. Für die Werte des `OnCalendar` Schlüssel kennt systemd eine flexible Syntax zur Zeitangabe. So steht z.B. der Wert `Thu,Fri 2016-*-1,5 11:12:13` für: * am 1. und 5. jedes Monats im Jahr 2016 um 11 Uhr, 12 Minuten und 13 Sekunden ausführen * aber nur, wenn diese Tage ein Donnerstag oder Freitag sind Eine vollständige Übersicht inklusive vieler Beispiele findet man in der [http://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events Dokumentation] {en} von systemd. == verpasste Timer nachholen == Möchte man eine Timer Unit auch noch nachträglich ausführen lassen, also z.B. falls der Rechner zum Zeitpunkt der Fälligkeit des Timers ausgeschaltet war, muss man im Abschnitt `[Timer]` zusätzlich die Direktive {{{Persistent=true}}} setzen. Die Voreinstellung von systemd ist hier `false`, d.h. verpasste Timer werden nicht nachgeholt. Die Direktive funktioniert nur in Kombination mit der `OnCalendar` Direktive, nicht mit anderen Direktiven für Zeitpunkte. == Timer Units aktivieren == Nach dem Erstellen müssen Timer Units noch aktiviert und gestartet werden[1]: {{{#!vorlage Befehl sudo systemctl enable name_des_timers.timer sudo systemctl start name_des_timers.timer }}} == at Ersatz == Neben den Aufgaben, die traditionell [:Cron:] erledigt, kann systemd auch die typische Aufgabe von [:at:] übernehmen, einen Job nur ein einziges mal zu einem bestimmten Zeitpunkt zu starten. Es muss kein Script angelegt werden, sondern es genügt das Abschicken eines Befehls im Terminal. Beispiel: {{{#!vorlage Befehl # als root sudo systemd-run --on-calendar="2022-01-30 20:01:35" touch /tmp/testfile # als normaler User systemd-run --user --on-calendar="2022-01-30 20:01:35" touch ~/testfile }}} Diese Timer werden in den Verzeichnissen '''/run/systemd/transient''' (systemweit) und für Benutzer in '''/run/user//systemd/transient''' angelegt. Dabei wird standardmäßig ein zufälliger Name generiert. Man kann den Namen des Timers aber auch explizit mit der Option ``--unit=`` festlegen. == Genauigkeit == Per Voreinstellung haben die Timer eine Genauigkeit von einer Minute, d.h aller spätestens eine Minute nach der in der '''.timer''' Datei angegebenen Zeit wird die vom Timer aufgerufene Service Unit aufgerufen. Wer für einzelne Timer Units einen genaueren Ausführungszeitraum braucht, der kann in der Sektion ''"[Timer]"'' zusätzlich den Schlüssel `AccuracySec` angeben, gefolgt von einer Zeitangabe. So würde z.B. `AccuracySec=5s` die Genauigkeit auf 5 Sekunden setzen. Wer eine höhere Genauigkeit für alle Timer systemweit benötigt, der hinterlegt den gewünschten Wert in der Konfigurationsdatei '''/etc/systemd/system.conf'''. Aufgrund dieser Tatsache kann nicht eindeutig die verbleibende Zeit bis zum Trigger ermittelt werden. Dieser Umstand wird im [https://unix.stackexchange.com/a/526906/427268 unix.stackexchange] ausführlich beschrieben. Darüber hinaus gibt es noch die Möglichkeit mit `RandomizedDelaySec` eine absichtliche gleichverteilt zufällige Verzögerung zu erzeugen. == Timer anzeigen == Man kann sich alle aktiven Timer mit Hilfe von [:systemd/systemctl:systemctl] wie folgt anzeigen lassen: {{{#!vorlage Befehl # Systemweite Timer: systemctl list-timers # Von Benutzern angelegte Timer: systemctl --user list-timers }}} Möchte man zusätzlich die inaktiven Timer sehen, muss man dem Befehl noch die Option `--all` hinzufügen. == Timer stoppen und deaktivieren == Wie alle anderen Systemd-Units lassen sich Timer mittels, {{{#!vorlage Befehl sudo systemctl stop name_des_timers.timer }}} stoppen. Sofern Timer wiederkehrend mit dem System-Start aktiviert wurden, deaktiviert man sie unter Verwendung von {{{#!vorlage Befehl sudo systemctl disable name_des_timers.timer }}} Bei mittels ``systemd-run`` angelegten Timern muss berücksichtigt werden, dass das System für diese zwei Dateien pro Timer generiert; eine mit der Endung '''.service''' und eine mit der Endung '''.timer'''. Dementsprechend stopt man diese mittels: {{{#!vorlage Befehl sudo systemctl stop name_des_timers.{service,timer} }}} Die ``systemd-run``-Timer werden damit auch gleichzeitig aus den betreffenden Verzeichnissen gelöscht, so dass sie gegebenenfalls durch erneutes Anlegen mittels ``systemd-run`` neu eingerichtet werden müssen. = Links = * [http://www.freedesktop.org/software/systemd/man/systemd.timer.html Dokumentation] {en} von systemd Timer Units * [archwiki:Systemd/Timers#Example: systemd Timer] {en} im Wiki von Archlinux #tag: System, systemd