So ist ein Cron-Ausdruck aufgebaut
Cron ist der Zeitplaner auf jedem Linux-Server. Jede Zeile einer crontab besteht aus fünf Zeitfeldern und dem Befehl. Ein Feld mit * bedeutet „jeder Wert“. Die Felder werden von links nach rechts gelesen: Minute, Stunde, Tag des Monats, Monat, Wochentag.
| Feld | Erlaubte Werte | Beispiel | Bedeutung |
|---|---|---|---|
| Minute | 0 bis 59 | 30 | zur Minute 30 |
| Stunde | 0 bis 23 | 3 | um 3 Uhr nachts |
| Tag des Monats | 1 bis 31 | 1,15 | am 1. und 15. |
| Monat | 1 bis 12 oder JAN bis DEC | */3 | Januar, April, Juli, Oktober |
| Wochentag | 0 bis 7 oder SUN bis SAT | 1-5 | Montag bis Freitag |
Beim Wochentag sind 0 und 7 beide Sonntag. Namen wie MON oder JAN sind englisch und unabhängig von Groß- und Kleinschreibung.
Sonderzeichen
| Zeichen | Bedeutung | Beispiel |
|---|---|---|
* | jeder Wert des Feldes | * * * * * läuft jede Minute |
, | Liste einzelner Werte | 0,30 zur Minute 0 und 30 |
- | Bereich, beide Enden eingeschlossen | 9-17 von 9 bis 17 Uhr |
/ | Schrittweite nach * oder einem Bereich | */15 alle 15 Minuten, 8-18/2 jede zweite Stunde von 8 bis 18 |
@reboot | einmal beim Start des Cron-Dienstes | @reboot /usr/local/bin/start.sh |
@hourly, @daily, @weekly, @monthly, @yearly | Kurzformen für 0 * * * *, 0 0 * * *, 0 0 * * 0, 0 0 1 * *, 0 0 1 1 * | @daily /root/backup.sh |
Ein Schritt nach einer einzelnen Zahl wie 5/10 wird von manchen Generatoren akzeptiert, vom Cron unter Debian und Ubuntu aber abgelehnt. Schreibe stattdessen 5-59/10.
Tag und Wochentag zugleich: ODER statt UND
Die häufigste Überraschung: Sind sowohl der Tag des Monats als auch der Wochentag eingeschränkt, läuft der Job, wenn eine der beiden Bedingungen zutrifft. 30 2 13 * 5 heißt also nicht „Freitag, der 13.“, sondern „am 13. jedes Monats und zusätzlich jeden Freitag“. Steht in einem der beiden Felder ein *, zählt nur das andere. Wer wirklich nur Freitag, den 13. will, prüft den Tag im Befehl selbst:
30 2 13 * * [ "$(date +\%u)" = 5 ] && /root/freitag13.shDer Generator oben berechnet die nächsten Termine genau nach dieser Regel, so wie der Cron unter Debian sie auswertet.
Fallstricke, die in der Praxis Zeit kosten
PATH ist fast leer
Cron startet Befehle mit einer minimalen Umgebung, meist nur PATH=/usr/bin:/bin. Was in der Shell funktioniert, scheitert im Cronjob mit „command not found“. Verwende absolute Pfade (/usr/bin/php, /usr/local/bin/wp) oder setze oben in der crontab eine eigene Zeile PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin. Den Pfad eines Programms zeigt command -v php.
Das Prozentzeichen
In einer crontab ist % ein Sonderzeichen: Es beendet den Befehl, alles danach wird als Standardeingabe übergeben. date +%F muss deshalb als date +\%F geschrieben werden. Der Generator oben maskiert Prozentzeichen im Befehl automatisch.
Zeitzone des Servers
Cron rechnet in der Zeitzone des Servers, nicht in deiner. Die Termine oben zeigt der Generator in der Zeitzone deines Browsers. Mit timedatectl siehst du die Serverzeitzone. Bei der Zeitumstellung im Frühjahr fällt die Stunde von 2 bis 3 Uhr weg. Jobs um 2:30 Uhr holt der Cron unter Debian dann direkt nach, im Herbst laufen sie trotz doppelter Stunde nur einmal. Wichtige Jobs legst du trotzdem besser außerhalb dieser Stunde.
Ausgabe und MAILTO
Alles, was ein Job ausgibt, schickt Cron per Mail an den Besitzer der crontab. Ohne funktionierenden lokalen Mailversand verschwindet die Ausgabe, mit funktionierendem Mailversand füllt sich womöglich ein Postfach. Steuere das bewusst: MAILTO="admin@example.de" am Anfang der crontab für Fehlermeldungen per Mail, MAILTO="" zum Abschalten, oder die Ausgabe mit >> /var/log/job.log 2>&1 in eine Logdatei umleiten. > /dev/null 2>&1 verwirft alles, auch Fehler. Das ist bequem, aber du merkst dann nicht, wenn der Job scheitert.
Überlappende Läufe
Dauert ein Job länger als sein Intervall, startet Cron ihn trotzdem erneut. Bei Backups oder Importen führt das zu doppelter Last oder beschädigten Daten. flock -n /tmp/job.lock befehl startet den Befehl nur, wenn keine andere Instanz die Sperre hält. Die Option oben baut das ein.
Plesk: Aufgaben im Panel anlegen
In Plesk legst du Cronjobs für ein Abonnement unter Websites & Domains, Geplante Aufgaben an. Plesk schreibt sie in die crontab des Systembenutzers des Abonnements. Wenn du dieselbe crontab parallel per crontab -e -u benutzer bearbeitest, können Panel und Datei auseinanderlaufen. Bleib daher bei einem Weg. Bei Abonnements mit chroot-Shell stehen im Cronjob nur die Programme der chroot-Umgebung zur Verfügung, PHP rufst du dort über die Plesk-PHP-Version auf, etwa /opt/plesk/php/8.3/bin/php.
Beispiele
| Ausdruck | Bedeutung |
|---|---|
*/5 * * * * | alle 5 Minuten, etwa für die WordPress-Aufgaben per wp cron event run --due-now |
*/15 9-17 * * 1-5 | alle 15 Minuten zwischen 9:00 und 17:59 Uhr, Montag bis Freitag |
0 3 * * * | täglich um 3 Uhr, klassisch für Backups |
30 4 * * 0 | sonntags um 4:30 Uhr, etwa für Logrotation oder Updates |
0 0 1,15 * * | am 1. und 15. jedes Monats um Mitternacht |
0 */6 * * * | alle 6 Stunden: 0, 6, 12 und 18 Uhr |
0 2 1 */3 * | quartalsweise am 1. um 2 Uhr (Januar, April, Juli, Oktober) |
@reboot | einmal nach jedem Neustart des Servers |
Bestehende Jobs eines Benutzers zeigt crontab -l, die systemweiten liegen in /etc/crontab und /etc/cron.d/. Ob ein Job gelaufen ist, verrät grep CRON /var/log/syslog oder auf Systemen ohne syslog journalctl -u cron.