Cron-Ausdrücke erklärt: Felder, Schritte und Zeitzonen
Cron ist der Zeitplaner, der auf Unix-ähnlichen Systemen Befehle zu festen Zeiten startet, und sein Format mit fünf Feldern hat sich weit darüber hinaus verbreitet: GitHub Actions, Kubernetes und viele Hosting-Oberflächen verwenden dieselbe Schreibweise. Eine Zeile wie 30 2 * * 1 bedeutet „jeden Montag um 02:30“. Das meiste daran ist einfach; einige Regeln sind es nicht, und genau sie stecken hinter Jobs, die zur falschen Zeit, doppelt oder nie laufen. Dieser Ratgeber folgt dem POSIX-Standard und cronie, einem verbreiteten Linux-Cron, und nennt die Unterschiede anderer Zeitplaner.
Die fünf Felder
Eine Crontab-Zeile hat fünf durch Leerzeichen getrennte Zeitfelder, danach folgt der Befehl. Der Job läuft in jeder Minute, die alle Felder erfüllt, mit einer Ausnahme für die beiden Tagesfelder, die weiter unten erklärt wird. Der Standard nummeriert die Wochentage von 0 bis 6, 0 ist Sonntag; cronie und die meisten Linux-Crons akzeptieren auch 7 für Sonntag sowie englische Namen mit drei Buchstaben wie mon oder jan, in beliebiger Schreibung.
| Feld | Werte | Beispiel | Bedeutung |
|---|---|---|---|
| Minute | 0–59 | 30 | in Minute 30 |
| Stunde | 0–23 | 2 | von 02:00 bis 02:59 |
| Tag des Monats | 1–31 | 1,15 | am 1. und am 15. |
| Monat | 1–12 oder jan–dec | * | jeden Monat |
| Wochentag | 0–7 oder sun–sat (0 und 7 sind Sonntag) | 1-5 | Montag bis Freitag |
Ein Sternchen steht für alle Werte des Feldes. Uhrzeiten folgen der 24-Stunden-Zählung: 9 ist 09:00, 21 ist 21:00.
Listen, Bereiche und Schritte
Ein Feld kann eine Liste (1,15), einen Bereich (9-17) oder einen Schritt enthalten. Ein Schritt teilt einen Bereich auf: 0-30/10 im Minutenfeld sind die Minuten 0, 10, 20 und 30, und */15 läuft durch alle Werte ab dem ersten, also die Minuten 0, 15, 30 und 45. Schritte zählen ab dem Anfang des Bereichs und beginnen mit jeder neuen Stunde, jedem Tag oder Monat von vorn; sie laufen nicht vom vorherigen weiter.
*/15 * * * *Alle 15 Minuten: in den Minuten 0, 15, 30 und 45.0 9-17 * * 1-5Zu jeder vollen Stunde von 09:00 bis 17:00, Montag bis Freitag.0 0 */7 * *Um Mitternacht am 1., 8., 15., 22. und 29.: die Zählung beginnt jeden Monat neu.*/25 * * * *In den Minuten 0, 25 und 50, also liegen zwischen :50 und dem nächsten :00 nur 10 Minuten, nicht 25.
Im Minutenfeld ergeben nur Schritte, die 60 ohne Rest teilen (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30), gleiche Abstände. Für alle 90 Minuten braucht man zwei Zeilen: 0 0-21/3 * * * läuft um 00:00, 03:00 … 21:00 und 30 1-22/3 * * * um 01:30, 04:30 … 22:30.
cronie kennt außerdem Kurzformen: @hourly, @daily (0 0 * * *), @weekly (0 0 * * 0), @monthly (0 0 1 * *), @yearly oder @annually (0 0 1 1 *) und @reboot, das einmal beim Start läuft. Sie gehören nicht zum Standard: GitHub Actions zum Beispiel akzeptiert sie nicht.
Tag des Monats oder Wochentag
Wenn sowohl das Feld für den Tag des Monats als auch das für den Wochentag etwas anderes als ein Sternchen enthalten, passt laut Standard ein Tag, wenn eines der beiden passt, nicht beide. 0 9 13 * 5 läuft deshalb um 09:00 an jedem 13. und an jedem Freitag, nicht nur an Freitag, dem 13. Im November 2026 sind das der 6., der 13. (ein Freitag, einmal ausgeführt), der 20. und der 27.
Um beides zu verknüpfen, plant man ein Feld und lässt den Befehl das andere prüfen. In einer Crontab wird ein % im Befehl zu einem Zeilenumbruch, deshalb muss es als \% geschrieben werden:
0 9 13 * * [ "$(date +\%u)" = 5 ] && /usr/local/bin/jobNur Freitag, der 13.: läuft an jedem 13., und der Job startet, wenn der Wochentag 5 (Freitag) ist.0 18 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && /usr/local/bin/reportDer letzte Tag des Monats, mit GNU date (Linux): läuft vom 28. bis 31., und der Job startet, wenn morgen der 1. ist.
Zeitzonen und Sommerzeit
Cron liest den Zeitplan in der Zeitzone der Maschine oder des Dienstes, der ihn ausführt, und das ist auf Servern und gehosteten Plattformen oft UTC. 0 9 * * * auf einem UTC-Server läuft je nach Jahreszeit um 10:00 oder 11:00 in Berlin, Paris, Madrid oder Rom und um 09:00 oder 10:00 in Lissabon und London. Brasilien hat keine Sommerzeit, in São Paulo ist es also immer 06:00. cronie erlaubt einer Crontab mit der Variablen CRON_TZ eine eigene Zeitzone; GitHub Actions nimmt einen Schlüssel timezone neben cron an; Kubernetes hat das Feld .spec.timeZone, stabil seit Version 1.27, und lehnt CRON_TZ oder TZ im Zeitplan ab.
Durch die Sommerzeit fallen manche Ortszeiten weg oder kommen doppelt vor. Am 29. März 2026 springen die Uhren in Berlin, Paris, Madrid und Rom von 02:00 auf 03:00, also bezeichnet 30 2 * * * eine Zeit, die es nicht gibt; am 25. Oktober 2026 gibt es die Stunde von 02:00 bis 03:00 zweimal. In Lissabon und London ist es die Stunde von 01:00 bis 02:00.
| Zeitplaner | Job in der übersprungenen Stunde | Job in der doppelten Stunde |
|---|---|---|
| cronie (Umstellungen unter 3 Stunden, Jobs zu fester Zeit oder seltener als stündlich) | läuft direkt nach der Umstellung | läuft einmal |
| GitHub Actions (mit timezone) | rückt zur nächsten gültigen Zeit: aus 02:30 wird 03:00 | nicht angegeben |
| AWS EventBridge Scheduler (mit Zeitzone) | entfällt | läuft einmal |
| Zeitpläne in UTC | nicht betroffen | nicht betroffen |
Jobs, die öfter als einmal pro Stunde laufen, plant cronie ganz normal, und sein Crontab-Handbuch warnt allgemein, dass fehlende Zeiten nie passen und doppelte zweimal auslösen können; das Verhalten unterscheidet sich also von Cron zu Cron. Sicher ist es, den Zeitplan in UTC zu halten oder für Jobs, die genau einmal am Tag laufen müssen, die Zeit zwischen 01:00 und 03:00 Ortszeit zu meiden.
Die Umgebung eines Jobs
Ein Cron-Job bekommt nicht die Umgebung Ihres Terminals. Der Standard führt den Befehl mit sh und wenigen Variablen aus (HOME, LOGNAME, PATH und SHELL), daher kann ein Befehl, der beim Eintippen funktioniert, in Cron scheitern, weil ein Programm nicht im PATH liegt oder eine Variable fehlt. Verwenden Sie vollständige Pfade oder setzen Sie PATH am Anfang der Crontab.
Alles, was der Befehl ausgibt, wird per E-Mail an den Besitzer der Crontab geschickt; cronie schickt es stattdessen an die Adresse in MAILTO und schickt nichts, wenn MAILTO leer ist. Auf einem Server ohne eingerichtete Mail geht diese Ausgabe leicht verloren, also leiten Sie sie besser in eine Logdatei um.
0 3 * * * /usr/local/bin/backup >> /var/log/backup.log 2>&1Hängt normale Ausgabe und Fehler an ein Log an.5 0 * * * tar czf /srv/backup-$(date +\%F).tgz /srv/dataSchreibt ein Archiv mit Datum im Namen: die %-Zeichen sind maskiert.*/5 * * * * flock -n /tmp/sync.lock /usr/local/bin/syncÜberspringt einen Lauf, solange der vorige noch die Sperre hält.
Cron startet jeden Lauf pünktlich, egal ob der vorige fertig ist, daher kann ein Job, der manchmal länger als sein Intervall braucht, zweimal gleichzeitig laufen. flock aus util-linux hält während des Befehls eine Sperrdatei; mit -n gibt es sofort mit dem Exit-Status 1 auf, wenn die Sperre belegt ist. Kubernetes hat dieselbe Wahl eingebaut: concurrencyPolicy ist standardmäßig Allow und kann Forbid (neuen Lauf auslassen) oder Replace (alten beenden) sein.
Derselbe Zeitplan auf anderen Plattformen
Das Format mit fünf Feldern ist nicht universell. Manche Zeitplaner ergänzen Sekunden oder ein Jahr, manche verlangen ein Fragezeichen in einem der beiden Tagesfelder, weil sie die Entweder-oder-Regel nicht unterstützen, und manche zählen die Wochentage ab 1. „Werktags um 09:00“ in jedem:
| Zeitplaner | Ausdruck | Hinweise |
|---|---|---|
| Linux-Cron (cronie) | 0 9 * * 1-5 | Zeitzone der Maschine oder CRON_TZ. |
| GitHub Actions | 0 9 * * 1-5 | UTC, sofern timezone nicht gesetzt ist; höchstens alle 5 Minuten; keine @-Kurzformen. |
| Kubernetes CronJob | 0 9 * * 1-5 | Zeitzone des Controllers oder .spec.timeZone. |
| AWS EventBridge | cron(0 9 ? * MON-FRI *) | Sechs Felder mit Jahr; ? in einem Tagesfeld; die Tage 1–7 beginnen am Sonntag; geplante Regeln laufen in UTC. |
| Quartz (Java) | 0 0 9 ? * MON-FRI | Sekunden zuerst, Jahr optional; ? in einem Tagesfeld; die Tage 1–7 beginnen am Sonntag. |
| systemd-Timer | OnCalendar=Mon..Fri *-*-* 09:00:00 | Wochentag und Datum müssen beide passen; *-*~01 ist der letzte Tag des Monats. |
Wenn Sie einen Zeitplan in ein anderes System übernehmen, prüfen Sie die Zahl der Felder und die Nummerierung der Wochentage: 1 ist in Cron Montag, in Quartz und EventBridge aber Sonntag.
Warum ein Job nicht gelaufen ist
- Die Maschine war zu dem Zeitpunkt aus oder im Ruhezustand: Cron holt verpasste Läufe nicht nach. Ein systemd-Timer mit Persistent=true tut das beim nächsten Start.
- Der Zeitplan liegt in einer anderen Zeitzone, meist UTC.
- Der Befehl hängt vom PATH, einer Variablen oder dem aktuellen Ordner Ihres Terminals ab.
- Ein nicht maskiertes % hat den Befehl an dieser Stelle abgeschnitten.
- Tag des Monats und Wochentag waren beide gesetzt, und die Entweder-oder-Regel hat ihn an anderen Tagen gestartet, oder der Job wartete auf einen Tag, der nie kam.
- Auf einer gehosteten Plattform wurde ein Lauf verzögert oder verworfen: GitHub weist darauf hin, dass geplante Läufe zu Spitzenzeiten wie dem Beginn jeder Stunde verzögert werden können, und deaktiviert Zeitpläne in öffentlichen Repositorys nach 60 Tagen ohne Aktivität.
Bevor Sie sich auf einen Zeitplan verlassen, lesen Sie ihn Feld für Feld zurück und prüfen Sie unter Linux die nächsten Läufe: systemd-analyze calendar zeigt sie für einen Timer-Ausdruck an.
Häufige Fragen
Ist Sonntag 0 oder 7?
Beides, in cronie und den meisten Linux-Crons. Der POSIX-Standard definiert nur 0 bis 6, 0 ist Sonntag, also ist 0 die portable Wahl.
Kann Cron einen Job alle 30 Sekunden starten?
Nein: die kleinste Einheit ist die Minute. Zeitplaner mit Sekundenfeld wie Quartz können es, unter Linux auch ein systemd-Timer.
Wie starte ich einen Job alle 90 Minuten?
Mit zwei Zeilen: 0 0-21/3 * * * und 30 1-22/3 * * *. Zusammen laufen sie alle anderthalb Stunden, von 00:00 bis 22:30.
Was bedeutet 0 0 * * 0?
Mitternacht zu Beginn jedes Sonntags. In cronie ist das dasselbe wie @weekly.
Warum läuft mein Job an Tagen, die ich nicht gewählt habe?
Wahrscheinlich, weil beide Tagesfelder gesetzt sind. Der Standard-Cron startet den Job, wenn der Tag des Monats oder der Wochentag passt.
Quellen
- The Open Group Base Specifications (POSIX.1-2024) — crontab
- cronie — crontab(5): tables for driving cron
- cronie — cron(8): daylight saving time and other time changes
- util-linux — flock(1)
- GitHub Docs — Events that trigger workflows: schedule
- Kubernetes documentation — CronJob
- Amazon EventBridge — Cron expressions for scheduled rules
- Amazon EventBridge Scheduler — Schedule types (time zones and daylight saving)
- Quartz Scheduler — CronTrigger tutorial
- systemd — systemd.timer(5) and systemd.time(7): calendar events
Weitere Ratgeber
- IP-Adressen erklärt: IPv4, IPv6 und die reservierten Bereiche
- Subnetze und CIDR erklärt: Präfixe, Masken und nutzbare Hosts
- DNS-Einträge erklärt: A, AAAA, CNAME, MX, TXT und NS
- Ist eine Website down oder liegt es an Ihnen? So prüfen Sie es Schritt für Schritt
- HTTP-Statuscodes und Cloudflare-Fehler: was 403, 404, 429, 500, 503 und 521 bedeuten
- Unix-Zeitstempel und Zeitzonen erklärt
- Mit Datumsangaben rechnen: Tage zwischen zwei Daten, Schaltjahre und ISO-Wochen
- Zeitzonen und Sommerzeit: Termine über Städte hinweg
- Bildformate erklärt: JPEG, PNG, WebP, AVIF und HEIC
- Bildgröße erklärt: Pixel, DPI, Dateigröße und Qualität
- Handyfotos erklärt: HEIC, EXIF-Metadaten und Ihre Privatsphäre
- Passwortstärke erklärt: Länge, Entropie und Passphrasen
- Hashfunktionen erklärt: SHA-256, Prüfsummen und Passwort-Hashing
- JSON Web Tokens erklärt: Claims, Signaturen und sichere Prüfung
- API-Schlüssel erklärt: Länge, Format, Speicherung und Rotation
- UUIDs erklärt: v4, v7 und die Wahl der richtigen Version
- QR-Codes erklärt: Kapazität, Fehlerkorrektur und Druckgröße
- Prozente und Mehrwertsteuer erklärt: aufschlagen, herausrechnen, kombinieren
- Häufige JSON-Fehler und wie man sie behebt
- CSV-Dateien erklärt: Trennzeichen, Anführungszeichen, Kodierung und Excel
- Textkodierungen erklärt: UTF-8, Base64 und URL-Kodierung
- Reguläre Ausdrücke erklärt: Klassen, Quantoren und Gruppen
- MB oder MiB, Mbit/s oder MB/s: Dateigrößen und Geschwindigkeiten
- UTM-Parameter erklärt: Links so markieren, dass Analytics sie lesen kann
- Break-even, Marge und ROAS erklärt: die Zahlen hinter einem kleinen Unternehmen
- Freelancer-Stundensatz erklärt: Stundensatz, Tagessatz und abrechenbare Stunden
- PDFs im Browser bearbeiten: Was beim Zusammenfügen, Teilen und Umwandeln erhalten bleibt