Guide
Cron-Expression-Tutorial: Crontab-Zeitpläne lesen und schreiben
Fünf Felder, sechs Sonderzeichen und ein historischer Bug, der entscheidet, ob Ihr Job einmal oder zweimal läuft.
By Buğra SözeriPublished
Cron ist vierzig Jahre alt und immer noch der Standard-Scheduler auf fast jedem Unix-System, das dieses Jahr ausgeliefert wird. Die Syntax passt in eine Zeile, was der Hauptgrund für ihr Überleben ist — und auch der Grund, warum sie zuverlässig falsch gelesen wird. Dieser Ratgeber führt durch die fünf Felder, jedes Sonderzeichen, den day-of-month-vs-day-of-week-Stolperstein und eine kleine Sammlung von Ausdrücken, die Sie direkt in eine crontab kopieren können.
Die fünfspaltige Anatomie
Ein POSIX-Cron-Ausdruck hat fünf durch Leerzeichen getrennte Felder, in dieser Reihenfolge:
# ┌──────────── minute (0 - 59)
# │ ┌────────── hour (0 - 23)
# │ │ ┌──────── day of month (1 - 31)
# │ │ │ ┌────── month (1 - 12) or JAN-DEC
# │ │ │ │ ┌──── day of week (0 - 6) or SUN-SAT, where 0 and 7 are Sunday
# │ │ │ │ │
* * * * * command-to-runJedes Feld muss vorhanden sein. Es gibt keine Standardwerte und keine positionsbasierten Kurzformen. Ein Feld mit *bedeutet „jeder gültige Wert in diesem Bereich“, nicht „überspringen“. Diese Unterscheidung wird wichtig, sobald Sie beginnen, Felder zu kombinieren.
Manche Varianten fügen am Anfang ein sechstes Sekundenfeld hinzu (Quartz, Springs @Scheduled) oder am Ende ein siebtes Jahresfeld. Das sind Erweiterungen, kein POSIX. Wenn Sie portabel schreiben, bleiben Sie bei fünf Feldern.
Warum zwei Tagesfelder?
Cron erlaubt es, „jeden Montag“ und „den Ersten des Monats“ in derselben Zeile zu sagen, was mehrdeutig wäre, wenn beide Felder übereinstimmen müssten. Die historische Auflösung ist ODER-Semantik, wenn beide Felder eingeschränkt sind: Der Job feuert, wenn day-of-month oder day-of-week passt. Darauf kommen wir zurück; es ist der mit Abstand häufigste Cron-Bug.
Sonderzeichen
Jedes Feld akzeptiert sechs Sonderzeichen. Ihr Verhalten ist über alle Felder hinweg identisch, doch der gültige Bereich unterscheidet sich naturgemäß je Feld.
* — jeder Wert
Trifft jeden gültigen Wert im Feld. * * * * * bedeutet jede Minute jeder Stunde jedes Tages. Das ist der einzige Ausdruck, der tatsächlich sechzigmal pro Stunde feuert; alles Komplexere feuert in der Regel seltener.
, — Liste
Das Komma trennt einzelne Werte. 0,15,30,45 * * * * feuert zur vollen, zur Viertel-nach-, zur halben und zur Viertel-vor-Stunde jeder Stunde. Die Reihenfolge ist dem Parser egal, aber Leser schätzen aufsteigende Listen.
- — Bereich
Der Bindestrich definiert einen inklusiven Bereich. 0 9-17 * * 1-5 feuert zur vollen Stunde von 09:00 bis 17:00 einschließlich, Montag bis Freitag. Beide Endpunkte sind enthalten; das sind neun Ausführungen pro Tag, nicht acht.
/ — Step
Der Schrägstrich wendet einen Step auf einen Bereich an. */5 im Minutenfeld ist die Kurzform für 0-59/5— alle fünf Minuten ab Minute 0. Sie können den Step mit einem expliziten Bereich kombinieren: 0-30/10 feuert bei 0, 10, 20, 30 und sonst nirgends.
Die Falle: */N teilt den vollen Bereich, nicht ab Ihrer aktuellen Uhrzeit. */7auf Minuten feuert bei 0, 7, 14, 21, 28, 35, 42, 49, 56 — dann bei 0 der nächsten Stunde, eine Lücke von vier Minuten. Cron ist kein periodischer Timer.
? — kein bestimmter Wert (nur Quartz)
Das Zeichen ? ist keinPOSIX. Es erscheint im Quartz-Dialekt von Cron (und in AWS EventBridge, das die Quartz-Syntax erbt) und bedeutet „kein bestimmter Wert — das andere Tagesfeld ist maßgeblich“. Sie schreiben 0 9 ? * MON-FRI in EventBridge, aber 0 9 * * MON-FRI in klassischem Cron.
Benannte Werte
Monate akzeptieren JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC, Wochentage akzeptieren SUN MON TUE WED THU FRI SAT. Sie sind in den meisten Implementierungen unabhängig von Groß-/Kleinschreibung, in einigen wenigen jedoch nicht; Großbuchstaben sind die sichere Wahl. Benannte Werte funktionieren nicht in allen Implementierungen innerhalb von Bereichen oder Steps — MON-FRI funktioniert auf Vixie cron, aber nicht auf jeder BSD-Variante. Im Zweifel verwenden Sie die numerische Form.
Rezepte
Der schnellste Weg, Cron zu verinnerlichen, ist, ein paar Dutzend Ausdrücke neben einfachem Klartext zu lesen. Fügen Sie einen davon in unseren Cron-Expression-Builder ein, um die nächsten zehn Ausführungszeiten in Ihrer lokalen Zone zu sehen.
Alle N Minuten
* * * * *— jede Minute*/5 * * * *— alle fünf Minuten, bei Minute 0, 5, 10…*/15 * * * *— jede Viertelstunde0,30 * * * *— zur vollen und zur halben Stunde5,35 * * * *— um fünf Minuten versetzt — nützlich, um Jobs zu staffeln, die um dieselbe Datenbank konkurrieren
Stündliche Varianten
0 * * * *— jede Stunde zur vollen Stunde0 */2 * * *— alle zwei Stunden ab 00:000 9-17 * * *— zur vollen Stunde, 09:00 bis 17:00 einschließlich
Tägliche Varianten
0 0 * * *— jeden Tag um Mitternacht (entspricht@daily)30 3 * * *— jeden Tag um 03:30 — das klassische Backup-Fenster0 9 * * 1-5— 09:00 an Werktagen0 18 * * 5— 18:00 nur freitags
Wöchentlich, monatlich, jährlich
0 9 * * 1— 09:00 jeden Montag (im Sinne von@weekly, aber mit einer sinnvollen Uhrzeit)0 0 1 * *— Mitternacht am Ersten jedes Monats (entspricht@monthly)0 0 1 1 *— Mitternacht am 1. Januar (entspricht@yearly)0 0 28-31 * *— Mitternacht an den letzten möglichen vier Tagen des Monats, kombiniert mit einem Skript, das prüft „ist heute der letzte Tag?“ — Cron kennt kein natives „letzter Tag des Monats“.
Geschäftszeiten
0 9-17 * * 1-5— zur vollen Stunde, 09:00-17:00, Montag-Freitag — neun Ausführungen pro Arbeitstag*/10 9-17 * * 1-5— alle zehn Minuten während der US-Geschäftszeiten0 9,13,17 * * 1-5— Öffnung, nach dem Mittag, Schließung — drei Ausführungen pro Arbeitstag
Der day-of-month-/day-of-week-ODER-Stolperstein
Dies ist das am häufigsten nachgefragte Verhalten in Cron, und die Spezifikation ist eindeutig: Wenn beide Felder, day-of-month und day-of-week, eingeschränkt sind (also nicht *), feuert der Job, wenn eine der beiden Bedingungen passt, nicht beide.
Betrachten Sie 0 0 1 * 1. Eine naheliegende Lesart ist „Mitternacht am Ersten des Monats, aber nur wenn es ein Montag ist“. Das tatsächliche Verhalten ist „Mitternacht am Ersten jedes Monats oderMitternacht an jedem Montag“. Das sind grob fünf Ausführungen pro Monat, nicht die null bis eins, die Sie wahrscheinlich beabsichtigt haben.
Der Workaround: Lassen Sie eines der beiden Tagesfelder als *. Wenn Sie wirklich UND-Semantik brauchen — „erster Montag des Monats“ — müssen Sie es innerhalb des Skripts prüfen:
# crontab: fire midnight on the first seven days of the month
0 0 1-7 * * /usr/local/bin/maybe-run-monthly.sh
# inside maybe-run-monthly.sh: bail if today isn't Monday
[ "$(date +%u)" = "1" ] || exit 0Der Quartz-Dialekt von Cron (und EventBridge) umgeht den Stolperstein mit dem Zeichen ? und expliziten Tokens für den n-ten Wochentag des Monats wie MON#1. Klassisches Cron hat weder das eine noch das andere.
Zeitzonen und Sommerzeit
Cron-Ausdrücke werden in der lokalen Zeitzone des Schedulers ausgewertet. Unter Linux ist das, worauf /etc/localtime verweist; unter macOS die Systemeinstellung. Der Ausdruck selbst benennt nie eine Zone.
Das macht Zeitumstellungen interessant. In einer Sommerzeit-Zone springt die lokale Uhr im Frühjahr vor (eine Stunde ausgelassen) und fällt im Herbst zurück (eine Stunde wiederholt). Ein Cron-Job bei 0 2 * * *feuert am Tag der Vorstellung möglicherweise gar nicht — die Stunde 02:00 existierte nicht — und feuert im Herbst möglicherweise zweimal.
Die meisten Cloud-Scheduler akzeptieren eine explizite Zeitzone pro Regel; IANA-Zonenbezeichner wie America/New_York sind korrekt, EST ist es nicht (es beachtet keine Sommerzeit). Wenn Sie absolute Konsistenz brauchen, planen Sie zwischen 03:00 und 23:00 (deutlich außerhalb jedes Zeitumstellungsfensters) oder lassen Sie den Scheduler in UTC laufen und nehmen die Lokalzeit-Arithmetik in Kauf.
Häufige Fehler
Den Schrägstrich als echte Periode behandeln
Das haben wir oben behandelt. */N teilt den Feldbereich, sodass die Periode zwischen der letzten Ausführung einer Stunde und der ersten der nächsten kürzer ist als N. Wenn Sie strikte N-Minuten-Abstände brauchen, ist Cron das falsche Werkzeug.
Vergessen, dass es die Minute 0 gibt
0-59/15feuert bei 0, 15, 30, 45 — viermal pro Stunde, nicht dreimal. Der Bereich beginnt bei 0. Off-by-one-Fehler sind in Cron selten, weil jedes Feld klar definierte Endpunkte hat, doch dieser tritt auf, wenn man vom menschlichen Klartext („viermal pro Stunde“) zum Ausdruck übersetzt und die implizite Minute null vergisst.
Einen Kommentar hinter den Befehl setzen
Cron behandelt die gesamte Zeile nach dem fünften Feld als einen einzigen Befehl. # comment auf einer crontab-Zeile ist Teil des Shell-Befehls, der sich meist einfach zu nichts expandiert, weil #in der Shell einen Kommentar einleitet — aber wenn es innerhalb eines in Anführungszeichen gesetzten Strings steht, haben Sie Ihren Befehl verändert. Setzen Sie Kommentare in eine eigene Zeile über dem Zeitplan.
Den PATH des Jobs voraussetzen
Cron läuft mit einer minimalen Umgebung. PATH ist typischerweise /usr/bin:/bin, und Ihre Shell-Aliase existieren nicht. Verwenden Sie entweder absolute Pfade zu jeder Binärdatei oder setzen Sie PATH=oben in der crontab. Wenn ein Job „funktioniert, wenn ich ihn von Hand ausführe, aber nicht aus Cron“, ist das fast immer die Ursache.
Stdout das Postfach füllen lassen
Cron schickt die Ausgabe jedes Jobs standardmäßig per E-Mail an den lokalen Benutzer. Auf einem Server ohne konfigurierte Mail wächst die Spool-Datei stillschweigend, bis etwas anderes kaputtgeht. Hängen Sie >>/var/log/myjob.log 2>&1 an jeden Befehl an und rotieren Sie das Log.
Kurzreferenz-Karte
| Ausdruck | Bedeutung |
|---|---|
* * * * * | jede Minute |
*/5 * * * * | alle 5 Minuten |
0 * * * * | zur vollen Stunde |
0 9-17 * * 1-5 | stündlich, 9-17 Uhr, werktags |
0 0 * * * | täglich um Mitternacht |
30 3 * * 0 | 03:30 jeden Sonntag |
0 0 1 * * | Mitternacht am 1. jedes Monats |
0 0 1 1 * | Mitternacht am 1. Januar |
@reboot | einmal beim Scheduler-Start (systemabhängig) |
Vor dem Commit prüfen
Der billigste Weg, einen Anruf um 3 Uhr morgens zu vermeiden, ist, Ihren Ausdruck vor dem Speichern der crontab in einen Parser einzufügen. Unser Cron-Expression-Builder gibt die nächsten zehn Ausführungszeiten in Ihrer lokalen Zone und in UTC aus, dazu eine Beschreibung in Klartext, die den day-of-month-/day-of-week-Stolperstein sofort entlarvt.
Cron ist ein kleines, scharfes Werkzeug. Lesen Sie die Spezifikation einmal, bauen Sie ein Muskelgedächtnis für die fünf Felder auf, fügen Sie neue Ausdrücke in einen Parser ein, bis sie offensichtlich richtig aussehen — und kalkulieren Sie ein, dass der Fehlermodus eines falsch gelesenen Ausdrucks meist still ist, nicht laut.
Frequently asked questions
- Nutzt Cron die Zeitzone des Servers oder UTC?
- Klassisches Unix-Cron verwendet die lokale Systemzeitzone, also das, worauf /etc/localtime zeigt. Viele Cloud-Scheduler (AWS EventBridge, GCP Cloud Scheduler) verwenden standardmäßig UTC und erlauben es, pro Regel eine benannte IANA-Zone zu wählen. Geben Sie die aufgelöste Zeitzone immer in der ersten Logzeile Ihres Jobs aus — das eliminiert eine ganze Kategorie von Fehlern nach Zeitumstellungen.
- Warum lief mein Job zweimal an dem Morgen, an dem die Sommerzeit endete?
- Wenn die Uhr von 02:00 auf 01:00 zurückgestellt wird, kommt die Stunde zwischen 01:00 und 02:00 auf der lokalen Uhr zweimal vor. Ein um 01:30 in einer Sommerzeit-Zone geplanter Job läuft beide Male, sofern Ihre Cron-Implementierung nicht ausdrücklich dedupliziert. Die Lösung besteht entweder darin, zwischen 03:00 und 23:00 zu planen (niemals innerhalb des mehrdeutigen Zeitfensters) oder den Scheduler in UTC laufen zu lassen.
- Was ist das kleinste Intervall, das Cron unterstützt?
- Eine Minute. Das erste Feld sind die Minuten; es gibt in POSIX-crontab kein Sekundenfeld. Wenn Sie eine Planung unterhalb von Minuten benötigen, verwenden Sie einen langlaufenden Prozess mit eigener Sleep-Schleife, systemd-Timer mit OnUnitActiveSec oder einen dedizierten Scheduler wie Quartz, der ein Sekundenfeld unterstützt.
- Sind @hourly, @daily, @reboot portabel?
- Die Kurzform-Strings (@yearly, @monthly, @weekly, @daily, @hourly) werden von Vixie cron, cronie und den meisten modernen Derivaten unterstützt, sind also auf Linux und macOS sicher. @reboot ist weit verbreitet, aber seine Semantik unterscheidet sich — manche Implementierungen laufen einmal beim nächsten Boot, andere bei jedem Boot. Verwenden Sie @reboot nicht in Containern; nutzen Sie stattdessen den Startbefehl des Containers selbst.
- Warum überspringt */7 manchmal das letzte Intervall?
- Der Step-Operator teilt den gesamten erlaubten Bereich, nicht Ihre Startzeit. Für Minuten (0-59) feuert */7 bei 0, 7, 14, 21, 28, 35, 42, 49, 56 — dann ist die nächste gültige Minute die 0 der nächsten Stunde. Der Abstand zwischen 56 und 60 beträgt nur vier Minuten, nicht sieben. Wenn Sie ein striktes Sieben-Minuten-Intervall brauchen, verwenden Sie einen langlaufenden Scheduler mit einem echten Intervall-Timer, nicht Cron.
- Sollte ich 2026 Cron verwenden oder systemd-Timer?
- Auf einem einzelnen Linux-Host ohne Orchestrator sind systemd-Timer meist die bessere Standardwahl: strukturiertes Logging über journalctl, Abhängigkeitsreihenfolge, einfachere Randomisierung mit RandomizedDelaySec und Ressourcenlimits auf Unit-Ebene. Cron gewinnt, wenn Sie Portabilität über Nicht-systemd-Systeme brauchen oder wenn die gesamte Automatisierung eine Zeile in einer crontab ist. In container-orchestrierten Umgebungen keines von beidem — verwenden Sie den nativen Scheduler der Plattform (Kubernetes CronJob, ECS Scheduled Tasks usw.).
Sources & references
Authoritative references cited by this piece. Verified by Buğra Sözeri on the dates shown and re-checked at every deploy.
- POSIX crontab(5) — The Open Group Base Specifications Issue 7 — Maßgebliche Spezifikation für die Fünf-Feld-Syntax und Feldbereiche(as of )
- crontab(5) — Vixie cron / Linux man page — Referenz für Step-Werte, benannte Monate/Wochentage und die @-Kurzformen(as of )
- systemd.timer(5) — freedesktop.org — Moderne Alternative, die im FAQ-Vergleich verwendet wird(as of )
- IANA Time Zone Database — Maßgebliche Quelle für die in der DST-Diskussion genannten Zonenbezeichner(as of )
Related
- Cron-Expression-Builder & -ErklärerAusdruck einfügen, nächste Ausführungen und eine klare Beschreibung sehen
- Glossar: IANA-ZeitzoneWarum Zonen America/New_York heißen, nicht EST
- Glossar: Unix-TimestampSekunden seit 1970-01-01 UTC — die Basis fast jedes Schedulers
- Timestamp-KonverterUmrechnung zwischen Epoch-Sekunden, ISO 8601 und Ihrer lokalen Zeitzone
- Zeitzonen-Spickzettel für Remote-TeamsPraktische Zonenrechnung für verteilte Planung
Published May 31, 2026