Cron-Ausdruck-Parser

Lies einen Cron-Ausdruck im Klartext und sieh genau, wann er das nächste Mal läuft.

Minute · Stunde · Tag des Monats · Monat · Wochentag. Makros wie @daily gehen auch.

Beispiele:

Das läuft

um 03:00, am Montag

Die nächsten sechs Läufe · UTC

  1. 2026-09-21 03:00Montag
  2. 2026-09-28 03:00Montag
  3. 2026-10-05 03:00Montag
  4. 2026-10-12 03:00Montag
  5. 2026-10-19 03:00Montag
  6. 2026-10-26 03:00Montag

In UTC angezeigt. Ein echter Crontab läuft in der Zeitzone des Servers, und genau dort macht die Sommerzeit Ärger — siehe unten.

Feld für Feld

Minute
00
Stunde
33
Tag des Monats
*beliebig
Monat
*beliebig
Wochentag
11

Wissenswertes zu diesem Zeitplan

  • Den 31. gibt es nicht in jedem Monat, in diesen Monaten läuft der Job daher schlicht nicht.
  • Den 29. Februar gibt es nur in Schaltjahren — das läuft einmal alle vier Jahre.

Fünf Felder, das gröbste zuletzt

PositionFeldBereichHinweise
1Minute0–59
2Stunde0–2324-Stunden-Zählung, Serverzeit
3Tag des Monats1–31Nicht existierende Tage werden schlicht übersprungen
4Monat1–12Oder JANDEC
5Wochentag0–70 und 7 bedeuten beide Sonntag. Oder SUNSAT

Innerhalb eines Feldes: * heißt beliebig, , zählt Werte auf, - gibt einen Bereich, / schrittet. */15 im Minutenfeld ist alle fünfzehn Minuten; 5/10 heißt ab 5 in Zehnerschritten, also 5, 15, 25 und so fort. Bereiche dürfen umlaufen, FRI-MON ist also eine gültige Art, das Wochenende samt seiner Ränder zu sagen.

Die Regel, die jeden erwischt

Das ist das eine, was man von dieser Seite mitnehmen sollte.

Sind beide Felder — Tag des Monats und Wochentag — eingeschränkt, führt cron den Job aus, wenn eines von beiden zutrifft. Nicht beide. Es ist ein ODER und liest sich wie ein UND.

0 0 1 * MON   # NOT "the 1st, if it is a Monday"
              # Actually: every 1st, AND every Monday

Dieser Zeitplan feuert rund fünfmal im Monat. Fügen Sie ihn oben in den Parser ein und sehen Sie sich die nächsten Laufzeiten an — die Folge verrät es sofort.

Die Regel greift nur, wenn beide Felder eingeschränkt sind. Steht in einem *, bestimmt schlicht das andere, weshalb 0 0 * * MON sich genau wie erwartet verhält. Das Verhalten steht in der POSIX-Spezifikation und jeder verbreitete cron setzt es um, es ist also kein Fehler, den man wegkonfigurieren kann.

Um wirklich beide Bedingungen zu verlangen, schränken Sie ein Feld im Zeitplan ein und prüfen das andere am Anfang des Jobs:

0 0 * * MON  [ "$(date +\%d)" = "01" ] && /usr/local/bin/job

Die Zeitumstellung, die Jobs zweimal im Jahr zerlegt

Cron läuft in der lokalen Zeitzone des Servers, sofern nichts anderes gesagt wird, und Ortszeit ist nicht durchgehend. Beim Vorstellen verschwindet eine Stunde: Ein für 02:30 geplanter Job kann ganz ausfallen oder um 03:30 feuern, je nach cron. Beim Zurückstellen gibt es 01:30 zweimal — und womöglich den Job auch.

Moderner Vixie-cron bemüht sich — durch den Vorwärtssprung verpasste Jobs laufen meist einmal danach —, aber das Verhalten ist über die Implementierungen hinweg nicht einheitlich, und Container-Scheduler weichen nochmals ab.

Die dauerhafte Lösung ist, den Scheduler in UTC laufen zu lassen und an den Rändern umzurechnen. Kubernetes-CronJobs laufen genau deshalb standardmäßig in UTC. Muss ein Job zu einer bestimmten Ortszeit laufen, nehmen Sie hin, dass er einen Teil des Jahres eine Stunde danebenliegt — oder nehmen Sie einen Scheduler, der Zeitzonen wirklich versteht: systemd-Timer tun das.

Andere Gründe, warum ein Cron-Job nicht läuft

  • Die Umgebung ist nahezu leer. Cron liest Ihr Shell-Profil nicht ein, PATH ist also minimal und Ihr virtuelles Environment nicht aktiv. Verwenden Sie immer absolute Pfade.
  • Ein nacktes Prozentzeichen. In einer crontab bedeutet % einen Zeilenumbruch. date +%Y bricht stillschweigend; es muss date +\%Y heißen.
  • Kein abschließender Zeilenumbruch. Manche crons ignorieren die letzte Zeile einer crontab, die nicht mit einem endet.
  • Die Ausgabe geht ins Nichts. Cron mailt die Ausgabe an den Benutzer, und ohne konfigurierte Mail verschwindet sie. Leiten Sie in eine Logdatei um, damit Fehlschläge sichtbar sind.
  • Überlappende Läufe. Cron wartet nicht, bis der vorige Lauf fertig ist. Ein fünfminütiger Job im Minutentakt staut sich, bis etwas umfällt. Nehmen Sie flock.

Was cron nicht ausdrücken kann

Die Felder sind unabhängig, alles, was nicht glatt in eine Stunde oder einen Tag aufgeht, ist damit unerreichbar. „Alle 90 Minuten“ lässt sich nicht schreiben. „Der letzte Freitag im Monat“ in Standard-cron ebenso wenig — dafür gibt es L und # in Quartz, und deshalb sind sie nicht portabel.

Wenn Sie mit der Syntax ringen, ist das meist das Signal, zu einem Scheduler zu wechseln, der in Intervallen statt in Kalenderfeldern denkt. Ein systemd-Timer mit OnUnitActiveSec=90min sagt in einer Zeile, was Sie meinten.

Verwandt

Die Laufzeiten oben sind in UTC — der Zeitstempel-Konverter bringt jede davon in Ihre eigene Zeitzone oder in das Format, in dem Ihr Scheduler protokolliert. Geht es ums Treffen von Text statt ums Planen, ist der Regex-Tester nebenan.

Fragen zu Cron

Warum läuft mein Job an Tagen, die ich nicht eingeplant habe?

Mit größter Wahrscheinlichkeit wegen der Regel für Monatstag und Wochentag. Sind beide Felder eingeschränkt, führt cron den Job aus, wenn EINES von beiden zutrifft — nicht beide. 0 0 1 * MON feuert also am Ersten jedes Monats und an jedem Montag, also etwa fünfmal im Monat statt des einen gemeinten Termins. Steht in einem der Felder *, greift die Regel nicht und das andere bestimmt allein. Wollen Sie beide Bedingungen, schränken Sie ein Feld in cron ein und prüfen das andere im Job selbst.

Was bedeuten die fünf Felder?

Minute (0–59), Stunde (0–23), Tag des Monats (1–31), Monat (1–12), Wochentag (0–7, wobei 0 und 7 beide Sonntag heißen). Von links nach rechts wird es zunehmend grober — eine brauchbare Merkhilfe. Manche Planer — Quartz, Spring und einige Job-Runner — stellen ein sechstes Feld für Sekunden voran; das klassische crontab hat überhaupt kein Sekundenfeld.

Was passiert mit einem Cron-Job bei der Zeitumstellung?

Das hängt von der Implementierung ab, und genau hier gehen geplante Jobs zweimal im Jahr still kaputt. Beim Vorstellen existiert eine Stunde nicht — ein Job um 02:30 kann ganz ausfallen oder um 03:30 laufen, je nach cron. Beim Zurückstellen gibt es 01:30 zweimal, der Job kann also doppelt laufen. Moderne Vixie-cron und systemd-Timer bemühen sich um vernünftiges Verhalten, ältere nicht. Die belastbare Antwort: geplante Arbeit in UTC ausführen und erst an den Rändern umrechnen.

Was sind L, W und # und warum werden sie hier abgelehnt?

Es sind Quartz-Erweiterungen — L für „letzter“ (letzter Tag des Monats, letzter Freitag), W für den nächstgelegenen Werktag und # für „der n-te Wochentag im Monat“. Sie sind wirklich nützlich und sie sind kein Standard-cron. crontab, Kubernetes CronJobs und GitHub Actions weisen sie zurück oder lesen sie falsch. Dieser Parser verweigert die Annahme, statt zu raten, denn ein Zeitplan, der ein L stillschweigend ignoriert, wäre genau auf die Weise falsch, die niemand kontrolliert.

Was macht @reboot?

Es führt den Job einmal aus, wenn cron startet, üblicherweise beim Hochfahren. Es hat keinen wiederkehrenden Plan, also gibt es keine nächsten Laufzeiten zu berechnen — deshalb sagt dieses Werkzeug das, statt eine leere Liste zu zeigen. Gut zu wissen: @reboot feuert beim Start des cron-Dienstes, nicht wenn die Maschine fertig gebootet hat; alles, was ein funktionierendes Netz voraussetzt, muss also selbst warten.

Wie lasse ich etwas alle 90 Minuten laufen?

Direkt gar nicht, und das ist eine echte Grenze und kein Kniff, den Sie noch nicht kennen. Die Felder von cron sind unabhängig, */90 im Minutenfeld ist also ungültig, und ein Plan, der nicht glatt in eine Stunde oder einen Tag aufgeht, lässt sich nicht formulieren. Behelfen kann man sich mit zwei Einträgen, die das Muster über einen Tag abdecken — oder, ehrlicher, mit einem Planer, der in Intervallen statt in Kalenderfeldern denkt, etwa einem systemd-Timer mit OnUnitActiveSec.

Zuletzt geprüft . Etwas veraltet gefunden? Sagen Sie uns Bescheid.