Guides 8 Min. Lesezeit

Cron-Ausdrücke erklärt: Syntax, Beispiele und häufige Fehler

Ein Cron-Ausdruck besteht aus fünf Feldern, die festlegen, wann ein Job läuft. Syntax, Sonderzeichen und Kürzel wie @daily, fertige Beispiele sowie die Zeitzonen- und PATH-Fehler, an denen Jobs scheitern.

Ein Cron-Ausdruck besteht aus fünf durch Leerzeichen getrennten Feldern: Minute, Stunde, Tag des Monats, Monat und Wochentag, gefolgt vom auszuführenden Befehl. 30 2 * * * bedeutet „täglich um 02:30 Uhr“. Jedes Feld akzeptiert eine Zahl, ein * für „jeder Wert“, eine Liste mit Kommas, einen Bereich mit Bindestrich oder eine Schrittweite mit Schrägstrich. Die meisten Cron-Probleme entstehen nicht durch die Syntax selbst, sondern durch das Drumherum: die Zeitzone des Servers, die Regel für die Kombination von Tag des Monats und Wochentag und die minimale Umgebung, in der Cron Befehle ausführt.

Dieser Leitfaden erklärt jedes Feld und jedes Sonderzeichen, liefert eine Tabelle mit sofort nutzbaren Ausdrücken und geht die Fehler durch, durch die Jobs zur falschen Zeit oder gar nicht laufen.

Die fünf Felder

Jede Zeile in einer Benutzer-Crontab folgt demselben Aufbau:

┌───────────── Minute (0–59)
│ ┌─────────── Stunde (0–23)
│ │ ┌───────── Tag des Monats (1–31)
│ │ │ ┌─────── Monat (1–12 oder JAN–DEC)
│ │ │ │ ┌───── Wochentag (0–7 oder SUN–SAT, 0 und 7 sind beide Sonntag)
│ │ │ │ │
* * * * * /path/to/command

Ein Job läuft, wenn die aktuelle Minute zu allen Feldern passt – mit einer Ausnahme für die beiden Tagesfelder, die weiter unten erklärt wird. Monate und Wochentage lassen sich als dreibuchstabige englische Namen schreiben, Groß- und Kleinschreibung spielt dabei keine Rolle.

Ihre eigene Crontab bearbeiten Sie mit crontab -e und zeigen sie mit crontab -l an. Systemweite Dateien, also /etc/crontab und die Dateien in /etc/cron.d/, haben zwischen Zeitplan und Befehl ein sechstes Feld: den Benutzer, unter dem der Job läuft. Eine Zeile von einem Format ins andere zu kopieren, ohne dieses Feld zu ergänzen oder zu entfernen, ist ein Klassiker, um einen Job kaputtzumachen.

Sonderzeichen

ZeichenBedeutungBeispielErgebnis*Jeder Wert* * * * *Jede Minute,Liste von Werten0 8,12,18 * * *Um 08:00, 12:00 und 18:00 Uhr-Bereich0 9 * * 1-509:00 Uhr, Montag bis Freitag/Schrittweite*/15 * * * *Minuten 0, 15, 30 und 45

Wie Schrittweiten wirklich funktionieren

Eine Schrittweite teilt den Wertebereich eines Felds ein, beginnend mit dem ersten Wert. */15 im Minutenfeld bedeutet 0, 15, 30 und 45. Eine Schrittweite lässt sich auch auf einen Bereich anwenden: 0-30/10 bedeutet die Minuten 0, 10, 20 und 30.

Schrittweiten beginnen an der Grenze des Felds von vorn. */7 im Minutenfeld läuft um 0, 7, 14 und so weiter bis 56, dann wieder um 0 – die letzte Lücke jeder Stunde beträgt also nur vier Minuten. */7 heißt nicht „alle sieben Minuten“. Auch „alle 90 Minuten“ lässt sich mit klassischem Cron nicht in einer Zeile ausdrücken; dafür brauchen Sie zwei Zeilen oder eine Prüfung im Skript.

Syntax, die nicht zum klassischen Cron gehört

In Dokumentationen begegnen Ihnen eventuell L (letzter), W (nächster Werktag), # (n-ter Wochentag im Monat) und ?. Diese stammen aus Quartz und einigen Cloud- und CI-Schedulern, nicht vom Cron auf einem Linux-Server, und manche dieser Scheduler stellen außerdem ein Sekundenfeld voran. Viele Cron-Varianten lehnen zudem Bereiche aus Namen ab, schreiben Sie also 1-5 statt MON-FRI.

Kürzel wie @daily

Die meisten Cron-Implementierungen unter Linux akzeptieren anstelle der fünf Felder ein benanntes Kürzel:

@reboot: einmal, wenn der Cron-Daemon nach einem Neustart startet.

@yearly oder @annually: 0 0 1 1 *, Mitternacht am 1. Januar.

@monthly: 0 0 1 * *, Mitternacht am Ersten des Monats.

@weekly: 0 0 * * 0, Mitternacht zwischen Samstag und Sonntag.

@daily oder @midnight: 0 0 * * *.

@hourly: 0 * * * *.

Alle Kürzel feuern zur vollen Stunde oder um Mitternacht, auf einem ausgelasteten Server konkurrieren also alle Jobs um 00:00 Uhr um dieselben Ressourcen. Wenn Sie den vollständigen Ausdruck mit einer krummen Minute schreiben, etwa 17 0 * * *, verteilt sich die Last.

Cron-Ausdrücke zum direkten Übernehmen

AusdruckLäuft* * * * *Jede Minute*/5 * * * *Alle 5 Minuten*/15 * * * *Alle 15 Minuten0 * * * *Jede Stunde, zur vollen Stunde15 */2 * * *In Minute 15 jeder zweiten Stunde: 00:15, 02:15, 04:15 und so weiter0 9-17 * * 1-5Stündlich von 09:00 bis 17:00 Uhr, Montag bis Freitag*/10 8-18 * * 1-5Alle 10 Minuten während der Bürozeiten an Werktagen30 2 * * *Täglich um 02:30 Uhr0 8,12,18 * * *Dreimal täglich: 08:00, 12:00 und 18:00 Uhr0 6 * * 1Jeden Montag um 06:00 Uhr0 22 * * 5Jeden Freitag um 22:00 Uhr0 0 * * 0Jeden Sonntag um Mitternacht0 3 1 * *Am Ersten jedes Monats um 03:00 Uhr0 4 1,15 * *Am 1. und 15. jedes Monats um 04:00 Uhr0 5 1 */3 *Vierteljährlich: am 1. Januar, April, Juli und Oktober um 05:00 Uhr0 0 1 1 *Einmal im Jahr, um Mitternacht am 1. Januar@rebootEinmal nach jedem Systemstart

Ein häufiger Fehler in diesem Zusammenhang ist * */2 * * *. Das läuft nicht alle zwei Stunden, sondern jede Minute in jeder zweiten Stunde, sechzigmal hintereinander. Wenn Sie die Stunde einschränken, legen Sie immer auch die Minute fest.

Tag des Monats und Wochentag: die ODER-Regel

Alle Felder werden mit UND verknüpft, außer den beiden Tagesfeldern. Sind sowohl Tag des Monats als auch Wochentag eingeschränkt, also keines von beiden *, läuft der Job, sobald eines davon passt. Diese Zeile:

0 9 1 * 1 /usr/local/bin/report.sh

läuft also um 09:00 Uhr am Ersten jedes Monats und jeden Montag um 09:00 Uhr – nicht nur an Montagen, die auf den Ersten fallen. Aus demselben Grund bedeutet 0 9 1-7 * 1 nicht „der erste Montag im Monat“; der Job läuft an den Tagen 1 bis 7 und an jedem Montag. Für den ersten Montag planen Sie die Tage 1 bis 7 ein und prüfen den Wochentag im Befehl. Beachten Sie das maskierte Prozentzeichen, das weiter unten erklärt wird:

0 9 1-7 * * [ „$(date +\%u)“ = „1“ ] && /usr/local/bin/report.sh

Einen „letzten Tag des Monats“ kennt klassisches Cron ebenfalls nicht. Mit GNU date planen Sie die Tage 28 bis 31 ein und führen den Befehl nur aus, wenn morgen der Erste ist:

0 23 28-31 * * [ „$(date -d tomorrow +\%d)“ = „01“ ] && /usr/local/bin/month-end.sh

Zeitzonen und Sommerzeit

Cron nutzt die Zeitzone des Systems, auf dem es läuft. Ein Job, der für Stockholmer Zeit geschrieben wurde, startet auf einem Server in UTC je nach Jahreszeit eine oder zwei Stunden versetzt. Prüfen Sie die Zeitzone des Servers mit timedatectl oder date, bevor Sie einen Zeitplan festlegen. Verwenden Sie dieselbe Zeitzone auch beim Monitoring des Jobs: Cron-Monitore von Uptimecheck übernehmen den Crontab-Zeitplan zusammen mit einer Zeitzone, sodass die erwarteten Laufzeiten zu denen des Servers passen.

Manche Implementierungen wie cronie akzeptieren am Anfang der Crontab eine Variable CRON_TZ, um die Zeitpläne in einer anderen Zeitzone auszuführen. Die Unterstützung unterscheidet sich je nach Cron-Version – testen Sie es also, statt davon auszugehen, dass es funktioniert.

Die Sommerzeit sorgt für die merkwürdigsten Fehler. Im Frühjahr gibt es eine Ortsstunde gar nicht, im Herbst gibt es eine Stunde zweimal. Ein Job, der ungefähr zwischen 01:00 und 03:00 Uhr Ortszeit geplant ist, kann ausfallen, sich verzögern oder doppelt laufen, und jede Cron-Implementierung geht mit der Umstellung anders um. Die sichersten Optionen:

Betreiben Sie Server in UTC, das keine Sommerzeit kennt, und rechnen Sie im Kopf oder in einem Kommentar um.

Muss der Server in Ortszeit laufen, legen Sie wichtige Jobs außerhalb der Stunden, in denen die Uhr umgestellt wird.

Schreiben Sie die Zeitzone als Kommentar über jeden Job, damit die nächste Person nicht raten muss.

Machen Sie Jobs so robust, dass ein doppelter Lauf nicht schadet, zum Beispiel indem Sie prüfen, ob der heutige Export schon existiert.

Stolperfallen bei Umgebung und PATH

Ein Befehl, der im Terminal funktioniert und unter Cron scheitert, scheitert fast immer an der Umgebung. Cron lädt Ihr Shell-Profil nicht, daher fehlt vieles, was Sie für selbstverständlich halten:

PATH ist minimal, oft nur /usr/bin:/bin. Befehle in /usr/local/bin oder Tools, die mit nvm, pyenv, rbenv oder Composer installiert wurden, werden nicht gefunden. Verwenden Sie absolute Pfade oder setzen Sie PATH am Anfang der Crontab.

Die Shell ist /bin/sh, nicht bash. Reine Bash-Syntax wie [[ ]] oder source schlägt fehl. Setzen Sie SHELL=/bin/bash oder lagern Sie die Logik in ein Skript mit Bash-Shebang aus.

Prozentzeichen haben eine Sonderbedeutung. In einer Crontab-Zeile wird % in einen Zeilenumbruch umgewandelt. date +%F muss als date +\%F geschrieben oder in ein Skript verschoben werden.

Das Arbeitsverzeichnis ist das Home-Verzeichnis des Benutzers, nicht Ihr Projekt. Relative Pfade zeigen ins Leere. Wechseln Sie zuerst mit cd ins Projekt.

Umgebungsvariablen fehlen. API-Schlüssel und Datenbank-URLs, die in der .bashrc exportiert werden, existieren nicht. Laden Sie sie im Skript aus einer Datei.

Ausgaben verschwinden. Cron schickt Ausgaben per Mail an MAILTO, sofern Mail eingerichtet ist – und auf den meisten Servern ist das nicht der Fall. Leiten Sie die Ausgabe in eine Logdatei um.

Läufe können sich überschneiden. Braucht ein Job, der alle fünf Minuten läuft, manchmal sieben, laufen zwei Instanzen gleichzeitig. flock -n überspringt einen Lauf, solange der vorherige die Sperre hält.

Manche Cron-Versionen ignorieren außerdem eine letzte Zeile, die nicht mit einem Zeilenumbruch endet. Eine Crontab, die all das berücksichtigt, sieht so aus:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=““

# Nächtliches Datenbank-Backup. Serverzeit ist UTC.
30 2 * * * cd /var/www/fjordstudio && flock -n /tmp/backup.lock ./bin/backup.sh >> /var/log/backup.log 2>&1

So testen Sie einen Cron-Ausdruck

Lassen Sie ihn sich in Worten vorlesen. Fügen Sie den Ausdruck in einen Cron-Parser ein und prüfen Sie, ob die Beschreibung und die nächsten Ausführungszeiten dem entsprechen, was Sie gemeint haben.

Führen Sie den Befehl in der Cron-Umgebung aus. Eine abgespeckte Umgebung reproduziert die meisten „Im Terminal geht’s doch“-Fehler, bevor Sie auf den Zeitplan warten.

Planen Sie ihn einmal minütlich ein. Setzen Sie vorübergehend * * * * *, beobachten Sie den Lauf und stellen Sie dann den echten Zeitplan ein.

Prüfen Sie, ob Cron ihn gestartet hat. Unter Debian und Ubuntu mit grep CRON /var/log/syslog oder journalctl -u cron, auf Red-Hat-basierten Systemen mit /var/log/cron oder journalctl -u crond.

Stellen Sie sicher, dass die Crontab installiert ist, mit crontab -l als der Benutzer, der den Job ausführen soll.

So simulieren Sie die Cron-Umgebung in einer Shell:

env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=“$HOME“ /bin/sh -c ‚/usr/local/bin/backup.sh‘

Jeden Job mit einem Heartbeat absichern

Ein korrekter Ausdruck sagt Cron nur, wann ein Job starten soll. Ob er gelaufen ist oder fertig wurde, verrät er nicht. Ein Neustart, eine überschriebene Crontab oder eine fehlende Variable – all das scheitert lautlos.

Ein Heartbeat schließt diese Lücke. Der Job ruft nach erfolgreichem Abschluss eine eindeutige URL auf, und der Monitoring-Dienst alarmiert Sie, wenn dieser Aufruf nicht rechtzeitig eintrifft:

30 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 –retry 3 https://heartbeat.example.com/your-unique-id > /dev/null

Stellen Sie das erwartete Intervall des Heartbeats auf denselben Zeitplan wie den Cron-Ausdruck ein, mit etwas Puffer für langsame Läufe: 24 Stunden plus etwas Spielraum für einen nächtlichen Job, eine Stunde plus etwas Spielraum für einen stündlichen. Das Cron-Job-Monitoring von Uptimecheck funktioniert genau so: mit Alarmen, wenn ein Ping ausbleibt, und einer Entwarnung, sobald sich der Job wieder meldet. Die Cron-Monitore übernehmen den Crontab-Zeitplan in Ihrer Zeitzone, akzeptieren Start- und End-Pings auf einem Monitor, alarmieren, wenn ein Lauf seine maximale Laufzeit überschreitet, und können den Exit-Code und die Ausgabe des Jobs speichern. Der Leitfaden Cron-Jobs mit Heartbeats überwachen beschreibt die Einrichtung im Detail, und verpasste Cron-Aufgaben verhindern behandelt die Gewohnheiten rund um das Thema.

Bleibt ein Heartbeat aus, liegt die Ursache oft auf dem Server: eine volle Festplatte, erschöpfter Arbeitsspeicher oder ein ungeplanter Neustart. Server-Monitoring neben Ihren Heartbeats zeigt diese Ursache im selben Moment.

Checkliste: häufige Fehler

Die Stunde einschränken, die Minute aber auf * lassen.

Beide Tagesfelder setzen und UND statt ODER erwarten.

Davon ausgehen, dass der Server in Ihrer Zeitzone läuft.

Wichtige Jobs in die Stunde der Zeitumstellung legen.

Relative Pfade, Bash-Syntax oder nicht maskierte % verwenden.

Einen Job ohne Heartbeat betreiben, sodass niemand merkt, wenn er stehen bleibt.

Zusammenfassung

Fünf Felder, vier Sonderzeichen und eine Handvoll Kürzel decken fast jeden Zeitplan ab, den Sie brauchen werden. Der Ausdruck ist selten das Problem. Zeitzonen, die ODER-Regel für die Tagesfelder und die karge Umgebung von Cron sind es. Notieren Sie die Zeitzone neben jedem Job, verwenden Sie absolute Pfade, protokollieren Sie die Ausgabe und geben Sie jedem wichtigen Job einen Heartbeat.

Heartbeats von Uptimecheck sind in jedem Tarif enthalten, auch im Free-Tarif, zusammen mit Uptime-, SSL-, Domain- und DNS-Monitoring. Starten Sie die 14-tägige kostenlose Testphase, ohne Kreditkarte.

Fragen

Was bedeutet */5 * * * * in Cron?

Alle fünf Minuten: in den Minuten 0, 5, 10 und so weiter bis 55 jeder Stunde, an jedem Tag.

Wie lasse ich einen Cron-Job alle zwei Stunden laufen?

Mit 0 */2 * * *, das in Minute 0 jeder zweiten Stunde läuft. * */2 * * * dagegen läuft jede Minute in jeder zweiten Stunde.

Welche Zeitzone verwendet Cron?

Die Zeitzone des Systems, auf dem es läuft. Viele Cloud-Server und Container nutzen UTC, prüfen Sie es also mit timedatectl oder date, bevor Sie einen Zeitplan festlegen. Manche Implementierungen unterstützen eine Variable CRON_TZ.

Warum funktioniert mein Cron-Job im Terminal, aber nicht in Cron?

Cron führt Befehle mit minimalem PATH, /bin/sh als Shell, dem Home-Verzeichnis als Arbeitsverzeichnis und ohne Ihr Shell-Profil aus. Verwenden Sie absolute Pfade, maskieren Sie %-Zeichen und schreiben Sie die Ausgabe in ein Log, um den Fehler zu sehen.

Weiterlesen

Guides 6 Min. Lesezeit

Cron-Jobs mit Heartbeats überwachen

Cron-Jobs scheitern lautlos. Ein Heartbeat-Monitor alarmiert Sie, wenn sich ein geplanter Job nicht rechtzeitig meldet. Wie Heartbeats funktionieren, wie Sie einen in die Crontab einbauen und welche Einstellungen Sie wählen.

Lesen

Downtime ist von gestern.

Richten Sie Ihren ersten Monitor in weniger als einer Minute ein – oder sehen Sie sich zuerst die Live-Demo an.

14 Tage kostenlos testen · Danach gratis für 5 Monitore · Keine Kreditkarte