Cron: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Keine Bearbeitungszusammenfassung |
|||
| (47 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
Animation zum Durchklicken: [https://labs.xinux.net/cron-praxis.html Cron und systemd-Timer] | |||
= Chronos Tabula = | |||
Der | * Der Name leitet sich vom griechischen Wort für Zeit ab (chronos), crontab steht für ''cron table'' | ||
* Der Legende nach hat sich der Entwickler dabei verschrieben – eine schöne Anekdote, belegt ist sie nicht | |||
[[Bild:cron-namensherkunft.png]] | |||
* Der cron-Daemon ist eine Jobsteuerung für wiederkehrende Aufgaben, die automatisch zu einer bestimmten Zeit ausgeführt werden sollen (cronjobs). | |||
* z.B. Archivieren und Löschen von Logdateien, Erneuern von Zertifikaten, [https://www.duckdns.org/install.jsp DynDNS] oder andere Programme zur Instandhaltung des Systems | |||
* Der Cron-Daemon überwacht dazu verschiedene Dateien und Verzeichnisse, in denen Anweisungen liegen, die in regelmäßigen Abständen ausgeführt werden sollen (crontabs). | |||
* Beim Start des Daemons wird die Tabelle in den Arbeitsspeicher geladen | |||
* Es wird minütlich nach auszuführenden Jobs und Änderungen im crontab geprüft | |||
= Crontabs = | |||
''' | * Um Syntaxfehler zu vermeiden, werden die Tabellen nicht nur mit dem Texteditor bearbeitet, sondern über den Befehl: '''crontab''' | ||
== User-Crontab == | |||
'''cron. | * Jeder Benutzer des Systems kann eine eigene Crontab erstellen und bearbeiten | ||
* Die Jobs, die darin aufgeführt sind, werden von Cron unter der jeweiligen Benutzerkennung ausgeführt | |||
* Gespeichert wird sie unter ''/var/spool/cron/crontabs/'' (Debian) bzw. ''/var/spool/cron/'' (Rocky) – dort nie direkt bearbeiten, sondern immer mit <code>crontab -e</code> | |||
* Wer Crontabs anlegen darf, regeln ''/etc/cron.allow'' und ''/etc/cron.deny''. Existiert ''cron.allow'', dürfen nur die dort genannten Benutzer | |||
== Systemweiter Crontab == | |||
* Befindet sich unter ''/etc/crontab'' | |||
* Das Format unterscheidet sich etwas von den Benutzercrontabs: es gibt eine zusätzliche Spalte für den Benutzer, unter dem der Job laufen soll | |||
= | == /etc/cron.d/ == | ||
* Hier liegen Dateien im selben Format wie ''/etc/crontab'' – also mit Zeitfeldern und Benutzerspalte | |||
* Nützlich für Snippets, vor allem für Pakete, die eigene Jobs mitbringen | |||
== cron.hourly, cron.daily, cron.weekly, cron.monthly == | |||
* '''Anderes Prinzip:''' Hier liegen keine Crontab-Zeilen, sondern '''ausführbare Skripte ohne jede Zeitangabe''' | |||
* Wann sie laufen, steht in ''/etc/crontab'' bzw. wird von ''anacron'' bestimmt | |||
* Die Datei muss ausführbar sein | |||
* Unter Debian darf sie außerdem keinen Punkt im Namen haben – ''backup.sh'' wird von <code>run-parts</code> ignoriert, ''backup'' läuft. Unter Rocky läuft auch ''backup.sh'' | |||
* Welche Skripte laufen würden, zeigt unter Debian: <code>run-parts --test /etc/cron.daily</code> | |||
= Aufbau einer Crontab-Datei = | |||
* * * * * auszuführender Befehl | * * * * * auszuführender Befehl | ||
| Zeile 58: | Zeile 54: | ||
└──────────── Minute (0-59) | └──────────── Minute (0-59) | ||
z.B. wöchentliches Backup der Heimatverzeichnisse aller Benutzer um 3 Uhr morgens: | |||
0 3 * * 1 tar -zcf /var/backups/home.tgz /home/ | |||
;Achtung beim Prozentzeichen | |||
* In der Crontab bedeutet ein unmaskiertes <code>%</code> einen Zeilenumbruch – alles dahinter wird zur Standardeingabe des Befehls | |||
| | * Datumsformate müssen deshalb maskiert werden: | ||
0 3 * * 1 tar -zcf /var/backups/home-$(date +\%F).tgz /home/ | |||
== Kurzformen == | |||
Statt der fünf Zeitfelder geht auch ein Schlüsselwort: | |||
{| class="wikitable" | |||
! Kurzform !! entspricht | |||
|- | |- | ||
| | | <code>@reboot</code> || einmal nach jedem Systemstart | ||
| | |||
| | |||
|- | |- | ||
| | | <code>@hourly</code> || <code>0 * * * *</code> | ||
| | |||
| | |||
|- | |- | ||
| | | <code>@daily</code> || <code>0 0 * * *</code> | ||
| | |||
| | |||
|- | |- | ||
| | | <code>@weekly</code> || <code>0 0 * * 0</code> | ||
| | |||
| | |||
|- | |- | ||
| | | <code>@monthly</code> || <code>0 0 1 * *</code> | ||
| | |||
| | |||
|} | |} | ||
=Beispiele= | |||
;<nowiki>*</nowiki>/2 - Dieser Eintrag führt die Aufgabe alle 2 Minuten aus. | |||
*/2 * * * * /pfad/zum/skript.sh | |||
;1,3,5,9 - Dieser Eintrag führt die Aufgabe zu bestimmten Minuten aus, nämlich 1, 3, 5 und 9. | |||
1,3,5,9 * * * * /pfad/zum/skript.sh | |||
;5-9 - Dieser Eintrag führt die Aufgabe von Minute 5 bis Minute 9 in jeder Stunde aus. | |||
5-9 * * * * /pfad/zum/skript.sh | |||
= Die Umgebung im Cron = | |||
* Cron startet den Job '''nicht''' in Ihrer Login-Umgebung: <code>PATH</code> ist auf <code>/usr/bin:/bin</code> beschränkt, <code>.bashrc</code> und <code>.profile</code> werden nicht gelesen | |||
* Die Zeile wird mit '''<code>/bin/sh</code>''' ausgeführt, nicht mit bash. Unter Debian ist das <code>dash</code>: Bash-Eigenheiten wie <code>[[ ]]</code>, <code>{1..5}</code> oder <code>source</code> funktionieren dort nicht. Entweder <code>SHELL=/bin/bash</code> oben in die Crontab schreiben oder ein Skript mit eigener Shebang-Zeile aufrufen | |||
* Das ist der häufigste Grund für „im Terminal geht es, im Cron nicht" | |||
* Deshalb im Job absolute Pfade verwenden oder <code>PATH</code> oben in der Crontab setzen: | |||
SHELL=/bin/bash | |||
PATH=/usr/local/bin:/usr/bin:/bin | |||
* Zum Nachsehen, was der Job tatsächlich vorfindet: | |||
* * * * * env > /tmp/cronenv.txt | |||
= Lief der Job? = | |||
* Cron protokolliert jeden Start – unabhängig davon, ob der Befehl selbst funktioniert hat | |||
;Debian | |||
*journalctl -fu cron | |||
;Rocky | |||
*journalctl -u crond -f | |||
* Ausgaben des Befehls gehen per Mail an den Benutzer (bzw. an die Adresse in <code>MAILTO=</code>). Ist kein Mailsystem eingerichtet, sind sie weg – deshalb im Job umleiten: | |||
0 3 * * 1 /pfad/zum/skript.sh >> /var/log/mein-job.log 2>&1 | |||
= Verwaltung von Crontab = | |||
== Eigene Crontab anzeigen == | |||
* '''crontab -l''' | |||
== | == Crontab eines anderen Benutzers anzeigen == | ||
* '''crontab -l -u ''Benutzer''''' (nur als root) | |||
== Crontab bearbeiten == | |||
* '''crontab -e''' | |||
== Crontab löschen == | |||
* '''crontab -r''' | |||
* '''Achtung:''' löscht die komplette Crontab '''ohne Rückfrage'''. Das <code>r</code> liegt auf der Tastatur direkt neben dem <code>e</code> – wer sich bei <code>crontab -e</code> vertippt, ist alle Jobs los. <code>crontab -ri</code> fragt vorher nach. Vorsorge: <code>crontab -l > ~/crontab.bak</code> | |||
== Crontab aus einer Datei lesen == | |||
== | * '''crontab ''/Pfad/zur/Datei''''' | ||
= Alternative Systemd = | |||
* Systemd-Service-Dateien haben auch eine [[Systemd Service timers|Timer]]-Funktion | |||
* Vorteile gegenüber Cron: | |||
** Sekundenauflösung statt Minute – allerdings nur mit <code>AccuracySec=1s</code>; standardmäßig fasst systemd Timer auf eine Minute genau zusammen | |||
** <code>Persistent=true</code> holt verpasste Läufe nach, wenn die Maschine zur fälligen Zeit aus war | |||
** Die Ausgabe landet im Journal und ist mit <code>journalctl -u</code> abrufbar, statt per Mail verloren zu gehen | |||
** Abhängigkeiten zu anderen Units sind möglich | |||
* Alle Timer und ihr nächster Lauf: | |||
*systemctl list-timers | |||
= Aufgaben = | |||
== Aufgaben 1 == | |||
''' | Hinweis: Jobs, die nach ''/var/log'' schreiben oder ''/etc'' lesen, brauchen root – also als root mit <code>crontab -e</code> anlegen. | ||
* Erstellen Sie einen Cron-Job, der jede halbe Stunde den Inhalt von /tmp nach /var/log/tmp.log schreibt. | |||
<!-- Lösung (als root): | |||
crontab -e | |||
*/30 * * * * ls /tmp > /var/log/tmp.log | |||
--> | |||
* Erstellen Sie einen Cron-Job, der von Montag bis Freitag um 11 Uhr die Dateien aus /bin nach /root sichert. | |||
<!-- Lösung: | |||
0 11 * * 1-5 cp -a /bin/ /root/bin-sicherung | |||
Achtung: /bin ist seit usrmerge nur ein Symlink auf usr/bin. cp -a /bin /root würde nur den Link kopieren, | |||
der in /root ins Leere zeigt. Der Schrägstrich hinter /bin/ sorgt dafür, dass das Verzeichnis selbst kopiert wird. | |||
--> | |||
* Erstellen Sie einen Cron-Job, der jede Minute den aktuellen Speicherverbrauch in eine Logdatei schreibt. | |||
<!-- Lösung: | |||
* * * * * free -m >> ~/speicher.log | |||
--> | |||
* Erstellen Sie einen Cron-Job, der jeden Tag um 12 Uhr mittags eine Datei mit dem Datum im Namen anlegt. Achten Sie auf das Prozentzeichen. | |||
<!-- Lösung: | |||
0 12 * * * touch ~/datei_$(date +\%Y\%m\%d).txt | |||
--> | |||
* Erstellen Sie einen Cron-Job, der jeden Montag um 3 Uhr morgens ein Backup Ihres Home-Verzeichnisses erstellt. | |||
<!-- Lösung: | |||
0 3 * * 1 tar -zcf ~/backup_$(date +\%Y\%m\%d).tgz ~/ | |||
--> | |||
* Prüfen Sie im Log, ob die Jobs gestartet wurden. | |||
<!-- Lösung: Debian: journalctl -u cron Rocky: journalctl -u crond | |||
(Debian 12/13 hat ohne rsyslog keine /var/log/syslog mehr) --> | |||
* Lassen Sie sich Ihre Crontab anzeigen und löschen Sie anschließend alle Jobs. | |||
<!-- Lösung: crontab -l > ~/crontab.bak ; crontab -r --> | |||
== Aufgaben 2: Backup-Server mit Cron == | |||
* Installieren Sie nfs-common (Debian) bzw. nfs-utils (Rocky). | |||
<!-- Lösung: apt install -y nfs-common --> | |||
* Erstellen Sie das Verzeichnis /mnt/backup. | |||
<!-- Lösung: mkdir /mnt/backup --> | |||
* Tragen Sie die Freigabe in die /etc/fstab ein: | |||
192.168.6.200:/mnt/data /mnt/backup nfs defaults,_netdev,nofail 0 0 | |||
: <code>_netdev</code>: erst nach dem Netzwerk einhängen; <code>nofail</code>: Startet der Rechner ohne erreichbaren Server, bleibt er nicht im Notfall-Prompt hängen. | |||
* Laden Sie die Konfiguration neu, hängen Sie ein und kontrollieren Sie die Anbindung. | |||
<!-- Lösung: systemctl daemon-reload ; mount -a ; findmnt /mnt/backup --> | |||
* Erstellen Sie in /mnt/backup ein Verzeichnis mit Ihrem Hostnamen. | |||
<!-- Lösung: mkdir /mnt/backup/$(hostname) | |||
Schlägt das als root mit "Permission denied" fehl, exportiert der Server mit root_squash: root wird dort zu nobody. | |||
Dann muss das Verzeichnis auf dem Server beschreibbar sein oder die Freigabe no_root_squash bekommen. --> | |||
* Erstellen Sie einen Cron-Job, der stündlich Ihr /etc in dieses Verzeichnis sichert. Die Sicherung soll einen Namen in der Art '''2024-07-17-15-30-etc''' erhalten. | |||
<!-- Lösung (als root, /etc ist nicht für alle lesbar): | |||
0 * * * * tar -zcf /mnt/backup/$(hostname)/$(date +\%Y-\%m-\%d-\%H-\%M)-etc.tgz /etc | |||
--> | |||
* Warum muss hier besonders auf das Prozentzeichen geachtet werden? | |||
<!-- Lösung: der Dateiname besteht fast nur aus Datumsformaten. Unmaskiert bricht cron die Zeile beim ersten % ab, der Rest wird zur Standardeingabe von tar. --> | |||
Aktuelle Version vom 16. Oktober 2026, 16:17 Uhr
Animation zum Durchklicken: Cron und systemd-Timer
Chronos Tabula
- Der Name leitet sich vom griechischen Wort für Zeit ab (chronos), crontab steht für cron table
- Der Legende nach hat sich der Entwickler dabei verschrieben – eine schöne Anekdote, belegt ist sie nicht
- Der cron-Daemon ist eine Jobsteuerung für wiederkehrende Aufgaben, die automatisch zu einer bestimmten Zeit ausgeführt werden sollen (cronjobs).
- z.B. Archivieren und Löschen von Logdateien, Erneuern von Zertifikaten, DynDNS oder andere Programme zur Instandhaltung des Systems
- Der Cron-Daemon überwacht dazu verschiedene Dateien und Verzeichnisse, in denen Anweisungen liegen, die in regelmäßigen Abständen ausgeführt werden sollen (crontabs).
- Beim Start des Daemons wird die Tabelle in den Arbeitsspeicher geladen
- Es wird minütlich nach auszuführenden Jobs und Änderungen im crontab geprüft
Crontabs
- Um Syntaxfehler zu vermeiden, werden die Tabellen nicht nur mit dem Texteditor bearbeitet, sondern über den Befehl: crontab
User-Crontab
- Jeder Benutzer des Systems kann eine eigene Crontab erstellen und bearbeiten
- Die Jobs, die darin aufgeführt sind, werden von Cron unter der jeweiligen Benutzerkennung ausgeführt
- Gespeichert wird sie unter /var/spool/cron/crontabs/ (Debian) bzw. /var/spool/cron/ (Rocky) – dort nie direkt bearbeiten, sondern immer mit
crontab -e - Wer Crontabs anlegen darf, regeln /etc/cron.allow und /etc/cron.deny. Existiert cron.allow, dürfen nur die dort genannten Benutzer
Systemweiter Crontab
- Befindet sich unter /etc/crontab
- Das Format unterscheidet sich etwas von den Benutzercrontabs: es gibt eine zusätzliche Spalte für den Benutzer, unter dem der Job laufen soll
/etc/cron.d/
- Hier liegen Dateien im selben Format wie /etc/crontab – also mit Zeitfeldern und Benutzerspalte
- Nützlich für Snippets, vor allem für Pakete, die eigene Jobs mitbringen
cron.hourly, cron.daily, cron.weekly, cron.monthly
- Anderes Prinzip: Hier liegen keine Crontab-Zeilen, sondern ausführbare Skripte ohne jede Zeitangabe
- Wann sie laufen, steht in /etc/crontab bzw. wird von anacron bestimmt
- Die Datei muss ausführbar sein
- Unter Debian darf sie außerdem keinen Punkt im Namen haben – backup.sh wird von
run-partsignoriert, backup läuft. Unter Rocky läuft auch backup.sh - Welche Skripte laufen würden, zeigt unter Debian:
run-parts --test /etc/cron.daily
Aufbau einer Crontab-Datei
* * * * * auszuführender Befehl ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ └──── Wochentag (0-7 oder Sun, Mon, Tue,etc) (Sonntag =0 oder =7) │ │ │ └────── Monat (1-12 oder Jan, Feb, etc) │ │ └──────── Tag (1-31) │ └────────── Stunde (0-23) └──────────── Minute (0-59)
z.B. wöchentliches Backup der Heimatverzeichnisse aller Benutzer um 3 Uhr morgens:
0 3 * * 1 tar -zcf /var/backups/home.tgz /home/
- Achtung beim Prozentzeichen
- In der Crontab bedeutet ein unmaskiertes
%einen Zeilenumbruch – alles dahinter wird zur Standardeingabe des Befehls - Datumsformate müssen deshalb maskiert werden:
0 3 * * 1 tar -zcf /var/backups/home-$(date +\%F).tgz /home/
Kurzformen
Statt der fünf Zeitfelder geht auch ein Schlüsselwort:
| Kurzform | entspricht |
|---|---|
@reboot |
einmal nach jedem Systemstart |
@hourly |
0 * * * *
|
@daily |
0 0 * * *
|
@weekly |
0 0 * * 0
|
@monthly |
0 0 1 * *
|
Beispiele
- */2 - Dieser Eintrag führt die Aufgabe alle 2 Minuten aus.
*/2 * * * * /pfad/zum/skript.sh
- 1,3,5,9 - Dieser Eintrag führt die Aufgabe zu bestimmten Minuten aus, nämlich 1, 3, 5 und 9.
1,3,5,9 * * * * /pfad/zum/skript.sh
- 5-9 - Dieser Eintrag führt die Aufgabe von Minute 5 bis Minute 9 in jeder Stunde aus.
5-9 * * * * /pfad/zum/skript.sh
Die Umgebung im Cron
- Cron startet den Job nicht in Ihrer Login-Umgebung:
PATHist auf/usr/bin:/binbeschränkt,.bashrcund.profilewerden nicht gelesen - Die Zeile wird mit
/bin/shausgeführt, nicht mit bash. Unter Debian ist dasdash: Bash-Eigenheiten wie[[ ]],{1..5}odersourcefunktionieren dort nicht. EntwederSHELL=/bin/bashoben in die Crontab schreiben oder ein Skript mit eigener Shebang-Zeile aufrufen - Das ist der häufigste Grund für „im Terminal geht es, im Cron nicht"
- Deshalb im Job absolute Pfade verwenden oder
PATHoben in der Crontab setzen:
SHELL=/bin/bash PATH=/usr/local/bin:/usr/bin:/bin
- Zum Nachsehen, was der Job tatsächlich vorfindet:
* * * * * env > /tmp/cronenv.txt
Lief der Job?
- Cron protokolliert jeden Start – unabhängig davon, ob der Befehl selbst funktioniert hat
- Debian
- journalctl -fu cron
- Rocky
- journalctl -u crond -f
- Ausgaben des Befehls gehen per Mail an den Benutzer (bzw. an die Adresse in
MAILTO=). Ist kein Mailsystem eingerichtet, sind sie weg – deshalb im Job umleiten:
0 3 * * 1 /pfad/zum/skript.sh >> /var/log/mein-job.log 2>&1
Verwaltung von Crontab
Eigene Crontab anzeigen
- crontab -l
Crontab eines anderen Benutzers anzeigen
- crontab -l -u Benutzer (nur als root)
Crontab bearbeiten
- crontab -e
Crontab löschen
- crontab -r
- Achtung: löscht die komplette Crontab ohne Rückfrage. Das
rliegt auf der Tastatur direkt neben deme– wer sich beicrontab -evertippt, ist alle Jobs los.crontab -rifragt vorher nach. Vorsorge:crontab -l > ~/crontab.bak
Crontab aus einer Datei lesen
- crontab /Pfad/zur/Datei
Alternative Systemd
- Systemd-Service-Dateien haben auch eine Timer-Funktion
- Vorteile gegenüber Cron:
- Sekundenauflösung statt Minute – allerdings nur mit
AccuracySec=1s; standardmäßig fasst systemd Timer auf eine Minute genau zusammen Persistent=trueholt verpasste Läufe nach, wenn die Maschine zur fälligen Zeit aus war- Die Ausgabe landet im Journal und ist mit
journalctl -uabrufbar, statt per Mail verloren zu gehen - Abhängigkeiten zu anderen Units sind möglich
- Sekundenauflösung statt Minute – allerdings nur mit
- Alle Timer und ihr nächster Lauf:
- systemctl list-timers
Aufgaben
Aufgaben 1
Hinweis: Jobs, die nach /var/log schreiben oder /etc lesen, brauchen root – also als root mit crontab -e anlegen.
- Erstellen Sie einen Cron-Job, der jede halbe Stunde den Inhalt von /tmp nach /var/log/tmp.log schreibt.
- Erstellen Sie einen Cron-Job, der von Montag bis Freitag um 11 Uhr die Dateien aus /bin nach /root sichert.
- Erstellen Sie einen Cron-Job, der jede Minute den aktuellen Speicherverbrauch in eine Logdatei schreibt.
- Erstellen Sie einen Cron-Job, der jeden Tag um 12 Uhr mittags eine Datei mit dem Datum im Namen anlegt. Achten Sie auf das Prozentzeichen.
- Erstellen Sie einen Cron-Job, der jeden Montag um 3 Uhr morgens ein Backup Ihres Home-Verzeichnisses erstellt.
- Prüfen Sie im Log, ob die Jobs gestartet wurden.
- Lassen Sie sich Ihre Crontab anzeigen und löschen Sie anschließend alle Jobs.
Aufgaben 2: Backup-Server mit Cron
- Installieren Sie nfs-common (Debian) bzw. nfs-utils (Rocky).
- Erstellen Sie das Verzeichnis /mnt/backup.
- Tragen Sie die Freigabe in die /etc/fstab ein:
192.168.6.200:/mnt/data /mnt/backup nfs defaults,_netdev,nofail 0 0
_netdev: erst nach dem Netzwerk einhängen;nofail: Startet der Rechner ohne erreichbaren Server, bleibt er nicht im Notfall-Prompt hängen.
- Laden Sie die Konfiguration neu, hängen Sie ein und kontrollieren Sie die Anbindung.
- Erstellen Sie in /mnt/backup ein Verzeichnis mit Ihrem Hostnamen.
- Erstellen Sie einen Cron-Job, der stündlich Ihr /etc in dieses Verzeichnis sichert. Die Sicherung soll einen Namen in der Art 2024-07-17-15-30-etc erhalten.
- Warum muss hier besonders auf das Prozentzeichen geachtet werden?
