Ein Cron-Ausdruck ist eine Zeile aus fünf durch Leerzeichen getrennten Feldern, die beschreibt, wann eine Aufgabe laufen soll: Minute, Stunde, Tag des Monats, Monat und Wochentag. 0 9 * * 1-5 bedeutet „um 9:00 von Montag bis Freitag“. Dieselbe Syntax verwenden die crontab unter Linux und macOS, GitHub Actions, Kubernetes und die meisten Scheduler, mit kleinen Unterschieden, die man kennen sollte.
Dieser Artikel erklärt jedes Feld, die vier Sonderzeichen, die Fälle, die am häufigsten verwirren (Sonntag als 0 oder 7, die Kombination aus Monatstag und Wochentag, Zeitzonen), und sammelt Beispiele zum Kopieren.
Die fünf Felder
┌───────────── Minute (0-59)
│ ┌───────────── Stunde (0-23)
│ │ ┌───────────── Tag des Monats (1-31)
│ │ │ ┌───────────── Monat (1-12 oder jan-dec)
│ │ │ │ ┌───────────── Wochentag (0-6, Sonntag = 0; oft auch 7 = Sonntag, und mon-sun)
│ │ │ │ │
* * * * * Befehl
Die Reihenfolge ist immer gleich. Englische Kurznamen (jan, mon) akzeptieren die meisten Implementierungen, Zahlen funktionieren aber überall und sind deshalb die sichere Wahl.
Die vier Sonderzeichen
| Zeichen | Bedeutung | Beispiel |
|---|---|---|
* |
Jeder Wert | * * * * * jede Minute |
, |
Liste von Werten | 0 9,18 * * * um 9:00 und um 18:00 |
- |
Bereich | 0 9 * * 1-5 um 9:00 von Montag bis Freitag |
/ |
Schritt | */15 * * * * alle 15 Minuten (0, 15, 30, 45) |
Sie lassen sich kombinieren: 0 8-20/2 * * 1-5 läuft werktags alle zwei Stunden zwischen 8:00 und 20:00. Ein Detail zum Schritt: */15 im Minutenfeld beginnt bei 0; 5/15 (in manchen Implementierungen gültig, nicht in POSIX) würde bei Minute 5 beginnen.
Beispiele zum Kopieren
| Ausdruck | Wann er läuft |
|---|---|
*/5 * * * * |
Alle 5 Minuten |
0 * * * * |
Jede volle Stunde |
30 2 * * * |
Täglich um 2:30 |
0 9 * * 1-5 |
Montag bis Freitag um 9:00 |
0 10 * * 6,0 |
Samstags und sonntags um 10:00 |
0 0 1 * * |
Am 1. jedes Monats um Mitternacht |
0 0 1 1 * |
Am 1. Januar um Mitternacht |
0 6 * * 1 |
Montags um 6:00 |
0 */6 * * * |
Alle 6 Stunden (0:00, 6:00, 12:00, 18:00) |
15 14 1 * * |
Am 1. jedes Monats um 14:15 |
Wenn du einen Ausdruck prüfen willst, bevor er in Produktion geht, übersetzt ihn das Cron-Werkzeug von AIMRAN Tools in natürliche Sprache und zeigt die nächsten Ausführungen. Das erspart die klassische Überraschung, den Fehler erst zu entdecken, wenn der Job schon nicht gelaufen ist.
Die drei Punkte, die am meisten verwirren
1. Monatstag und Wochentag werden mit „oder“ verknüpft
Laut crontab(5) läuft der Job, wenn beide Felder einen anderen Wert als * haben, sobald einer von beiden zutrifft. 0 9 13 * 5 bedeutet nicht „Freitag, der 13.“, sondern „an jedem 13. um 9:00 und zusätzlich an jedem Freitag um 9:00“. Für „Freitag, der 13.“ muss der Wochentag im Befehl selbst geprüft werden.
2. Sonntag ist 0 (und meist auch 7)
Der POSIX-Standard definiert Sonntag als 0. Vixie cron (der übliche unter Linux) akzeptiert zusätzlich 7. Andere Scheduler nicht, also nutze 0, wenn du portabel bleiben willst.
3. Die Zeitzone steht nicht im Ausdruck
Ein Cron-Ausdruck trägt keine Zeitzone: Er wird in der Zeitzone des ausführenden Systems interpretiert. In GitHub Actions ist das immer UTC, sodass 0 9 * * 1-5 um 9:00 UTC läuft (11:00 in Deutschland im Sommer). In Kubernetes kannst du der CronJob-Spezifikation timeZone: "Europe/Berlin" hinzufügen. Auf einem Linux-Server hängt es von der Systemkonfiguration oder von der Variable CRON_TZ ab, falls der Cron sie unterstützt.
Unterschiede zwischen Umgebungen
| Umgebung | Besonderheiten |
|---|---|
Linux / macOS (crontab -e) |
Fünf Felder. Vixie cron kennt Kürzel wie @daily, @hourly, @weekly, @monthly, @reboot. Die Ausgabe geht per lokaler Mail, wenn sie nicht umgeleitet wird. |
GitHub Actions (on: schedule) |
Fünf Felder in Anführungszeichen, UTC, Mindestintervall 5 Minuten. Läufe können sich bei hoher Last verzögern, und der Scheduler wird in Repositories ohne Aktivität nach 60 Tagen deaktiviert. |
Kubernetes (CronJob) |
Fünf Felder, unterstützt timeZone, Kürzel wie @hourly und Nebenläufigkeitsregeln (concurrencyPolicy). |
| Manche Werkzeuge (Quartz, Spring, einige Cloud-Dienste) | Ergänzen vorne ein sechstes Feld für Sekunden oder hinten ein siebtes für das Jahr. Ein dort eingefügter Fünf-Felder-Ausdruck verschiebt sich und ändert seine Bedeutung komplett. |
Gute Praxis
- Prüfe den Ausdruck mit einem Werkzeug, das die nächsten Ausführungen anzeigt, bevor du ihn speicherst.
- Dokumentiere die Absicht in einem Kommentar darüber (
# tägliches Backup 2:30), denn der Ausdruck allein ist nicht auf einen Blick lesbar. - Vermeide volle Stunden, wenn es nicht nötig ist: Viele Jobs ballen sich bei
0 0 * * *und0 * * * *; ein paar Minuten Versatz verteilen die Last (genau das tun Cloud-Scheduler selbst). - Leite die Ausgabe um (
>> /var/log/job.log 2>&1), damit Cron keine Mails anhäuft und du debuggen kannst. - Mach den Job idempotent: Wenn Cron ihn zweimal startet oder er sich mit dem vorherigen Lauf überschneidet, darf nichts kaputtgehen. Ein Lock (
flock -n) verhindert Überschneidungen.
Fazit
Fünf Felder, vier Symbole und drei Fallen: das „oder“ zwischen Monatstag und Wochentag, Sonntag als 0 und die Zeitzone des Systems. Damit deckst du fast jede Planung ab. Und bevor du einem Ausdruck vertraust, prüfe ihn: Zwei Minuten mit einem Prüfwerkzeug sparen einen Job, der um 2:30 nachts still nicht gelaufen ist.