cron ist der älteste und am weitesten verbreitete Scheduler unter Unix. Ein Daemon liest sogenannte Crontabs, vergleicht sie minütlich mit der aktuellen Uhrzeit und startet Befehle, sobald die Felder passen. Klassische Aufgaben sind Backups, Log-Rotation, Cleanup-Skripte oder regelmäßige Reports. Auf modernen Systemen steht cron neben systemd-Timern — beide haben ihre Berechtigung, aber cron bleibt durch seine Kompaktheit und universelle Verfügbarkeit unverzichtbar.
Was cron macht
cron ist ein Hintergrundprozess, der typischerweise bereits beim Systemstart aktiv wird (crond, cron oder vixie-cron, je nach Distribution). Einmal pro Minute prüft er, ob in einer der hinterlegten Crontabs eine Zeile zu der aktuellen Minute passt, und führt den entsprechenden Befehl aus. Es gibt keine Sub-Minuten-Auflösung — wer alle paar Sekunden etwas tun will, braucht ein anderes Werkzeug.
Klassische Anwendungsfälle:
- Backups in der Nacht, wenn niemand das System belastet
- Log-Rotation und Aufräumen alter Dateien
- Wiederkehrende Reports, etwa Mailversand am Monatsanfang
- System-Maintenance wie Paket-Cache-Bereinigung oder Datenbank-Vacuum
- Health-Checks und Monitoring-Skripte alle paar Minuten
Auf modernen Systemen mit systemd gibt es mit systemd-Timern eine Alternative, die mehr Kontrolle bietet (Abhängigkeiten, Logs in journalctl, Recovery nach Ausfall). cron bleibt aber wegen seiner Einfachheit und universellen Verfügbarkeit Standard auf nahezu jeder Linux- und Unix-Maschine.
crontab-Syntax
Eine Cron-Zeile besteht aus fünf Zeitfeldern, gefolgt vom auszuführenden Befehl. Die Reihenfolge ist immer dieselbe und sollte sitzen.
| Feld | Bedeutung | Erlaubter Bereich |
|---|---|---|
| 1 | Minute | 0 bis 59 |
| 2 | Stunde | 0 bis 23 |
| 3 | Tag im Monat | 1 bis 31 |
| 4 | Monat | 1 bis 12 (oder jan-dec) |
| 5 | Wochentag | 0 bis 7 (oder sun-sat, 0 und 7 = Sonntag) |
| 6 | Befehl | beliebige Shell-Zeile |
In jedem Feld sind verschiedene Schreibweisen möglich:
| Schreibweise | Bedeutung | Beispiel |
|---|---|---|
* | jeder Wert im Bereich | * * * * * = jede Minute |
*/n | alle n Einheiten | */5 = alle 5 Minuten |
a-b | Bereich von a bis b | 1-5 = Montag bis Freitag |
a,b,c | Liste konkreter Werte | 0,15,30,45 = viertelstündlich |
a-b/n | Schritt innerhalb Range | 0-30/10 = 0, 10, 20, 30 |
Eine typische Zeile sieht so aus — ausgeführt jeden Tag um 03:30 Uhr:
30 3 * * * /home/user/backup.shSpezielle Strings
Statt fünf Sterne zu schreiben, lassen sich häufige Schedules mit lesbaren Kürzeln ausdrücken. Das macht eine Crontab auf den ersten Blick verständlicher.
| Kürzel | Entspricht | Bedeutung |
|---|---|---|
@reboot | — | Einmal beim Cron-Start nach Boot |
@yearly / @annually | 0 0 1 1 * | Jährlich am 1. Januar 00:00 |
@monthly | 0 0 1 * * | Monatlich am Ersten 00:00 |
@weekly | 0 0 * * 0 | Wöchentlich am Sonntag 00:00 |
@daily / @midnight | 0 0 * * * | Täglich um Mitternacht |
@hourly | 0 * * * * | Zur vollen Stunde |
Nicht jede cron-Implementation kennt alle Kürzel — @reboot ist zum Beispiel auf Vixie-cron, ISC-cron und cronie verfügbar, aber nicht auf jedem minimalistischen Embedded-cron.
Eigene crontab — crontab -e
Jeder User hat seine eigene Crontab. Sie wird nicht direkt als Datei bearbeitet, sondern über das Werkzeug crontab, das die Datei nach Speichern validiert.
| Befehl | Wirkung |
|---|---|
crontab -e | Eigene Crontab im $EDITOR öffnen |
crontab -l | Eigene Crontab auflisten |
crontab -r | Eigene Crontab komplett löschen — ohne Rückfrage |
crontab -u name -e | Crontab eines anderen Users editieren (root) |
crontab -r löscht alle Einträge auf einmal und fragt nicht nach. Wer das versehentlich auslöst, hat keinen Backup-Mechanismus. Best Practice: Vorher crontab -l > meine-crontab.bak sichern.
Welcher Editor benutzt wird, steuert die Variable EDITOR (oder VISUAL):
EDITOR=vim crontab -eDie intern gespeicherten Crontabs liegen unter /var/spool/cron/crontabs/ (Debian) oder /var/spool/cron/ (Red Hat) — diese Dateien sollten nie direkt editiert werden, da cron sie sonst ignoriert oder neu lädt.
System-Crontabs
Neben den User-Crontabs gibt es System-weite Mechanismen. Sie unterscheiden sich in einem entscheidenden Detail: Vor dem Befehl steht eine User-Spalte, weil das System wissen muss, mit welchen Rechten der Job läuft.
| Pfad | Zweck | Format |
|---|---|---|
/etc/crontab | Zentrale System-Crontab | 5 Zeitfelder + User + Befehl |
/etc/cron.d/ | Einzeldateien für Pakete und Admins | wie /etc/crontab, mit User-Spalte |
/etc/cron.hourly/ | Skripte stündlich | nur ausführbare Skripte, keine Cron-Syntax |
/etc/cron.daily/ | Skripte täglich | nur Skripte |
/etc/cron.weekly/ | Skripte wöchentlich | nur Skripte |
/etc/cron.monthly/ | Skripte monatlich | nur Skripte |
In den /etc/cron.{hourly,daily,weekly,monthly}/-Verzeichnissen brauchst du keine Cron-Zeile zu schreiben — du legst einfach ein ausführbares Skript ab. cron (oder anacron, siehe nächster Abschnitt) startet es zum entsprechenden Zeitpunkt. Die Reihenfolge richtet sich nach dem Dateinamen, daher sind Präfixe wie 00-cleanup oder 10-backup üblich.
anacron
Klassischer cron geht davon aus, dass das System 24/7 läuft. Auf Servern stimmt das. Auf Laptops oder Workstations, die nachts ausgeschaltet sind, würden Jobs um 03:00 Uhr nie ausgeführt.
anacron löst dieses Problem: Es merkt sich, wann ein Job zuletzt erfolgreich gelaufen ist (in /var/spool/anacron/), und holt versäumte Daily-, Weekly- und Monthly-Jobs nach, sobald das System wieder läuft. Konfiguriert wird das in /etc/anacrontab.
Auf vielen Distributionen (Ubuntu, Fedora) ist anacron so eingebunden, dass cron die cron.daily/cron.weekly/cron.monthly-Verzeichnisse gar nicht direkt ausführt — stattdessen ruft eine cron-Zeile anacron auf, das dann nach Bedarf nachholt. Wer auf einem Laptop nicht versteht, warum die Daily-Jobs nicht zur erwarteten Uhrzeit laufen, findet hier die Erklärung.
Cron-Output und Logs
cron behandelt jeden auf stdout oder stderr ausgegebenen Text als Mail. Wenn ein Job etwas ausgibt, schickt cron eine lokale Mail an den User (über sendmail oder einen anderen MTA). Auf Servern ohne Mail-Setup landet diese Mail nirgends — die Ausgabe geht verloren.
In der Praxis ist das Standard-Pattern: Output explizit selbst loggen.
0 3 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1>> hängt an die Log-Datei an, 2>&1 leitet stderr ebenfalls dort hinein. So sind Erfolgs- und Fehlermeldungen an einer Stelle nachlesbar.
cron selbst loggt seine Aktivität (welcher Job wann gestartet wurde) ins System-Log. Je nach Distribution findest du diese Einträge mit:
journalctl -u cronAuf Systemen ohne systemd liegt das Cron-Log oft in /var/log/syslog oder /var/log/cron.
Cron-Restrictions
Standardmäßig darf jeder User seine eigene Crontab pflegen. Wer das einschränken will, nutzt zwei Dateien:
| Datei | Wirkung |
|---|---|
/etc/cron.allow | Wenn vorhanden: nur gelistete User dürfen crontab -e |
/etc/cron.deny | Wenn vorhanden: gelistete User dürfen nicht |
Existiert cron.allow, wird cron.deny ignoriert. Existiert keine der beiden, hängt das Standardverhalten von der Distribution ab — typischerweise dürfen alle User. root ist von beiden Dateien ausgenommen.
Praxis-Patterns
Konkrete Beispiele aus dem Alltag — jeder Block ist erläutert.
Daily-Backup um 3 Uhr, Output in eine Log-Datei umgeleitet, damit nichts an den lokalen MTA geschickt wird:
0 3 * * * /home/user/backup.sh > /var/log/backup.log 2>&1Beim Boot ein Service-Skript starten — praktisch für User-Services, die nicht über systemd laufen sollen:
@reboot /home/user/start-services.shAlle 15 Minuten einen Health-Check ausführen. */15 bedeutet: Minute 0, 15, 30, 45 jeder Stunde:
*/15 * * * * /usr/local/bin/check.shWerktags um 9 Uhr eine Morgenmail verschicken. 1-5 umfasst Montag bis Freitag (Sonntag = 0):
0 9 * * 1-5 /usr/local/bin/morning-mail.shPATH explizit setzen — als erste Zeilen der Crontab. Cron startet mit minimalem Environment, in dem /usr/local/bin oft fehlt:
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
MAILTO=admin@example.comFür einmalige Läufe in der Zukunft (zum Beispiel zum Testen) ist at der passendere Befehl — cron ist nur für wiederkehrende Aufgaben gedacht.
Stolperfallen
Cron startet mit minimalem Environment
cron-Jobs laufen nicht mit deiner interaktiven Shell-Umgebung. Es gibt kein ~/.bashrc, kein vollständiges PATH, oft kein HOME im erwarteten Sinne. Das ist die häufigste Ursache für „Mein Skript läuft im Terminal, aber nicht in cron”. Lösung: PATH und andere benötigte Variablen entweder oben in der Crontab setzen oder im Skript selbst per source einlesen. Skripte vorab mit env -i bash -c 'mein-skript.sh' testen — das simuliert das leere cron-Env.
Prozentzeichen sind Newline-Trigger
In einer Crontab-Zeile bedeutet ein nicht-escaptes % einen Zeilenumbruch — alles nach dem ersten % wird als stdin an den Befehl gegeben. Ein date +%Y-%m-%d direkt in der Crontab schlägt fehl. Entweder mit Backslash escapen (\%Y-\%m-\%d) oder den Befehl in ein Skript auslagern, das selber date aufruft. Letzteres ist die robustere Variante.
Wochentag 0 oder 7 = Sonntag — je nach cron
Klassisch akzeptiert cron sowohl 0 als auch 7 für Sonntag. Manche minimalen Implementationen kennen nur 0-6 oder nur 1-7. Wer auf einem ungewöhnlichen System schreibt, sollte das vorher in der Manpage nachsehen — eine Crontab, die auf Linux funktioniert, kann auf BusyBox-cron eines Embedded-Systems still scheitern.
Tag und Wochentag sind ODER, nicht UND
Wenn du sowohl Tag-im-Monat als auch Wochentag setzt, läuft der Job, sobald eine der beiden Bedingungen passt — nicht beide. 0 0 1 * 1 startet am Ersten jedes Monats und an jedem Montag. Wer ausschließlich „Montag, der ein Erster ist” will, kommt mit reiner Cron-Syntax nicht aus und braucht eine if-Prüfung im Skript.
Mail-Output ohne MTA verschwindet
cron versucht, jede Ausgabe per Mail zu verschicken. Auf Servern ohne installierten Mail Transfer Agent (Postfix, sendmail, ssmtp) landen diese Mails im Nirgendwo. Praktischer Effekt: Fehlermeldungen sind unsichtbar, du erfährst nicht, dass ein Job fehlschlägt. Konsequenz: Immer explizit in eine Log-Datei umleiten — >> /var/log/job.log 2>&1 — und das Log regelmäßig sichten oder per Monitoring überwachen.
`crontab -e` als root ist eine andere Crontab
Die Crontab gehört zum jeweiligen User. Wer sudo crontab -e eingibt, editiert die root-Crontab — nicht die eigene. Andersherum: Ein User-Job läuft mit den Rechten des Users, nicht mit root-Rechten. Vor jedem crontab -e lieber whoami ausführen oder crontab -u name -e mit explizitem User verwenden.
`@reboot` läuft nicht bei Container-Restart
@reboot startet den Job, wenn der cron-Daemon anläuft. In Containern ist cron oft gar nicht der Init-Prozess, läuft separat oder gar nicht. Ein Container-Restart ist daher nicht dasselbe wie ein klassischer System-Boot. Wer in Containern Init-artige Tasks braucht, nutzt das Container-eigene Entrypoint-Skript oder einen dedizierten Init wie tini.
Daylight Saving Time verdoppelt oder verschluckt Jobs
Bei der Zeitumstellung kann ein Job, der zwischen 02:00 und 03:00 Uhr terminiert ist, doppelt laufen (Winterzeit-Umstellung) oder gar nicht (Sommerzeit-Umstellung). Klassisches cron hat dagegen keine eingebaute Schutzlogik. Wer DST-immune Schedules braucht, ist mit systemd-Timern (OnCalendar= mit Persistent=true) oder mit fester UTC-Systemzeit besser aufgehoben.
Skripte vor cron-Einsatz mit leerem Env testen
Bevor du ein Skript per cron einplanst, simuliere die cron-Umgebung im Terminal: env -i HOME=$HOME PATH=/usr/bin:/bin bash -c '/pfad/zum/skript.sh'. Wenn es so durchläuft, läuft es auch unter cron. Das spart die typische Schleife aus „in cron einbauen, warten, fehlschlagen, debuggen”.
`crontab.guru` nutzen, aber nicht blind vertrauen
Online-Tools wie crontab.guru sind Gold wert, um komplexe Ausdrücke zu verifizieren. Sie zeigen aber nur die Standard-Vixie-Semantik. Distributionsspezifische Erweiterungen (@reboot-Verhalten, Random-Delays bei anacron, MAILTO-Variablen) sind nicht abgedeckt — im Zweifel die crontab(5)-Manpage des konkreten Systems lesen.
Weiterführende Ressourcen
Externe Quellen
- crontab(1) — Manpage — Bedienung des
crontab-Werkzeugs - crontab(5) — Manpage — Format der Crontab-Datei mit allen Feldern und Sondersyntax
- Arch Wiki: cron — Praxisnaher Überblick mit Implementations-Vergleich
- crontab.guru — Interaktiver Online-Tester für Cron-Ausdrücke
- anacron(8) — Manpage — Konfiguration und Verhalten von anacron
Verwandte Artikel
- at — Einmalige zeitgesteuerte Aufgaben
- systemd-Timer — Moderne Alternative mit besseren Logs und Recovery
- Prozess-Modell — Wie Linux-Prozesse aufgebaut sind
- Shell-Scripting — Skripte schreiben, die cron startet
- Signale — Prozesse beenden und steuern