Zum Inhalt springen
OneKitly

Wie man einen Cron-Ausdruck schreibt: fünf Felder und die ODER-Regel, die niemand erwähnt

Veröffentlicht am 21.5.2026 · 9 Min. Lesezeit · Entwickler-Tools

Daniel Okonkwo

Daniel OkonkwoFront-end-Entwickler und Tech-Redakteur bei OneKitly

Web-Performance · Dateiformate

Anhand von 2 Quellen geprüft

Profil ansehen
Kurz gesagt

Ein Cron-Ausdruck besteht aus fünf durch Leerzeichen getrennten Feldern, von links nach rechts gelesen: Minute (0-59), Stunde (0-23), Tag des Monats (1-31), Monat (1-12 oder dreibuchstabige Namen) und Wochentag (in POSIX 0-6 mit 0 als Sonntag, von den meisten Implementierungen auf 0-7 erweitert, sodass auch 7 Sonntag ist). Ein Sternchen steht für alle Werte im Bereich des Feldes. Ein Bindestrich bildet einen einschließenden Bereich: 8-11 im Stundenfeld sind 8, 9, 10 und 11. Ein Komma bildet eine Liste, und Listen und Bereiche lassen sich mischen: 1-3,7-9. Ein Schrägstrich fügt einen Schritt hinzu, und genau hier geht es beim ersten Mal schief — ein Schritt durchläuft einen Bereich und setzt kein Intervall: */15 im Minutenfeld bedeutet 0, 15, 30 und 45, und */40 bedeutet 0 und 40 und danach nichts mehr, bis die nächste Stunde den Bereich neu startet. Die zweite, größere Falle: Tag des Monats und Wochentag werden mit ODER verknüpft, nicht mit UND. Sind beide eingeschränkt, läuft der Job, sobald eines von beiden zutrifft. 0 0 1 * 1 bedeutet also nicht den ersten Montag des Monats; es läuft um Mitternacht am 1. jedes Monats UND um Mitternacht an jedem Montag. Um einen Job auf einen bestimmten Wochentag festzunageln, lässt man den Tag des Monats als Sternchen stehen — und umgekehrt. Alles Weitere, das dir begegnet — @daily, ein sechstes Sekundenfeld, das Zeichen ?, L, W und # — liegt außerhalb des Standards und hängt vollständig davon ab, welches Cron du betreibst.

Minute, Stunde, Tag des Monats, Monat, Wochentag. Die Fallen: Ein Schritt ist eine Schrittweite durch einen Bereich und kein Intervall, und die beiden Tagesfelder werden mit ODER verknüpft — 0 0 1 * 1 läuft also am 1. und an jedem Montag.

Fünf Felder, und ein Schritt ist kein Intervall

Lies die Felder von links nach rechts, und die Notation passt in den Kopf. Das Sternchen steht für den gesamten Bereich seines Feldes. Der Bindestrich bildet einen einschließenden Bereich: 8-11 im Stundenfeld sind vier Stunden, nicht drei. Das Komma bildet eine Liste, und Listen und Bereiche lassen sich im selben Feld frei kombinieren: 1-3,7-9 ist eine gültige Menge aus sechs Werten. In den Feldern Monat und Wochentag dürfen dreibuchstabige Namen die Zahlen ersetzen, doch klassisches Vixie-Cron akzeptiert weder Bereiche noch Listen aus Namen — 1-3 wird gelesen, wo JAN-MAR scheitern kann, ein guter Grund, in allem Portablen bei Zahlen zu bleiben.

Beim Schrägstrich zerbricht das mentale Modell meist. Ein Schritt durchläuft einen Bereich, er ist kein Wiederholungsintervall, und der Bereich beginnt zu Beginn jeder übergeordneten Einheit von vorn. Im Minutenfeld läuft */15 über 0, 15, 30, 45, dann wechselt die Stunde und es beginnt wieder bei 0 — was zufällig genau alle fünfzehn Minuten ergibt, weshalb niemand den Unterschied bemerkt. Schreibe */40, und die Illusion bricht zusammen: Es läuft über 0 und 40, dann wechselt die Stunde und es beginnt wieder bei 0, was Abstände von vierzig und dann zwanzig Minuten ergibt. Für einen begrenzten Bereich gilt dasselbe: 0-23/2 im Stundenfeld sind die geraden Stunden, und 1-9/2 sind 1, 3, 5, 7 und 9. Brauchst du wirklich ein Intervall, das seine Einheit nicht glatt teilt, kann Cron das nicht in einer Zeile ausdrücken — dann braucht es zwei Einträge oder eine Absicherung im Befehl selbst.

Die beiden Tagesfelder werden mit ODER verknüpft, nicht mit UND

Das ist die Regel, die die meisten Erklärungen falsch wiedergeben, und sie ist keine Eigenart einer Implementierung — sie steht in der Spezifikation. POSIX legt fest: Sind der Tag des Monats als Element oder Liste und ebenso der Wochentag als Element oder Liste angegeben, so gilt jeder Tag, der entweder auf den Tag des Monats oder auf den Wochentag passt. Das Handbuch crontab(5) sagt dasselbe schlichter und liefert das kanonische Beispiel: 30 4 1,15 * 5 läuft um 4:30 Uhr morgens am 1. und am 15. jedes Monats, dazu an jedem Freitag. Nicht am 1. oder 15., wenn diese auf einen Freitag fallen. Beide Mengen, vereinigt.

Die praktischen Regeln daraus sind kurz. Ist genau eines der beiden Tagesfelder ein Sternchen, bestimmt das andere, und es gibt keine Mehrdeutigkeit — dieser Fall sollte fast immer der geschriebene sein. Sind beide Sternchen, passt jeder Tag, ebenfalls eindeutig. Nur wenn beide eingeschränkt sind, greift die Vereinigung, und das Ergebnis ist fast nie das Gemeinte: 0 0 1 * 1 läuft rund fünfmal im Monat statt einmal. Für die Schnittmenge gibt es keine Cron-Syntax; brauchst du wirklich den ersten Montag des Monats, ist der übliche Kniff, die Vereinigung zu planen und sie im Befehl einzuengen — auf 0 0 1-7 * 1 laufen lassen und das Skript mit einer Prüfung öffnen, dass der Wochentag Montag ist, oder auf 0 0 * * 1 mit einer Prüfung, dass der Tag des Monats höchstens 7 ist. Crons im Quartz-Stil bieten dafür einen Operator #, im System-Cron gibt es ihn nicht.

Alles jenseits der fünf Felder ist implementierungsabhängig

POSIX definiert fünf Felder, das Sternchen, Bereiche, Listen — sonst nichts. Jede Bequemlichkeit darüber hinaus ist eine Erweiterung, und Erweiterungen unterscheiden sich. Der Schrägstrich-Schritt ist eine Vixie-Erweiterung, heute nahezu universell, aber weiterhin nicht im Standard. Die Kurzformen — @yearly mit dem Synonym @annually, @monthly, @weekly, @daily mit dem Synonym @midnight, @hourly und @reboot — stammen aus derselben Linie, und gerade @reboot hat systemübergreifend keine feste Bedeutung, weil vom Dienst abhängt, was als Neustart gilt. Ein sechstes Feld für Sekunden ist in Anwendungs-Schedulern wie Quartz, Spring und mehreren Node-Bibliotheken üblich und fehlt im System-Cron: Ein aus einer Framework-Dokumentation in eine Crontab kopierter Ausdruck ist um ein Feld verschoben und plant etwas völlig anderes, statt laut zu scheitern.

Das Fragezeichen gehört zur selben Familie. In Quartz bedeutet es kein bestimmter Wert und existiert genau dafür, die Mehrdeutigkeit zwischen Tag des Monats und Wochentag aufzulösen, indem ein Feld für unerheblich erklärt wird; System-Cron akzeptiert es überhaupt nicht. Die Operatoren L, W und # für letzter Tag des Monats, nächster Werktag und n-ter Wochentag sind ebenfalls nur in Quartz zu Hause. Zwei Umgebungsfakten wiegen schwerer als diese ganze Syntax: Der Dienst führt Jobs in der Zeitzone aus, für die er konfiguriert ist, sodass ein in einer Umgebung korrekter Ausdruck in einer anderen eine Stunde zu früh oder zu spät auslöst, und rund um eine Zeitumstellung läuft ein in der übersprungenen Stunde geplanter Job womöglich gar nicht, während einer in der wiederholten Stunde zweimal laufen kann. Und Cron ist ein Auslöser, kein Job-Runner — keine Wiederholungen, keine Nebenläufigkeitskontrolle, keine Erinnerung daran, dass der letzte Lauf fehlschlug. Dürfen sich zwei Aufrufe nicht überlappen, setze die Sperre im Befehl selbst.

Die fünf Felder in der Reihenfolge, mit dem Fehler, zu dem jedes verleitet
PositionFeldZulässige WerteDer Fehler, zu dem es verleitet
1.Minute0-59Hier * schreiben, wo 0 gemeint war — ein Ausdruck wie * 3 * * * läuft sechzigmal, in jeder Minute der 3-Uhr-Stunde
2.Stunde0-23In einer 12-Stunden-Uhr denken: Es gibt keine 24 und kein pm, Mitternacht ist 0 und 23 Uhr ist 23
3.Tag des Monats1-3131 verwenden und zwölf Läufe im Jahr erwarten: Kürzere Monate treffen schlicht nie zu, der Job überspringt also stillschweigend Februar, April, Juni, September und November
4.Monat1-12 oder JAN bis DECAnnehmen, dass Namen überall funktionieren: Klassisches Vixie-Cron akzeptiert dreibuchstabige Namen, lehnt aber Bereiche oder Listen davon ab — JAN-MAR kann also scheitern, wo 1-3 funktioniert
5.WochentagIn POSIX 0-6 mit 0 als Sonntag; in den meisten Implementierungen 0-7, wobei auch 7 Sonntag istDieses Feld und den Tag des Monats gleichzeitig einschränken: Beide werden mit ODER verknüpft, der Job läuft also an beiden Tagesmengen statt an deren Schnittmenge
Cron-Ausdruck-GeneratorBaue einen Cron-Zeitplan Feld für Feld — Minute, Stunde, Tag des Monats, Monat, Wochentag — und sieh Ausdruck und Klartext-Beschreibung live aktualisieren. Vorlagen decken die gängigen Zeitpläne ab, und die Syntax (*, */5, 1-5, 1,15) wird erklärt.Tool ausprobieren

Häufige Fragen

Was bedeutet */15 genau?
Im Minutenfeld wählt es die Werte 0, 15, 30 und 45 — eine Schrittweite von fünfzehn durch den Bereich 0 bis 59, beginnend beim ersten Wert des Bereichs. Es ist kein Timer, der fünfzehn Minuten nach dem letzten Lauf auslöst, und es überlebt keine unsaubere Teilung: */40 im Minutenfeld wählt nur 0 und 40, die Abstände betragen also vierzig Minuten und dann zwanzig, wenn die nächste Stunde den Bereich neu startet. Willst du ein Intervall, das ab dem letzten Lauf und nicht ab dem Stundenbeginn misst, ist Cron das falsche Werkzeug — ein systemd-Timer mit OnUnitActiveSec oder eine Schleife in einem langlebigen Prozess ist das richtige.
Wie führe ich einen Job alle 90 Minuten aus?
Nicht in einer Zeile, denn 90 teilt 60 nicht, und ein Schritt bleibt auf ein einzelnes Feld beschränkt. Das Muster wiederholt sich allerdings alle drei Stunden, sodass zwei Einträge es exakt abdecken: 0 */3 * * * ergibt 00:00, 03:00, 06:00 und so fort, und 30 1-23/3 * * * ergibt 01:30, 04:30, 07:30 und so fort. Zusammen ergeben sie einen Lauf alle neunzig Minuten, und die Folge schließt um Mitternacht sauber, weil vierundzwanzig Stunden genau sechzehn Neunzig-Minuten-Intervalle sind. Derselbe Zwei-Einträge-Kniff funktioniert für jedes Intervall, das eine ganze Stundenzahl glatt teilt; was das nicht tut, etwa alle 50 Minuten, lässt sich in Cron überhaupt nicht ausdrücken.
Warum lief mein nächtlicher Job zweimal — oder gar nicht?
Die übliche Ursache ist eine Zeitumstellung. Cron vergleicht die Uhrzeit an der Wand: Springt die Uhr vor, wird eine nie existierende Stunde auch nie getroffen, und ein darin geplanter Job läuft schlicht nicht; fällt die Uhr zurück, tritt eine Stunde zweimal auf, und ein darin geplanter Job kann zweimal auslösen. Die Implementierungen unterscheiden sich darin, wie sehr sie das ausgleichen — deshalb verhält sich dieselbe Crontab auf zwei Distributionen anders. Verlässliche Abhilfen: heikle Jobs außerhalb des Umstellungsfensters planen, den Dienst in einer Zeitzone ohne Umstellungen betreiben, oder den Befehl selbst gefahrlos zweimal ausführbar machen. Letzteres lohnt sich ohnehin: Idempotenz schützt auch vor Wiederholungen, überlappenden Läufen und manuellem Nachstarten.

Artikel, die dich interessieren könnten

Alle Ratgeber
ErklärungWie Unix-Dateirechte funktionieren: 755 lesen, ohne zu ratenLesen ist 4, Schreiben 2, Ausführen 1, und jede der drei Ziffern beschreibt eine andere Partei. Was die meisten Erklärungen falsch darstellen: Bei einem Verzeichnis gewährt das Ausführungsbit den Durchgang, nicht das Recht, etwas zu starten.RatgeberHTTP-Statuscodes erklärt: die, die wirklich verwechselt werden301 gegen 308, 302 gegen 307, 401 gegen 403, 404 gegen 410 — dazu, was Retry-After bei einem 429 oder 503 wirklich zusagt. Die Paare, bei denen der falsche Code das Verhalten ändert und nicht nur die Formulierung.ErklärungWas ist ein Cron-Ausdruck?Ein Cron-Ausdruck plant, dass eine Aufgabe zu festgelegten Zeiten automatisch läuft. Hier steht, wofür er ist, seine fünf Felder, wie man ihn liest und die häufigen Fallstricke.AnleitungWie man eine robots.txt schreibt: Direktiven, Abgleich und was sie nicht verbergen kannVier Direktiven, zwei Platzhalter, eine Datei im Wurzelverzeichnis des Hosts. Sie ist eine Crawl-Anweisung und nicht mehr — sie entfernt keine Seite aus den Ergebnissen, beschränkt keinen Zugriff und veröffentlicht jeden Pfad, den du darin auflistest.ErklärungWas ein Verfügbarkeitsprozentsatz wirklich erlaubtDrei Neunen klingen nach einem Versprechen — bis man sie in Minuten teilt. Was 99,9 % pro Jahr, pro Monat, pro Woche und pro Tag kaufen; warum das Messfenster weit mehr zählt als die zusätzliche Neun; und die zwei verschiedenen Monate, die dieses Werkzeug unter derselben Kennung benutzt.ErklärungGoldene Stunde und blaue Stunde sind Winkel, keine StundenDie goldene Stunde reicht von +6° bis −4° Sonnenhöhe und die blaue von −4° bis −6°, weshalb sie am Äquator vierzig Minuten dauert, in mittleren Breiten über eine Stunde, und oberhalb von 72,6° im Juni gar nicht stattfindet. Die Schwellen dieses Rechners, an seiner eigenen Ausgabe geprüft.

Ähnliche Tools

Quellen

Hast du einen Fehler in diesem Artikel entdeckt?