GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Verwenden Sie systemd-Timer anstelle von Cronjobs

Ich bin dabei, meine Cron-Jobs in systemd-Timer umzuwandeln. Ich benutze Timer seit ein paar Jahren, aber normalerweise habe ich gerade genug gelernt, um die Aufgabe zu erfüllen, an der ich arbeitete. Bei der Recherche für diese Systemd-Serie habe ich erfahren, dass Systemd-Timer einige sehr interessante Fähigkeiten haben.

Wie Cron-Jobs können systemd-Timer Ereignisse – Shell-Skripte und Programme – in bestimmten Zeitintervallen auslösen, z. B. einmal am Tag, an einem bestimmten Tag im Monat (vielleicht nur, wenn es ein Montag ist) oder alle 15 Minuten während der Geschäftszeiten von 8 bis 18 Uhr. Timer können auch einige Dinge tun, die Cron-Jobs nicht können. Beispielsweise kann ein Timer ein Skript oder Programm auslösen, um eine bestimmte Zeitspanne nach einem Ereignis wie Booten, Hochfahren, Abschluss einer vorherigen Aufgabe oder sogar dem vorherigen Abschluss der vom Timer aufgerufenen Diensteinheit auszuführen.

Systemwartungstimer

Wenn Fedora oder eine andere systemd-basierte Distribution auf einem neuen System installiert wird, erstellt es mehrere Timer, die Teil der Systemwartungsverfahren sind, die im Hintergrund eines jeden Linux-Hosts ablaufen. Diese Timer lösen Ereignisse aus, die für allgemeine Wartungsaufgaben erforderlich sind, wie z. B. das Aktualisieren von Systemdatenbanken, das Bereinigen temporärer Verzeichnisse, das Rotieren von Protokolldateien und mehr.

Als Beispiel schaue ich mir einige der Timer auf meiner primären Workstation an, indem ich den systemctl status *timer verwende Befehl, um alle Timer auf meinem Host aufzulisten. Das Sternchen-Symbol funktioniert genauso wie beim Datei-Globbing, also listet dieser Befehl alle systemd-Timer-Einheiten auf:

[root@testvm1 ~]# systemctl status *timer 
● mlocate-updatedb.timer - Updates mlocate database every day
     Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
   Triggers: ● mlocate-updatedb.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day.

● logrotate.timer - Daily rotation of log files
     Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
   Triggers: ● logrotate.service
       Docs: man:logrotate(8)
             man:logrotate.conf(5)

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files.

● sysstat-summary.timer - Generate summary of yesterday's process accounting
     Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left
   Triggers: ● sysstat-summary.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting.

● fstrim.timer - Discard unused blocks once a week
     Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left
   Triggers: ● fstrim.service
       Docs: man:fstrim

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week.

● sysstat-collect.timer - Run system activity accounting tool every 10 minutes
     Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left
   Triggers: ● sysstat-collect.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes.

● dnf-makecache.timer - dnf makecache --timer
     Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left
   Triggers: ● dnf-makecache.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer.

● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
     Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left
   Triggers: ● systemd-tmpfiles-clean.service
       Docs: man:tmpfiles.d(5)
             man:systemd-tmpfiles(8)

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.

Jedem Timer sind mindestens sechs Informationszeilen zugeordnet:

  • Die erste Zeile enthält den Dateinamen des Timers und eine kurze Beschreibung seines Zwecks.
  • Die zweite Zeile zeigt den Status des Timers an, ob er geladen ist, den vollständigen Pfad zur Timer-Unit-Datei und das Hersteller-Preset.
  • Die dritte Zeile zeigt den aktiven Status an, der das Datum und die Uhrzeit enthält, zu der der Timer aktiv wurde.
  • Die vierte Zeile enthält das Datum und die Uhrzeit, zu der der Timer das nächste Mal ausgelöst wird, sowie eine ungefähre Zeit bis zum Auslösen.
  • Die fünfte Zeile zeigt den Namen des Ereignisses oder des Dienstes, der durch den Timer ausgelöst wird.
  • Einige (aber nicht alle) systemd-Unit-Dateien haben Verweise auf die relevante Dokumentation. Drei der Timer in der Ausgabe meiner virtuellen Maschine haben Zeiger auf die Dokumentation. Dies ist ein nettes (aber optionales) Bit an Daten.
  • Die letzte Zeile ist der Journaleintrag für die letzte vom Timer ausgelöste Instanz des Dienstes.

Abhängig von Ihrem Host haben Sie wahrscheinlich unterschiedliche Timer.

Erstellen Sie einen Timer

Obwohl wir einen oder mehrere der vorhandenen Timer dekonstruieren können, um zu lernen, wie sie funktionieren, erstellen wir unsere eigene Serviceeinheit und eine Timereinheit, um sie auszulösen. Wir werden ein ziemlich triviales Beispiel verwenden, um dies einfach zu halten. Nachdem wir dies abgeschlossen haben, ist es einfacher zu verstehen, wie die anderen Timer funktionieren, und zu bestimmen, was sie tun.

Erstellen Sie zunächst einen einfachen Dienst, der etwas Grundlegendes ausführt, wie z. B. free Befehl. Beispielsweise möchten Sie möglicherweise den freien Speicher in regelmäßigen Abständen überwachen. Erstellen Sie den folgenden myMonitor.service unit-Datei in /etc/systemd/system Verzeichnis. Es muss nicht ausführbar sein:

# This service unit is for testing timer units 
# By David Both
# Licensed under GPL V2
#

[Unit]
Description=Logs system statistics to the systemd journal
Wants=myMonitor.timer

[Service]
Type=oneshot
ExecStart=/usr/bin/free

[Install]
WantedBy=multi-user.target

Schauen wir uns nun den Status an und testen unsere Serviceeinheit, um sicherzustellen, dass sie so funktioniert, wie wir es erwarten.

[root@testvm1 system]# systemctl status myMonitor.service 
● myMonitor.service - Logs system statistics to the systemd journal
     Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)
     Active: inactive (dead)
[root@testvm1 system]# systemctl start myMonitor.service
[root@testvm1 system]#

Wo ist die Ausgabe? Standardmäßig ist die Standardausgabe (STDOUT ) von Programmen, die von Systemd-Diensteinheiten ausgeführt werden, wird an das Systemd-Journal gesendet, das einen Datensatz hinterlässt, den Sie jetzt oder später anzeigen können – bis zu einem gewissen Punkt. (Ich werde mich in einem zukünftigen Artikel dieser Serie mit systemd-Journaling und Aufbewahrungsstrategien befassen.) Sehen Sie sich das Journal speziell für Ihre Serviceeinheit und nur für heute an. Das -S Option, die die Kurzversion von --since ist , ermöglicht es Ihnen, den Zeitraum anzugeben, in dem das journalctl Tool sollte nach Einträgen suchen. Das liegt nicht daran, dass Sie frühere Ergebnisse nicht interessieren – in diesem Fall gibt es keine –, sondern um die Suchzeit zu verkürzen, wenn Ihr Host schon lange läuft und eine große Anzahl von Einträgen angesammelt hat im Tagebuch:

[root@testvm1 system]# journalctl -S today -u myMonitor.service 
-- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --
Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 11 09:12:09 testvm1.both.org free[377966]:               total        used        free      shared  buff/cache   available
Jun 11 09:12:09 testvm1.both.org free[377966]: Mem:       12635740      522868    11032860        8016     1080012    11821508
Jun 11 09:12:09 testvm1.both.org free[377966]: Swap:       8388604           0     8388604
Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
[root@testvm1 system]#

Eine von einem Dienst ausgelöste Aufgabe kann ein einzelnes Programm, eine Reihe von Programmen oder ein in einer beliebigen Skriptsprache geschriebenes Skript sein. Fügen Sie dem Dienst eine weitere Aufgabe hinzu, indem Sie die folgende Zeile am Ende von [Service] hinzufügen Abschnitt von myMonitor.service Unit-Datei:

ExecStart=/usr/bin/lsblk

Starten Sie den Dienst erneut und überprüfen Sie das Journal auf die Ergebnisse, die so aussehen sollten. Sie sollten die Ergebnisse beider Befehle im Journal sehen:

Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 11 15:42:18 testvm1.both.org free[379961]:               total        used        free      shared  buff/cache   available
Jun 11 15:42:18 testvm1.both.org free[379961]: Mem:       12635740      531788    11019540        8024     1084412    11812272
Jun 11 15:42:18 testvm1.both.org free[379961]: Swap:       8388604           0     8388604
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sda             8:0    0  120G  0 disk
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1          8:1    0    4G  0 part /boot
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2          8:2    0  116G  0 part
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0            11:0    1 1024M  0 rom
Jun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.

Nachdem Sie nun wissen, dass Ihr Dienst wie erwartet funktioniert, erstellen Sie die Timer-Unit-Datei myMonitor.timer file in /etc/systemd/system , und fügen Sie Folgendes hinzu:

# This timer unit is for testing
# By David Both
# Licensed under GPL V2
#

[Unit]
Description=Logs some system statistics to the systemd journal
Requires=myMonitor.service

[Timer]
Unit=myMonitor.service
OnCalendar=*-*-* *:*:00

[Install]
WantedBy=timers.target

Der OnCalendar Zeitangabe in der Datei myMonitor.timer file , *-*-* *:*:00 , sollte den Timer auslösen, um myMonitor.service auszuführen Einheit jede Minute. Ich werde OnCalendar erkunden Einstellungen etwas später in diesem Artikel.

Beobachten Sie vorerst alle Journaleinträge, die sich auf die Ausführung Ihres Dienstes beziehen, wenn er durch den Timer ausgelöst wird. Sie könnten auch dem Timer folgen, aber wenn Sie dem Dienst folgen, können Sie die Ergebnisse nahezu in Echtzeit sehen. Führen Sie journalctl aus mit dem -f (Folgen) Option:

[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --

Starten Sie den Timer, aber aktivieren Sie ihn nicht, und sehen Sie, was passiert, nachdem er eine Weile gelaufen ist:

[root@testvm1 ~]# systemctl start myMonitor.service
[root@testvm1 ~]#

Ein Ergebnis wird sofort angezeigt, und die nächsten kommen in Intervallen von einer Minute. Sehen Sie sich das Tagebuch ein paar Minuten lang an und sehen Sie, ob Sie dieselben Dinge bemerken wie ich:

[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:39:19 testvm1.both.org free[630566]:               total        used        free      shared  buff/cache   available
Jun 13 08:39:19 testvm1.both.org free[630566]: Mem:       12635740      556604    10965516        8036     1113620    11785628
Jun 13 08:39:19 testvm1.both.org free[630566]: Swap:       8388604           0     8388604
Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sda             8:0    0  120G  0 disk
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2          8:2    0  116G  0 part
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0            11:0    1 1024M  0 rom
Jun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:40:46 testvm1.both.org free[630572]:               total        used        free      shared  buff/cache   available
Jun 13 08:40:46 testvm1.both.org free[630572]: Mem:       12635740      555228    10966836        8036     1113676    11786996
Jun 13 08:40:46 testvm1.both.org free[630572]: Swap:       8388604           0     8388604
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sda             8:0    0  120G  0 disk
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2          8:2    0  116G  0 part
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0            11:0    1 1024M  0 rom
Jun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:41:46 testvm1.both.org free[630580]:               total        used        free      shared  buff/cache   available
Jun 13 08:41:46 testvm1.both.org free[630580]: Mem:       12635740      553488    10968564        8036     1113688    11788744
Jun 13 08:41:46 testvm1.both.org free[630580]: Swap:       8388604           0     8388604
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sda             8:0    0  120G  0 disk
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2          8:2    0  116G  0 part
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0            11:0    1 1024M  0 rom
Jun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.

Überprüfen Sie unbedingt den Status des Timers und des Dienstes.

Mehr über Systemadministratoren

  • Sysadmin-Blog aktivieren
  • Das automatisierte Unternehmen:ein Leitfaden zur IT-Verwaltung mit Automatisierung
  • eBook:Ansible-Automatisierung für SysAdmins
  • Geschichten aus der Praxis:Ein Leitfaden für Systemadministratoren zur IT-Automatisierung
  • eBook:Ein Leitfaden zu Kubernetes für SREs und Systemadministratoren
  • Neueste Sysadmin-Artikel

Sie haben wahrscheinlich mindestens zwei Dinge im Tagebuch bemerkt. Erstens müssen Sie nichts Besonderes tun, um STDOUT zu verursachen aus dem ExecStart Trigger im myMonitor.service Einheit, die im Journal gespeichert werden soll. Das ist alles Teil der Verwendung von systemd zum Ausführen von Diensten. Es bedeutet jedoch, dass Sie möglicherweise vorsichtig sein müssen, wenn Sie Skripte von einer Diensteinheit ausführen und wie viel STDOUT sie erzeugen.

Die zweite Sache ist, dass der Timer nicht minutengenau um :00 Sekunden oder sogar genau eine Minute nach der vorherigen Instanz ausgelöst wird. Dies ist beabsichtigt, kann aber bei Bedarf außer Kraft gesetzt werden (oder wenn es nur Ihre Sysadmin-Empfindlichkeiten verletzt).

Der Grund für dieses Verhalten besteht darin, zu verhindern, dass mehrere Dienste gleichzeitig ausgelöst werden. Sie können beispielsweise Zeitangaben wie Wöchentlich, Täglich und mehr verwenden. Diese Verknüpfungen sind alle so definiert, dass sie um 00:00:00 Uhr an dem Tag ausgelöst werden, an dem sie ausgelöst werden. Wenn mehrere Timer auf diese Weise angegeben werden, besteht eine hohe Wahrscheinlichkeit, dass sie versuchen, gleichzeitig zu starten.

Systemd-Timer sind absichtlich so konzipiert, dass sie zufällig um die angegebene Zeit herum ausgelöst werden, um zu versuchen, gleichzeitige Trigger zu verhindern. Sie werden halbzufällig innerhalb eines Zeitfensters ausgelöst, das zur angegebenen Auslösezeit beginnt und zur angegebenen Zeit plus einer Minute endet. Diese Auslösezeit wird gemäß systemd.timer in Bezug auf alle anderen definierten Timereinheiten auf einer stabilen Position gehalten Manpage. Sie können in den obigen Journaleinträgen sehen, dass der Timer sofort ausgelöst wurde, als er gestartet wurde, und dann etwa 46 oder 47 Sekunden nach jeder Minute.

Meistens sind solche probabilistischen Auslösezeiten in Ordnung. Beim Planen von Aufgaben wie Backups, die ausgeführt werden sollen, gibt es keine Probleme, solange sie außerhalb der Geschäftszeiten ausgeführt werden. Ein Systemadministrator kann eine deterministische Startzeit auswählen, z. B. 01:05:00 in einer typischen Cron-Job-Spezifikation, um nicht mit anderen Aufgaben in Konflikt zu geraten, aber es gibt eine große Auswahl an Zeitwerten, die dies erreichen. Eine Minute Zufälligkeit in einer Startzeit ist normalerweise irrelevant.

Für einige Aufgaben sind jedoch exakte Auslösezeiten zwingend erforderlich. Für diese können Sie eine größere Trigger-Zeitspannengenauigkeit (bis auf eine Mikrosekunde) angeben, indem Sie eine Anweisung wie diese zum Timer hinzufügen Abschnitt der Timer-Unit-Datei:

AccuracySec=1us

Zeitspannen können verwendet werden, um die gewünschte Genauigkeit anzugeben sowie Zeitspannen für sich wiederholende oder einmalige Ereignisse zu definieren. Es erkennt die folgenden Einheiten:

  • usec, us, µs
  • ms, ms
  • Sekunden, Sekunden, Sekunden, Sekunden
  • Minuten, Minute, Minute, m
  • Stunden, Stunde, Std, h
  • Tage, Tag, T
  • Wochen, Woche, w
  • Monate, Monat, M (definiert als 30,44 Tage)
  • years, year, y (definiert als 365,25 Tage)

Alle Standard-Timer in /usr/lib/systemd/system Geben Sie einen viel größeren Bereich für die Genauigkeit an, da genaue Zeiten nicht kritisch sind. Sehen Sie sich einige der Spezifikationen in den vom System erstellten Timern an:

[root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer
/usr/lib/systemd/system/fstrim.timer:AccuracySec=1h
/usr/lib/systemd/system/logrotate.timer:AccuracySec=1h
/usr/lib/systemd/system/logwatch.timer:AccuracySec=12h
/usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h
/usr/lib/systemd/system/raid-check.timer:AccuracySec=24h
/usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h
[root@testvm1 system]#

Sehen Sie sich den vollständigen Inhalt einiger Timer-Unit-Dateien in /usr/lib/systemd/system an Verzeichnis, um zu sehen, wie sie aufgebaut sind.

Sie müssen den Timer in diesem Experiment nicht aktivieren, um ihn beim Booten zu aktivieren, aber der Befehl dazu wäre:

# systemctl enable myMonitor.timer

Die von Ihnen erstellten Unit-Dateien müssen nicht ausführbar sein. Sie haben das Servicegerät auch nicht aktiviert, weil es durch den Timer getriggert wird. Sie können die Service-Unit weiterhin manuell über die Befehlszeile auslösen, wenn Sie möchten. Versuchen Sie das und beobachten Sie das Tagebuch.

Siehe die Manpages für systemd.timer und systemd.time für weitere Informationen über Timer-Genauigkeit, Ereigniszeitspezifikationen und Trigger-Ereignisse.

Timer-Typen

systemd-Timer haben andere Fähigkeiten, die nicht in cron zu finden sind, die nur an bestimmten, sich wiederholenden Echtzeitdaten und -zeiten ausgelöst werden. Systemd-Timer können so konfiguriert werden, dass sie basierend auf Statusänderungen in anderen Systemd-Einheiten ausgelöst werden. Beispielsweise könnte ein Zeitgeber so konfiguriert werden, dass er eine bestimmte verstrichene Zeit nach dem Systemstart, nach dem Hochfahren oder nach der Aktivierung einer definierten Serviceeinheit auslöst. Diese werden als monotone Timer bezeichnet. Monoton bezieht sich auf eine Zählung oder Folge, die kontinuierlich zunimmt. Diese Timer sind nicht dauerhaft, da sie nach jedem Start zurückgesetzt werden.

Tabelle 1 listet die monotonen Timer zusammen mit einer kurzen Definition von jedem auf, sowie den OnCalendar Timer, der nicht monoton ist und verwendet wird, um zukünftige Zeiten anzugeben, die sich wiederholen können oder nicht. Diese Information wird von systemd.timer abgeleitet Manpage mit ein paar kleinen Änderungen.

Zeitgeber Monoton Definition
OnActiveSec= X Dies definiert einen Timer relativ zu dem Moment, in dem der Timer aktiviert wird.
OnBootSec= X Dies definiert einen Timer relativ zum Hochfahren der Maschine.
OnStartupSec= X Dies definiert einen Timer relativ zum ersten Start des Dienstmanagers. Für System-Timer-Einheiten ist dies sehr ähnlich zu OnBootSec= , da der Systemdienstmanager im Allgemeinen sehr früh beim Booten beginnt. Es ist in erster Linie nützlich, wenn es in Einheiten konfiguriert wird, die im benutzerspezifischen Service-Manager laufen, da der Benutzer-Service-Manager im Allgemeinen nur bei der ersten Anmeldung startet, nicht während des Bootens.
OnUnitActiveSec= X Dies definiert einen Timer relativ dazu, wann der zu aktivierende Timer zuletzt aktiviert wurde.
OnUnitInactiveSec= X Damit wird ein Timer relativ dazu definiert, wann der zu aktivierende Timer zuletzt deaktiviert wurde.
OnCalendar=   Dies definiert Echtzeit-Timer (d. h. Wanduhren) mit Kalenderereignisausdrücken. Siehe systemd.time(7) für weitere Informationen zur Syntax von Kalenderereignisausdrücken. Ansonsten ist die Semantik ähnlich wie bei OnActiveSec= und zugehörige Einstellungen. Dieser Timer ähnelt am ehesten jenen, die mit dem Cron-Dienst verwendet werden.

Tabelle 1:Systemd-Timer-Definitionen

Die monotonen Timer können die gleichen Kurznamen für ihre Zeitspannen verwenden wie AccuracySec zuvor erwähnte Anweisung, aber systemd normalisiert diese Namen auf Sekunden. Beispielsweise möchten Sie möglicherweise einen Timer angeben, der ein Ereignis einmal fünf Tage nach dem Systemstart auslöst. das könnte so aussehen:OnBootSec=5d . Wenn der Host um 2020-06-15 09:45:27 gestartet wurde , würde der Timer um 2020-06-20 09:45:27 ausgelöst oder innerhalb einer Minute danach.

Kalenderereignisspezifikationen

Kalenderereignisspezifikationen sind ein wichtiger Bestandteil beim Auslösen von Timern zu gewünschten sich wiederholenden Zeiten. Sehen Sie sich zunächst einige Spezifikationen an, die mit OnCalendar verwendet werden Einstellung.

systemd und seine Timer verwenden einen anderen Stil für Zeit- und Datumsangaben als das in crontab verwendete Format. Es ist flexibler als crontab und erlaubt unscharfe Datums- und Zeitangaben in der Art von at Befehl. Es sollte auch so vertraut sein, dass es leicht zu verstehen ist.

Das Grundformat für systemd-Timer mit OnCalendar= ist DOW YYYY-MM-DD HH:MM:SS . DOW (Wochentag) ist optional, und andere Felder können ein Sternchen (*) verwenden, um einen beliebigen Wert für diese Position abzugleichen. Alle Kalenderzeitformen werden in eine normalisierte Form konvertiert. Wenn die Uhrzeit nicht angegeben ist, wird 00:00:00 angenommen. Wenn das Datum nicht angegeben ist, aber die Uhrzeit, kann das nächste Spiel je nach aktueller Uhrzeit heute oder morgen stattfinden. Für Monat und Wochentag können Namen oder Zahlen verwendet werden. Kommagetrennte Listen jeder Einheit können angegeben werden. Einheitenbereiche können mit .. angegeben werden zwischen den Anfangs- und Endwerten.

Es gibt ein paar interessante Optionen für die Angabe von Daten. Die Tilde (~) kann verwendet werden, um den letzten Tag des Monats oder eine bestimmte Anzahl von Tagen vor dem letzten Tag des Monats anzugeben. Mit dem „/“ kann ein Wochentag als Modifikator angegeben werden.

Hier sind einige Beispiele einiger typischer Zeitangaben, die in OnCalendar verwendet werden Aussagen.

Kalenderereignisspezifikation Beschreibung
DOW YYYY-MM-DD HH:MM:SS  
*-*-* 00:15:30 Jeden Tag in jedem Monat in jedem Jahr um 15 Minuten und 30 Sekunden nach Mitternacht
Wöchentlich Jeden Montag um 00:00:00
Mo *-*-* 00:00:00 Wie wöchentlich
Mo Wie wöchentlich
Mittwoch 2020-*-* Jeden Mittwoch im Jahr 2020 um 00:00:00
Mo..Fr. 2021-*-* Jeden Wochentag im Jahr 2021 um 00:00:00
2022-6,7,8-1,15 01:15:00 Am 1. und 15. Juni, Juli und August 2022 um 01:15:00 Uhr
Montag *-05~03 Das nächste Vorkommen eines Montags im Mai eines jeden Jahres, der auch der 3. Tag nach dem Ende des Monats ist.
Mo..Fr *-08~04 Der 4. Tag vor Ende August für alle Jahre, in denen er auch auf einen Wochentag fällt.
*-05~03/2 Am 3. Tag nach Ende des Monats Mai und dann noch einmal zwei Tage später. Wiederholt sich jedes Jahr. Beachten Sie, dass dieser Ausdruck die Tilde (~) verwendet.
*-05-03/2 Der dritte Tag des Monats Mai und dann jeden zweiten Tag für den Rest des Monats Mai. Wiederholt sich jedes Jahr. Beachten Sie, dass dieser Ausdruck den Bindestrich (-) verwendet.

Tabelle 2:Beispiel für OnCalendar Veranstaltungsspezifikationen

Testkalenderspezifikationen

systemd bietet ein hervorragendes Werkzeug zum Validieren und Untersuchen von Kalenderzeitereignisspezifikationen in einem Timer. Der systemd-analyze calendar Das Tool parst eine Kalenderzeitereignisspezifikation und stellt die normalisierte Form sowie andere interessante Informationen wie Datum und Uhrzeit des nächsten "Verstreichens", d. h. Übereinstimmung, und die ungefähre Zeitspanne bis zum Erreichen der Auslösezeit bereit.

Betrachten Sie zunächst ein Datum in der Zukunft ohne Uhrzeit (beachten Sie, dass die Zeiten für Next elapse verstreichen und UTC je nach lokaler Zeitzone unterschiedlich):

[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#

Fügen Sie nun eine Zeit hinzu. In diesem Beispiel werden Datum und Uhrzeit separat als nicht verwandte Entitäten analysiert:

[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    

  Original form: 15:21:16                  
Normalized form: *-*-* 15:21:16            
    Next elapse: Mon 2020-06-15 15:21:16 EDT
       (in UTC): Mon 2020-06-15 19:21:16 UTC
       From now: 3h 55min left              
[root@testvm1 system]#

To analyze the date and time as a single unit, enclose them together in quotes. Be sure to remove the quotes when using them in the OnCalendar= event specification in a timer unit or you will get errors:

[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
Normalized form: 2030-06-17 15:21:16        
    Next elapse: Mon 2030-06-17 15:21:16 EDT
       (in UTC): Mon 2030-06-17 19:21:16 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#

Now test the entries in Table 2. I like the last one, especially:

[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
  Original form: 2022-6,7,8-1,15 01:15:00
Normalized form: 2022-06,07,08-01,15 01:15:00
    Next elapse: Wed 2022-06-01 01:15:00 EDT
       (in UTC): Wed 2022-06-01 05:15:00 UTC
       From now: 1 years 11 months left
[root@testvm1 system]#

Let’s look at one example in which we list the next five elapses for the timestamp expression.

[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
  Original form: Mon *-05~3                
Normalized form: Mon *-05~03 00:00:00      
    Next elapse: Mon 2023-05-29 00:00:00 EDT
       (in UTC): Mon 2023-05-29 04:00:00 UTC
       From now: 2 years 11 months left    
       Iter. #2: Mon 2028-05-29 00:00:00 EDT
       (in UTC): Mon 2028-05-29 04:00:00 UTC
       From now: 7 years 11 months left    
       Iter. #3: Mon 2034-05-29 00:00:00 EDT
       (in UTC): Mon 2034-05-29 04:00:00 UTC
       From now: 13 years 11 months left    
       Iter. #4: Mon 2045-05-29 00:00:00 EDT
       (in UTC): Mon 2045-05-29 04:00:00 UTC
       From now: 24 years 11 months left    
       Iter. #5: Mon 2051-05-29 00:00:00 EDT
       (in UTC): Mon 2051-05-29 04:00:00 UTC
       From now: 30 years 11 months left    
[root@testvm1 ~]#

This should give you enough information to start testing your OnCalendar time specifications. The systemd-analyze tool can be used for other interesting analyses, which I will begin to explore in the next article in this series.

Summary

systemd timers can be used to perform the same kinds of tasks as the cron tool but offer more flexibility in terms of the calendar and monotonic time specifications for triggering events.

Even though the service unit you created for this experiment is usually triggered by the timer, you can also use the systemctl start myMonitor.service command to trigger it at any time. Multiple maintenance tasks can be scripted in a single timer; these can be Bash scripts or Linux utility programs. You can run the service triggered by the timer to run all the scripts, or you can run individual scripts as needed.

I will explore systemd's use of time and time specifications in much more detail in the next article.

I have not yet seen any indication that cron and at will be deprecated. I hope that does not happen because at , at least, is much easier to use for one-off task scheduling than systemd timers.

Resources

There is a great deal of information about systemd available on the internet, but much is terse, obtuse, or even misleading. In addition to the resources mentioned in this article, the following webpages offer more detailed and reliable information about systemd startup.

  • The Fedora Project has a good, practical guide to systemd. It has pretty much everything you need to know in order to configure, manage, and maintain a Fedora computer using systemd.
  • The Fedora Project also has a good cheat sheet that cross-references the old SystemV commands to comparable systemd ones.
  • For detailed technical information about systemd and the reasons for creating it, check out Freedesktop.org's description of systemd.
  • Linux.com's "More systemd fun" offers more advanced systemd information and tips.

There is also a series of deeply technical articles for Linux sysadmins by Lennart Poettering, the designer and primary developer of systemd. These articles were written between April 2010 and September 2011, but they are just as relevant now as they were then. Much of everything else good that has been written about systemd and its ecosystem is based on these papers.

  • Rethinking PID 1
  • systemd for Administrators, Part I
  • systemd for Administrators, Part II
  • systemd for Administrators, Part III
  • systemd for Administrators, Part IV
  • systemd for Administrators, Part V
  • systemd for Administrators, Part VI
  • systemd for Administrators, Part VII
  • systemd for Administrators, Part VIII
  • systemd for Administrators, Part IX
  • systemd for Administrators, Part X
  • systemd for Administrators, Part XI

Linux
  1. Wie verwendet Systemd /etc/init.d-Skripte?

  2. Was sollte ich anstelle von windows.h unter Linux verwenden?

  3. wie man python2.7 pip anstelle von default pip verwendet

  4. Wie verwendet man Systemd, um einen Dienst neu zu starten, wenn er ausgefallen ist?

  5. So verwenden Sie erfolgreich das RDAP-Protokoll anstelle von Whois

Warum ich unter Linux exa anstelle von ls verwende

Du liebst Diff nicht? Verwenden Sie stattdessen Meld

Linux vs. Mac OS:15 Gründe, warum Sie Linux anstelle von Mac OS verwenden sollten

So verwenden Sie IPTables anstelle von Firewalld für Fedora 30-31-32

So verwenden Sie journalctl zum Anzeigen und Bearbeiten von Systemd-Protokollen

Kann Windows anstelle von cmd eine Linux-Shell verwenden?