Definition
Ein Cronjob ist ein zeitgesteuerter Hintergrundauftrag auf Unix-/Linux-Systemen. Er wird vom cron-Daemon anhand von Regeln aus sogenannten Crontab-Dateien automatisch ausgeführt (z. B. täglich um 02:30 Uhr). Jede Benutzerin/jeder Benutzer kann eigene Cronjobs definieren; Systemjobs existieren zusätzlich auf Ebene von /etc/crontab
, /etc/cron.d/*
und periodischen Verzeichnissen wie /etc/cron.daily
.

Ein Cronjob ist ein zeitgesteuerter, periodischer Hintergrundauftrag auf Unix/Linux, den der Cron-Daemon zu festgelegten Zeiten anhand definierter Crontab-Regeln automatisch ausführt.
Architektur und Grundprinzip
Ein Cronjob besteht aus zwei Teilen:
- Daemon
cron
(crond
): Ein Hintergrundprozess, der jede Minute Crontab-Einträge prüft und passende Befehle startet. Standardmäßig wird die Befehlszeile unter /bin/sh ausgeführt, es sei denn, Sie setzen in der CrontabSHELL=/bin/bash
o. Ä. - Crontab-Dateien: Textdateien mit Zeitmustern und Befehlen. Es gibt Benutzer-Crontabs (verwaltet mit
crontab -e
) sowie System-Crontabs (/etc/crontab
, Dateien in/etc/cron.d/
). System-Crontabs enthalten zusätzlich ein Benutzerfeld, das angibt, unter welchem Account der Job läuft.
Auf vielen Distributionen existieren ferner periodische Verzeichnisse (/etc/cron.hourly
, /etc/cron.daily
, /etc/cron.weekly
, /etc/cron.monthly
), die via run-parts
durch einen passenden System-Eintrag in /etc/crontab
bzw. durch Anacron/Systemd getriggert werden. In diese Verzeichnisse eingelegte, ausführbare Skripte werden automatisch zum vorgesehenen Intervall gestartet.
Die Crontab-Syntax – Felder, Operatoren, Sonderfälle
Die fünf Felder (Benutzer-Crontab)
Eine typische Cronzeile hat fünf Zeitfelder und danach die auszuführende Befehlszeile:
# m h dom mon dow command
5 2 * * * /usr/local/bin/backup.sh
- m Minute (0–59)
- h Stunde (0–23)
- dom Tag im Monat (1–31)
- mon Monat (1–12 oder Namen wie
jan
,feb
) - dow Wochentag (0–7, wobei 0 oder 7 = Sonntag; auch Namen wie
mon
erlaubt)
Zulässig sind *
(beliebig), Bereiche (8-11
), Listen (1,2,5,9
), Schrittweiten (*/5
, 0-23/2
) sowie Tagnamen/Monatsnamen.
OR-Logik von „Tag im Monat“ und „Wochentag“
Ein häufiges Missverständnis: Wenn beide Felder dom
und dow
eingeschränkt sind (also kein *
), genügt es für die Ausführung, wenn eines von beiden passt („OR-Semantik“). Beispiel:
30 4 1,15 * 5 # 4:30 Uhr am 1. und 15. des Monats UND zusätzlich jeden Freitag
Sonderzeichen, erweiterte Schreibweisen
- Prozentzeichen
%
in der Befehlszeile markiert standardmäßig Zeilenumbrüche; alles nach dem ersten%
geht an STDIN des Programms, sofern das%
nicht mit\%
escaped wird. Das unterscheidet sich von normaler Shell-Interpretation und überrascht oft. - Schrittweiten gelten nur innerhalb des jeweiligen Felds (z. B. führt
*/23
im Stundenfeld zu 00:00 und 23:00). - Namen statt Zahlen:
mon,wed,fri
oderjan-mar
sind erlaubt.
„Nicknames“ (Spezialstrings mit @
)
Statt fünf Feldern können Sie „Sprechformen“ verwenden:
@reboot
(einmalig nach dem Booten)@hourly
,@daily
,@weekly
,@monthly
,@yearly
/@annually
Diese sind äquivalent zu festen Mustern (z. B. @daily
≙ 0 0 * * *
).
System-Crontab & /etc/cron.d
Zeilen in /etc/crontab
und Dateien in /etc/cron.d/
integrieren ein zusätzliches sechstes Feld (den Benutzernamen), etwa:
# m h dom mon dow user command
1 5 * * * root run-parts /etc/cron.daily
Umgebung, Variablen & E-Mail
Standardumgebung und SHELL
cron
setzt u. a. SHELL=/bin/sh
, HOME
und LOGNAME
(manchmal USER
). Sie können SHELL
und HOME
in der Crontab überschreiben (nicht jedoch LOGNAME
). Die Befehlszeile wird standardmäßig von /bin/sh interpretiert.
MAILTO
, MAILFROM
, Content-Typen
MAILTO=user@example.com
bestimmt den Empfänger für die Ausgabe (STDOUT/STDERR), sofern es eine Ausgabe gibt. Leerer Wert (MAILTO=""
) unterdrückt Mails. Einige Implementierungen kennen auchMAILFROM
. Zusätzlich könnenCONTENT_TYPE
undCONTENT_TRANSFER_ENCODING
gesetzt werden.
CRON_TZ
und Zeitzonen
Manche Implementierungen (z. B. Cronie) unterstützen CRON_TZ=<TZ>
, womit die Interpretation der Zeiten in der Crontab auf eine bestimmte Zeitzone gesetzt wird (z. B. CRON_TZ=Europe/Berlin
). Wichtig: Nicht jedes System versteht CRON_TZ
; und das Setzen von TZ
in der Crontab beeinflusst oft nur die Umgebung des gestarteten Prozesses, nicht die Terminierung selbst.
Zeitempfindlichkeiten: Sommerzeit (DST) & „fehlende/ doppelte“ Zeiten
Während der Umstellung auf Sommer-/Winterzeit entstehen nicht existierende Zeitpunkte (z. B. „übersprungene Stunde“) und duplizierte Zeiten. Cron dokumentiert, dass ein Job in einer nicht existierenden Stunde nicht läuft, während ein Job in einer doppelt vorkommenden Stunde zweimal laufen kann. Planen Sie kritische Abläufe entsprechend robust (Idempotenz, Sperren).
Verwaltung: crontab
-Werkzeug & Zugriffskontrolle
- Bearbeiten/Listen/Löschen:
crontab -e
(Editieren mit$EDITOR
/$VISUAL
),crontab -l
(anzeigen),crontab -r
(entfernen; optional-i
für Sicherheitsabfrage). Nicht direkt in/var/spool/cron/crontabs
editieren. - Zugriff erlauben/verbieten: Über
/etc/cron.allow
(Whitelist) und/etc/cron.deny
(Blacklist) können Sie festlegen, wercrontab
benutzen darf. Existiertcron.allow
, hat es Vorrang. Root ist stets berechtigt.
Systemweite Periodik: run-parts
& die Verzeichnisse cron.*
Viele Distributionen verwenden run-parts
, um alle ausführbaren Dateien in /etc/cron.hourly
, /etc/cron.daily
, /etc/cron.weekly
, /etc/cron.monthly
aufzurufen. Wann diese Verzeichnisse laufen, ist in /etc/crontab
bzw. über Anacron/Systemd festgelegt (Distribution abhängig). Beachten Sie, dass run-parts
je nach System nur Dateien ohne Erweiterung ausführt.
Alternativen & Ergänzungen: Anacron und systemd-Timer
Anacron: „Nachholen“, falls der Rechner aus war
Anacron ist für nicht durchgängig laufende Systeme gedacht (z. B. Laptops). Es führt periodische Jobs nach, wenn diese während eines ausgeschalteten Zeitraums verpasst wurden. Das Verhalten wird via /etc/anacrontab
konfiguriert. Wichtige Variablen:
START_HOURS_RANGE
: Fenster (in Stunden), innerhalb dessen Anacron Jobs starten darf (z. B.6-8
).RANDOM_DELAY
: Zufallsverzögerung (in Minuten), um Lastspitzen zu vermeiden.- Jobs werden serialisiert nacheinander abgearbeitet.
Neuere Systeme koppeln Anacron häufig an systemd (als Service/Timer). Dabei kann sich das exakte Nachhol-Verhalten gegenüber klassischem Anacron unterscheiden (z. B. wöchentliche Jobs höchstens einmal pro 6 Tage vs. systemd, das „Montag 00:00 Uhr oder beim nächsten Boot“ versucht). Prüfen Sie die Manpages Ihrer Distribution.
systemd-Timer: Moderne Alternative mit Calendar-Ausdrücken
Statt Cron können Sie systemd-Timer nutzen (.timer
+ .service
). Vorteile: Journald-Logging, Abhängigkeiten, präzise OnCalendar-Ausdrücke (z. B. OnCalendar=Mon..Fri 08:00
, auch mehrere Termine pro Timer sind möglich). Syntax und Semantik sind anders als Cron und in systemd.timer(5)
/systemd.time(7)
dokumentiert.
Implementierungen & Abgrenzungen (Cronie, Vixie, Jenkins, Quartz)
- Cronie (viele Linux-Distros): Fork/Weiterentwicklung von Vixie-Cron mit u. a. PAM/SELinux,
CRON_TZ
,RANDOM_DELAY
, Test-Optionen. Details bei Guthub. - Vixie-Cron (historische Basis) & Varianten; Debian hat distributionseigene Erweiterungen (z. B.
/etc/cron.d
). - Nicht POSIX-Cron: Jenkins und Quartz verwenden cron-ähnliche Ausdrücke, abweichend von Unix-Cron:
Merksatz: Cron-Ausdrücke aus Jenkins/Quartz sind nicht 1:1 auf das System-cron
übertragbar.
Praxisbeispiele (sofort einsetzbar)
Hinweis: Verwenden Sie vollständige Pfade zu Programmen/Skripten und setzen Sie bei Bedarf SHELL
/PATH
, damit Jobs in der minimalen Cron-Umgebung sicher laufen.
Tägliche Sicherung um 02:30 Uhr
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
30 2 * * * /usr/local/bin/backup.sh >>/var/log/backup.log 2>&1
Erläuterung: Loggt STDOUT/STDERR in eine Datei und versendet bei Ausgabe zusätzlich E-Mail (je nach Setup).
Wochentage 08:00 Uhr
0 8 * * 1-5 /usr/local/bin/reports.sh
Montag–Freitag um 08:00.
Alle 5 Minuten
*/5 * * * * /usr/local/bin/healthcheck.sh
Schrittweite im Minutenfeld.
@reboot – einmalig nach dem Systemstart
@reboot /usr/local/bin/warmup.sh
Praktisch für Caches/Daemons, die nach Boot initialisiert werden sollen.
Unterschiedliche Zeitzonen (implementierungsabhängig)
CRON_TZ=Europe/Berlin
0 6 * * * /usr/local/bin/job_in_berlin.sh
CRON_TZ=America/New_York
0 6 * * * /usr/local/bin/job_in_ny.sh
Achtung: CRON_TZ
wird nicht überall unterstützt; prüfen Sie die Manpages Ihres Systems. Andernfalls sorgt TZ=
nur im Job-Prozess für die Zeitzone, nicht für die Terminierung.
System-Crontab: Job als bestimmter Benutzer
In /etc/crontab
:
# m h dom mon dow user command
15 3 * * * www-data /usr/local/bin/refresh_cdn.sh
Benutzerfeld nur in System-Crontabs.
run-parts
: Alles in /etc/cron.daily
ausführen
In /etc/crontab
(Distribution abhängig):
25 6 * * * root run-parts --report /etc/cron.daily
Periodische Verzeichnisse werden so angebunden.
Logging, Fehlerbilder & Debugging
Wohin loggt cron
?
- Cron startet Jobs und schreibt Start-/Ende-Meldungen und Status nach Syslog bzw. Journal (systemd). Die eigentliche Job-Ausgabe (STDOUT/STDERR) wird per Mail verschickt (sofern
MAILTO
gesetzt bzw. Standard-Mailzustellung vorhanden) oder Sie leiten explizit in Logdateien um.
Typische Umleitung:
0 * * * * /path/to/job.sh >>/var/log/job.log 2>&1
- Für feinere Kontrolle bzw. Journald-Integration erwägen Sie systemd-Timer (dort landet die Ausgabe per Default im Journal).
„Warum läuft mein Job nicht?“
Häufige Ursachen:
- Pfad/Umgebung: Cron hat eine minimale Umgebung – Interaktives
PATH
/Aliase/Profile fehlen. Setzen SiePATH
oben in der Crontab und verwenden Sie vollständige Pfade in Befehlen. - Berechtigungen/Dateirechte: Skript nicht ausführbar; falscher Benutzer (insbes. in
/etc/crontab
//etc/cron.d
). %
in Befehlszeile: Ohne Escape wird der Rest als STDIN in den Prozess geleitet.- DST/Zeitzonen: Sommerzeitumstellung (siehe oben).
run-parts
-Konventionen: Manche Systeme ignorieren Dateien mit Dateiendung incron.daily
etc. Testen Sie mitrun-parts --test
.
Debug-Tipps:
- Testen Sie die Crontab-Syntax (Implementationsabhängig, z. B.
crontab -T
vorhanden). - Lassen Sie Umgebungsvariablen einer Cron-Ausführung loggen (
* * * * * env > ~/cronenv
), um Unterschiede zur interaktiven Session sichtbar zu machen.
Sicherheit & Betrieb
- Least Privilege: Jobs nur mit den nötigen Rechten betreiben; für Systemjobs das
user
-Feld in/etc/crontab
nutzen. - Zugriff steuern mit
/etc/cron.allow
//etc/cron.deny
. - Idempotenz & Sperren: Verhindern Sie Doppelstarts (z. B. via Lockfiles oder
flock
), besonders rund um DST oder lange Laufzeiten. (Allgemeine Betriebsbest-Practice; konkrete Cron-Semantik s. oben zu DST.) - Pfad-Hygiene: Hart kodierte absolute Pfade; kein Verlass auf
PATH
. - Überwachung: Eigene Logfiles/Journald, E-Mail-Benachrichtigungen (
MAILTO
), ggf. externe Monitoring-Lösungen.
Unterschiede & Kompatibilität – worauf Sie achten sollten
- POSIX beschreibt grundlegend das Verhalten von
crontab
, u. a. zur Tag-Logik. Distributionen erweitern dies teils (z. B.@reboot
,/etc/cron.d
). Prüfen Sie stets die lokalen Manpages Ihrer Plattform. - Anbieter-Spezifika:
CRON_TZ
,RANDOM_DELAY
etc. sind implementierungsabhängig (Cronie vs. ältere crond-Varianten). - Nicht verwechseln mit Jenkins/Quartz-Ausdrücken (zusätzliche Felder/Operatoren).
Cron vs. at(1)
Cron ist für wiederkehrende Ausführungen gedacht. Einmalige, zeitversetzte Jobs gehören zu at
/atd
(z. B. „in 2 Stunden“). Der Debian-Leitfaden erläutert beide Dienste und deren Zugriffskontrolle.
Checkliste: robuste Cronjobs im Alltag
- Pfad & Shell setzen (
SHELL
,PATH
, absolute Pfade in Befehlen). - Ausgabe erfassen (Logfile/Journald) und Benachrichtigung aktivieren (
MAILTO
). - OR-Semantik von
dom
/dow
bewusst nutzen/umgehen. - DST-Effekte berücksichtigen (Idempotenz/Sperren).
- Umgebung prüfen (minimal; ggf.
env
dumpen und Profilskripte laden). - Zugriff kontrollieren (
/etc/cron.allow
/cron.deny
). - Distributionseigenheiten (z. B.
/etc/cron.d
,CRON_TZ
) nachlesen und nicht mit Jenkins/Quartz verwechseln.
Zusammengefasst
Ein Cronjob ist ein automatisch geplanter Systemauftrag, dessen Terminierung über kompakte Muster in einer Crontab definiert wird. Fünf Felder (Minute, Stunde, Tag, Monat, Wochentag) steuern die Ausführung, Sonderformen wie @daily
vereinfachen Standards. Distributionen bringen oft periodische Verzeichnisse (cron.daily
etc.) mit; Anacron holt verpasste Läufe nach, während systemd-Timer eine moderne Alternative mit sauberer Protokollierung und Abhängigkeiten darstellen. Achten Sie auf Umgebung, Pfade, Protokollierung, OR-Semantik von Tag/Wochentag sowie DST-Effekte.