Cron-Ausdruck erklären

Erklärt jeden Cron-Ausdruck — Vixie, Quartz, EventBridge oder Jenkins —, listet die nächsten Läufe in jeder Zeitzone und benennt die Fallstricke.

Eingabe

Gelesen als Vixie cron.

Was das bedeutet

Um 00:00 am 13. des Monats oder am Freitag

Feld für Feld

FeldGeschriebenTrifft zu auf
Minute00
Stunde00
Tag des Monats1313
Monat*jeden Wert
Wochentag5Freitag

Worauf zu achten ist

  • Beide Tagesfelder sind eingeschränkt, also führt cron dies aus, sobald eines von beiden passt: der Tag des Monats oder der Wochentag, nicht beide zusammen. Deshalb bedeutet 13 mit Freitag den 13. des Monats und jeden Freitag, nicht Freitag den 13.

Nächste Läufe

    Was dieses Werkzeug tut

    Es liest Ihnen einen Cron-Ausdruck in Worten zurück, listet die nächsten Zeitpunkte auf, zu denen er wirklich feuert — in der Zeitzone, in der der Job läuft —, und benennt das, was der Ausdruck impliziert, aber nicht sagt. Dieser letzte Teil ist der Punkt: Ein Cron-Ausdruck ist nie auf eine Weise falsch, die einen Fehler erzeugt. Er läuft an den falschen Tagen, still, bis es jemandem auffällt.

    Verstanden werden vier Dialekte statt nur einer. Die fünfteilige Form, die crontab annimmt, Quartz mit seinem Sekundenfeld und seinen Kalenderregeln, AWS EventBridge mit einem Jahr am Ende und Jenkins mit seinem Hash. Einen davon in ein Werkzeug zu kopieren, das nur einen anderen kennt, ist der Weg, auf dem die meisten überhaupt erfahren, dass es mehr als einen gibt.

    Die Felder, und wie viele es sind

    Der klassische Ausdruck hat fünf durch Leerzeichen getrennte Felder in fester Reihenfolge: Minute, Stunde, Tag des Monats, Monat, Wochentag. Jedes ist ein Stern für „jeder“, eine Zahl, eine kommagetrennte Liste, ein Bereich mit Bindestrich oder eine Schrittweite mit Schrägstrich. Monate und Tage dürfen als Dreibuchstaben-Namen geschrieben werden, was fast immer klarer ist als die Ziffern.

    • Ein Stern bedeutet jeden Wert, den das Feld annehmen kann.
    • Ein Bereich wie 9-17 bedeutet jeden Wert von 9 bis einschließlich 17.
    • Eine Schrittweite wie */15 bedeutet jeden 15. Wert ab dem unteren Ende des Feldes; 9-17/2 schreitet innerhalb eines Bereichs, und 5/15 schreitet von 5 bis ans obere Ende.
    • Eine Liste wie 0,30 bedeutet genau diese Werte.
    • Ein entarteter Bereich wie 13-13 ist schlicht die 13 — manche Bibliotheken machen das falsch und behandeln ihn wie einen Stern.

    Ein sechstes Feld ist die Stelle, an der sich die Dialekte trennen. Quartz stellt es nach vorn und liest es als Sekunden; EventBridge stellt es ans Ende und liest es als Jahr. Sechs blanke Felder sind daher wirklich mehrdeutig, und dieses Werkzeug sagt, wie es sie gelesen hat, statt still zu wählen. Den Ausdruck in cron(...) zu packen — EventBridges eigene Schreibweise — klärt die Sache.

    Die Makros sind Kurzschreibweisen: @hourly, @daily, @midnight, @weekly, @monthly, @yearly und @annually. Sie expandieren zu gewöhnlichen Ausdrücken, die das Werkzeug anzeigt. @reboot ist die Ausnahme und überhaupt kein Zeitplan.

    Die beiden Tagesfelder und das „oder“, das wie ein „und“ aussieht

    Ein Datum lässt sich auf zwei verschiedene Arten wählen — über den Tag des Monats und über den Wochentag — und cron hat beide Felder. Sind beide eingeschränkt, läuft der Job, sobald eines von beiden passt. Nicht beide.

    Also ist 0 0 13 * 5 nicht Freitag, der 13. Es ist der 13. jedes Monats, und jeder Freitag: rund 64 Tage im Jahr statt einem oder zwei. Der Ausdruck sieht aus wie eine Konjunktion und verhält sich wie eine Disjunktion, nichts meldet einen Fehler, und der Job läuft schlicht öfter als beabsichtigt.

    Die Regel hat eine zweite Hälfte, die seltsamer ist und die kaum jemand kennt. Cron prüft nicht, ob ein Tagesfeld eingeschränkt ist; es prüft, ob das erste Zeichen des Feldes ein Stern ist. Eine Schrittweite wie */14 zählt also als Stern, obwohl sie das Feld auf den 1., 15. und 29. einschränkt — und ihre Anwesenheit kippt die beiden Tagesfelder vom „oder“ zurück zum „und“. Zwei gleich eingeschränkt aussehende Ausdrücke verhalten sich dann völlig verschieden, und dieses Werkzeug meldet, welche Regel gilt.

    Quartz und EventBridge umgehen die ganze Frage, indem sie es nicht zulassen, dass beide Felder etwas sagen: genau eines von beiden muss ein Fragezeichen sein, das heißt „kein bestimmter Wert, das andere Feld entscheidet“.

    Schrittweiten, die ihr Feld nicht teilen

    Eine Schrittweite wird geschrieben, als wäre sie ein Intervall, und innerhalb eines Zyklus des Feldes ist sie das auch. Über die Grenze hinweg meist nicht.

    */7 im Stundenfeld bedeutet die Stunden 0, 7, 14 und 21. Nach 21 ist das Feld zu Ende, der nächste Lauf ist also um 0 Uhr am Folgetag — drei Stunden später, nicht sieben. Jeder Zyklus endet mit einer kurzen Lücke, und dasselbe passiert bei */7 in Minuten (eine Lücke von vier Minuten nach 56) und bei jeder anderen Schrittweite, die ihren Bereich nicht glatt teilt. */15 in Minuten und */6 in Stunden sind sicher; die meisten Zahlen, zu denen man greift, sind es nicht.

    Das zählt, wenn die Schrittweite gewählt wurde, um Arbeit zu verteilen. Ein Job auf */7 Stunden läuft nicht alle sieben Stunden, und ein auf sieben ausgelegtes Rate-Limit wird einmal am Tag gerissen.

    Wochentage werden an verschiedenen Orten verschieden gezählt

    Vixie cron zählt die Tage von 0 bis 7 mit dem Sonntag an beiden Enden, also sind 0 und 7 derselbe Tag und 1 ist Montag. Quartz und EventBridge zählen sie von 1 bis 7 mit dem Sonntag auf 1, dort ist 1 also Sonntag und 2 ist Montag.

    Ein aus einer Quartz-Konfiguration in eine crontab kopierter Ausdruck läuft daher einen Tag zu früh, und nirgends beschwert sich etwas, weil beide Schreibweisen in beiden Systemen gültige Zahlen sind. Dreibuchstaben-Namen — MON, FRI — bedeuten überall denselben Tag und sind die einfache Absicherung.

    Zeitumstellung: die zwei Morgen im Jahr

    Ein Cron-Daemon plant keine Zeitpunkte. Er schaut jede Minute auf die lokale Uhr und fragt, ob der Ausdruck passt. Zweimal im Jahr ist diese Uhr keine wohlerzogene Folge.

    Springt sie vor, findet eine Stunde von Ablesungen nie statt. Ein auf 02:30 gesetzter Job hat an diesem Tag kein 02:30. Geht sie zurück, findet eine Stunde von Ablesungen zweimal statt, und ein auf 01:30 gesetzter Job hat zwei davon.

    Vixie cron unterscheidet hier zwei Arten von Jobs, und die Unterscheidung ist es wert, gekannt zu werden, denn sie entscheidet, welche Ihrer Jobs betroffen sind. Ein an eine Uhrzeit genagelter Job — feste Stunde, feste Minute — wird in beiden Fällen genau einmal ausgeführt: nach einem Sprung nach vorn sofort, und nach einem Sprung zurück achtet cron darauf, ihn nicht zu wiederholen. Ein Job mit einem Stern in Stunde oder Minute ist ein Intervall-Job und folgt einfach der Uhr: Er verliert im Frühjahr eine Stunde Läufe und wiederholt im Herbst eine.

    Ein stündliches Backup läuft also tatsächlich in einer Nacht im Jahr zweimal, und ein nächtlicher Job um 02:30 läuft tatsächlich in einer anderen Nacht zu einem ungewöhnlichen Moment. Dieses Werkzeug prüft die nächsten zwölf Monate der gewählten Zone gegen Ihren Ausdruck und sagt, welcher der beiden Fälle zutrifft — mit Datum.

    Der verlässliche Ausweg ist, den Job in UTC zu planen oder außerhalb von 01:00–03:00 Ortszeit, wo keine Umstellung liegt.

    Auf welcher Uhr der Job wirklich läuft

    Eine crontab läuft in der lokalen Zone der Maschine oder in der, die CRON_TZ oder TZ am Anfang der Datei angeben. Das ist selten die Zone dessen, der den Ausdruck liest, und darum ist die Zeitzone hier eine Einstellung und nicht die Ihres Browsers.

    Ein Kubernetes-CronJob ist noch einmal anders: Er liest seinen Zeitplan in UTC, sofern das Manifest kein timeZone-Feld setzt — ganz gleich, was die Uhr des Knotens sagt. Ein für lokale Bürozeiten geschriebener und ohne dieses Feld ausgerollter Zeitplan läuft außerhalb von UTC überall zur falschen Tageszeit — und ändert sich nicht mit den Jahreszeiten, was je nach Job ein Fehler oder eine Erleichterung ist.

    Jenkins und das H

    Jenkins ergänzt ein Zeichen, das kein anderer Dialekt hat: H, das nach Zufall aussieht und keiner ist. Jenkins hasht den Namen des Jobs zu einem festen Wert innerhalb des Feldbereichs, sodass der Job jeden Tag zur selben Zeit läuft — seiner eigenen — während sich hundert Jobs mit H * * * * gleichmäßig über die Stunde verteilen, statt alle zur nullten Minute zu starten.

    Weil der Wert aus dem Jobnamen kommt und der Jobname nicht Teil des Ausdrucks ist, kann kein Werkzeug die genauen Zeiten berechnen. Dieses löst jedes H am unteren Rand seines Bereichs auf und sagt das auch: Die Form des Zeitplans — wie oft, an welchen Tagen — stimmt genau, und nur der Versatz innerhalb jeder Periode ist ein Platzhalter.

    Jenkins definiert außerdem die Makros um. Sein @daily ist @midnight, und das ist nicht Mitternacht, sondern eine gehashte Minute irgendwo in den ersten drei Stunden des Tages.

    Was cron nicht tut

    • Es holt nichts nach. War die Maschine im Schlaf oder der Daemon aus, als ein Lauf fällig war, findet dieser Lauf nicht später statt — er fällt einfach aus. anacron gibt es genau dafür und ist ein anderes Programm.
    • Es verhindert keine überlappenden Läufe. Dauert ein Job länger als das Intervall, startet der nächste trotzdem, und nach einer Weile laufen mehrere. Eine Sperrdatei ist die übliche Antwort.
    • In der klassischen Form kennt es keine Sekunden. Die feinste Auflösung ist eine Minute; alles Schnellere braucht Quartz, systemd oder eine Schleife im Job selbst.
    • @reboot ist kein Zeitplan. Es läuft einmal beim Start des Daemons, hat also keinen nächsten Lauf, und auf einer Maschine, die nie neu startet, läuft es nie.
    • Ein rate-Ausdruck in EventBridge zählt ab dem Anlegen der Regel, und dieser Moment steht nicht im Ausdruck — kein Werkzeug kann daher sagen, wann er das nächste Mal feuert.

    Häufig gestellte Fragen

    Wie führe ich einen Job am ersten Montag des Monats aus?
    Nicht mit einem einfachen Cron-Ausdruck: Das verlangt ein „und“ zwischen den beiden Tagesfeldern, und cron liefert ein „oder“. Der übliche Behelf ist, 0 0 1-7 * * zu planen und das Kommando selbst den Wochentag prüfen zu lassen. Quartz und EventBridge können es direkt ausdrücken, als 0 0 12 ? * MON#1.
    Warum läuft 0 0 13 * 5 so oft?
    Weil es den 13. oder jeden Freitag bedeutet, nicht Freitag den 13. Sind beide Tagesfelder eingeschränkt und beginnt keines mit einem Stern, führt cron den Job aus, sobald eines passt. Im klassischen Dialekt gibt es keine Möglichkeit, ein „und“ zu schreiben.
    Was ist der Unterschied zwischen */5 und 0-59/5?
    Beim Minutenfeld keiner: beide ergeben 0, 5, 10 und so weiter. Der Unterschied zeigt sich in den beiden Tagesfeldern, wo cron zwischen „und“ und „oder“ danach entscheidet, ob das Feld mit einem Stern beginnt — */5 und 0-59/5 wählen also dieselben Tage, verbinden sich aber unterschiedlich mit dem anderen Tagesfeld.
    Läuft mein Job doppelt, wenn die Uhr zurückgestellt wird?
    Wenn er einen Stern in Stunde oder Minute hat, ja: Er folgt der Uhr, und diese Stunde kommt zweimal vor. Hat er feste Stunde und Minute, nein — Vixie cron führt einen solchen Job einmal aus. Das Befundfeld sagt, welcher Fall bei Ihnen vorliegt, samt Datum.
    Welche Zeitzone verwendet ein Cron-Ausdruck?
    Die der Maschine, sofern nicht CRON_TZ oder TZ in der crontab gesetzt sind. Ein Kubernetes-CronJob verwendet UTC, sofern das Manifest kein timeZone setzt. Da die Zone nicht Teil des Ausdrucks ist, fragt dieses Werkzeug danach, statt die Ihres Browsers anzunehmen.
    Kann ich etwas alle 90 Minuten planen?
    Nicht als einen Ausdruck, denn jedes Feld läuft für sich im Kreis und 90 Minuten passen nicht in eine Stunde. Üblich sind zwei Ausdrücke, 0 0,3,6,9,12,15,18,21 * * * und 30 1,4,7,10,13,16,19,22 * * *, die zusammen alle 90 Minuten einen Lauf ergeben.
    Wird etwas von dem, was ich einfüge, an einen Server gesendet?
    Nein. Auswertung, Erklärung und die gesamte Zeitplanberechnung laufen in Ihrem Browser; nichts wird hochgeladen oder protokolliert, und es funktioniert ohne Netzverbindung.