Cron und crontab richtig nutzen – die Grundlagen
Cron und crontab sauber verstehen: Zeitfelder lesen, erste Jobs anlegen, PATH- und Logging-Fallen vermeiden und jeden Schritt direkt verifizieren.

Cron ist eines der klassischen Werkzeuge unter Linux, wenn Befehle oder Skripte automatisch zu bestimmten Zeiten laufen sollen. Typische Beispiele sind Backups, kleine Prüfjobs, Aufräumarbeiten oder regelmäßige Berichte. Viele Probleme mit Cron entstehen nicht, weil die Idee kompliziert wäre, sondern weil kleine Details wie Pfade, Benutzerkontext oder Logging übersehen werden.
Genau deshalb gehen wir in dieser Anleitung bewusst nicht nur die Syntax durch. Wir bauen zuerst einen kleinen Testjob, prüfen danach, ob Cron ihn wirklich ausgeführt hat, und arbeiten uns dann zu Zeitfeldern, Sonderstrings und System-Crontabs vor. So verstehst du nicht nur, wie ein Cronjob aussieht, sondern auch, woran du erkennst, dass er sauber läuft.
Voraussetzungen
- Ein Linux-System mit installiertem Cron-Daemon, zum Beispiel
cronauf Debian/Ubuntu odercrondauf RHEL/Fedora/Rocky - Terminalzugang zu deinem Benutzerkonto
- Für systemweite Cron-Jobs unter
/etc/crontaboder/etc/cron.d/zusätzlich sudo-Rechte - Ein Verzeichnis, in dem du einen ungefährlichen Testjob anlegen kannst
Wichtig vorab: Für das Lernen ist ein kleiner Testjob besser als sofort ein produktives Backup oder ein echtes Wartungsskript. So siehst du direkt, ob Cron grundsätzlich funktioniert, ohne bei Fehlern Schaden anzurichten.
Schritt 1: Einen einfachen Testjob vorbereiten
Bevor du Zeitfelder auswendig lernst, erzeugen wir einen Job, dessen Wirkung du sofort sehen kannst. Dazu legst du ein kleines Skript an, das einfach nur eine Zeile mit Zeitstempel in eine Datei schreibt.
mkdir -p ~/cron-test
nano ~/cron-test/testjob.sh
Inhalt des Skripts:
#!/bin/bash
echo "Cron lief: $(date '+%F %T')" >> /tmp/cron-test.log
Danach machst du das Skript ausführbar:
chmod 700 ~/cron-test/testjob.sh
Verifizieren: Prüfe mit
ls -l ~/cron-test/testjob.sh
Erwartung: Die Datei ist vorhanden und der Besitzer hat ein Execute-Bit. Wenn dort kein x steht, kann Cron das Skript später nicht ausführen.
Schritt 2: Die fünf Zeitfelder verstehen
Ein klassischer Cron-Eintrag besteht aus fünf Zeitfeldern und danach dem eigentlichen Befehl:
Minute Stunde Tag Monat Wochentag Befehl
* * * * * /pfad/zum/befehl
Die Bedeutung der Felder:
| Feld | Werte | Bedeutung |
|---|---|---|
| Minute | 0-59 | Minute innerhalb der Stunde |
| Stunde | 0-23 | Stunde des Tages |
| Tag | 1-31 | Kalendertag des Monats |
| Monat | 1-12 | Monat des Jahres |
| Wochentag | 0-7 | 0 oder 7 = Sonntag, 1 = Montag bis 6 = Samstag |
Ein Sternchen bedeutet: jeder mögliche Wert. Beispiele:
# Täglich um 02:30 Uhr
30 2 * * * /usr/local/bin/backup.sh
# Jeden Montag um 08:00 Uhr
0 8 * * 1 /home/user/wochenbericht.sh
# Am 1. jedes Monats um Mitternacht
0 0 1 * * /usr/local/bin/monatsjob.sh
Verifizieren: Du hast diesen Schritt verstanden, wenn du an 30 2 * * * sagen kannst: Minute 30, Stunde 2, jeden Tag, jeden Monat, an jedem Wochentag.
Schritt 3: Die eigene Crontab mit crontab -e bearbeiten
Deine persönliche Crontab bearbeitest du nicht direkt in irgendeiner Datei, sondern immer über crontab -e.
crontab -e
Füge dort für den ersten Testjob diese Zeile ein:
*/2 * * * * /bin/bash /home/DEIN-USER/cron-test/testjob.sh
Ersetze DEIN-USER durch deinen tatsächlichen Benutzernamen. Der Job läuft dann alle zwei Minuten.
Wichtig:
- Nutze möglichst absolute Pfade
- Verlasse dich nicht darauf, dass Cron deinen gewohnten Shell-Kontext kennt
- Bearbeite nicht direkt Dateien unter
/var/spool/cron/oder ähnlichen Pfaden
Danach kannst du dir die gespeicherte Crontab ansehen:
crontab -l
Verifizieren: Der Schritt ist erfolgreich, wenn dein Eintrag in der Ausgabe von crontab -l sichtbar ist. Wenn dort nichts steht, wurde die Crontab nicht gespeichert.
Schritt 4: Erste Muster mit Listen, Bereichen und Schrittweiten lesen
Cron kann mehr als nur feste Uhrzeiten. Drei Muster brauchst du besonders oft:
- Schrittweite wie
*/5= alle 5 Einheiten - Bereich wie
1-5= von 1 bis 5 - Liste wie
0,15,30,45= genau diese Werte
# Alle 5 Minuten
*/5 * * * * /usr/bin/python3 /home/user/check.py
# Um 00, 15, 30 und 45 Minuten jeder Stunde
0,15,30,45 * * * * /usr/local/bin/ping_check.sh
# Montag bis Freitag alle 3 Stunden
0 */3 * * 1-5 /opt/cleanup.sh
# Nur in den ersten 30 Minuten jeder Stunde, alle 5 Minuten
0-30/5 * * * * /usr/local/bin/kurzcheck.sh
Verifizieren: Du hast den Schritt verstanden, wenn du */5 * * * * als älle fünf Minuten? lesen kannst und 1-5 beim Wochentag als Montag bis Freitag erkennst.
Schritt 5: Sonderstrings wie @reboot und @daily einordnen
Für viele Standardsituationen musst du die fünf Felder nicht komplett ausschreiben. Cron kennt dafür praktische Sonderstrings:
| Sonderstring | Bedeutung |
|---|---|
@reboot | Einmal nach dem Systemstart |
@hourly | Jede Stunde |
@daily | Täglich |
@weekly | Wöchentlich |
@monthly | Monatlich |
@yearly | Jährlich |
@reboot /usr/local/bin/startvpn.sh
@daily /usr/local/bin/cleanup.sh >> /var/log/cleanup.log 2>&1
Verifizieren: Du solltest @reboot klar von einem echten Zeitplan unterscheiden können: Der Job läuft nicht zu einer Uhrzeit, sondern beim Booten.
Schritt 6: System-Crontab und /etc/cron.d/ verstehen
Neben deiner persönlichen Crontab gibt es auch systemweite Varianten. Der entscheidende Unterschied: Dort gibt es ein zusätzliches Feld für den Benutzernamen.
Minute Stunde Tag Monat Wochentag USERNAME Befehl
Beispiele:
# Systemweiter Backup-Job als root
0 2 * * * root /usr/local/bin/backup.sh
# Cleanup werktags alle 3 Stunden als postgres
0 */3 * * 1-5 postgres /opt/cleanup.sh >> /var/log/pg.log 2>&1
Für eigene systemweite Jobs ist /etc/cron.d/ meist die bessere Wahl als das direkte Bearbeiten von /etc/crontab.
ls -la /etc/cron.d/
sudo cat /etc/crontab
Außerdem gibt es die Verzeichnisse /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly und /etc/cron.monthly. Dort liegen ausführbare Skripte, die automatisch von run-parts aufgerufen werden.
Verifizieren: Du hast diesen Schritt verstanden, wenn du den Unterschied benennen kannst: In der Benutzer-Crontab steht direkt der Befehl, in /etc/cron.d/ steht zusätzlich noch, unter welchem Benutzer er laufen soll.
Schritt 7: PATH, SHELL und Umgebung richtig einordnen
Die häufigste Fehlerquelle bei Cron ist nicht die Zeitangabe, sondern die Umgebung. Cron startet Jobs mit deutlich weniger Kontext als deine normale Shell.
- PATH ist oft minimal
- SHELL ist häufig
/bin/shund nicht Bash - HOME und andere Variablen können anders wirken als erwartet
- Deine
.bashrcoder.profilewird nicht automatisch geladen
Darum sind absolute Pfade oft die sicherste Wahl. Zusätzlich kannst du Variablen am Anfang der Crontab setzen:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
MAILTO=''
*/5 * * * * /usr/bin/python3 /home/user/job.py >> /var/log/job.log 2>&1
Verifizieren: Wenn ein Befehl interaktiv funktioniert, aber unter Cron nicht, ist das ein starker Hinweis auf PATH oder SHELL. Genau dann prüfst du zuerst, ob du absolute Pfade verwendest.
Schritt 8: Logging, MAILTO und Fehlerprüfung nutzen
Damit du nicht rätseln musst, ob dein Job überhaupt gelaufen ist, brauchst du sauberes Logging. Für den Einstieg ist eine Logdatei meist am einfachsten.
*/5 * * * * /usr/local/bin/check.sh >> /var/log/check.log 2>&1
2>&1 sorgt dafür, dass auch Fehlermeldungen in derselben Datei landen. Alternativ kannst du Cron-Mails deaktivieren:
MAILTO=''
Oder die Ausgabe gezielt an Syslog schicken:
*/5 * * * * /usr/local/bin/check.sh | /usr/bin/logger -t CRONJOB
Zum Prüfen eignen sich je nach Distribution zum Beispiel:
# Debian / Ubuntu
grep CRON /var/log/syslog
# RHEL / CentOS / Rocky
grep CRON /var/log/cron
# systemd-basierte Logs
sudo journalctl -u cron
sudo journalctl -u crond
Für unseren Testjob aus Schritt 1 kannst du direkt prüfen, ob Cron geschrieben hat:
cat /tmp/cron-test.log
Verifizieren: Der Schritt ist erfolgreich, wenn in /tmp/cron-test.log nach ein paar Minuten neue Zeilen mit Zeitstempel auftauchen. Wenn die Datei leer bleibt oder gar nicht entsteht, lief der Job nicht sauber durch.
Schritt 9: Was sich mit systemd-Timern anders löst
Auf modernen Linux-Systemen sind systemd-Timer oft eine Alternative zu Cron. Sie passen besonders dann gut, wenn du ohnehin schon mit systemd-Services arbeitest und einheitliche Logs im Journal willst.
Für diese Grundlagen-Anleitung bleibt Cron aber der einfachere Ausgangspunkt. Wenn du später mehr Kontrolle, saubere Integration in systemd und bessere Nachvollziehbarkeit brauchst, lohnt sich der Blick auf Timer.
Verifizieren: Du musst hier noch nichts umstellen. Wichtig ist nur das Verständnis: Cron ist nicht die einzige Möglichkeit für geplante Jobs, aber oft die schnellste für einfache Aufgaben.
Troubleshooting
- Job läuft nicht: Mit
crontab -lprüfen, ob der Eintrag gespeichert ist. - Befehl funktioniert im Terminal, aber nicht in Cron: Fast immer PATH, SHELL oder fehlende absolute Pfade prüfen.
- Skript wird nicht ausgeführt: Prüfen, ob es ausführbar ist und ob der Shebang passt.
- Keine Logs sichtbar: Ausgabe bewusst in eine Logdatei oder an Syslog leiten.
- Job in /etc/cron.d/ läuft nicht: Prüfen, ob das Benutzerfeld vorhanden ist.
- Skript in /etc/cron.daily wird ignoriert: Oft ist die Datei nicht ausführbar oder hat eine unerwünschte Dateiendung.
Häufige Fragen
Was ist der Unterschied zwischen Cron und crontab?
Cron ist der Dienst, der Jobs ausführt. crontab ist das Werkzeug, mit dem du deine Jobliste bearbeitest.
Warum sollte ich meine Crontab nicht direkt in Spool-Dateien bearbeiten?
Weil crontab -e der saubere und unterstützte Weg ist. Direkte Änderungen an internen Dateien sind fehleranfälliger.
Warum funktioniert ein Job manuell, aber nicht automatisch?
Weil Cron in einer anderen Umgebung läuft. Meist fehlen absolute Pfade oder es wird die falsche Shell vorausgesetzt.
Wann nutze ich /etc/cron.d statt crontab -e?
Wenn ein Job systemweit laufen oder unter einem bestimmten Benutzer ausgeführt werden soll und du ihn zentral verwalten willst.
Warum ist Logging bei Cron so wichtig?
Weil ein Cronjob oft ohne sichtbares Fenster läuft. Ohne Logdatei oder Journal-Eintrag merkst du sonst kaum, ob er erfolgreich war.
Wann ist ein systemd-Timer sinnvoller?
Wenn du ohnehin mit systemd arbeitest und die geplante Aufgabe besser in diese Struktur integrieren willst.
Fazit
Der sichere Weg in Cron ist immer gleich: erst einen kleinen Testjob anlegen, dann die Crontab sauber speichern, danach Logging einbauen und zum Schluss prüfen, ob die Ausgabe wirklich ankommt. Genau diese Reihenfolge spart viel Zeit, weil du Fehler nicht erst suchst, wenn ein wichtiges produktives Skript längst nicht gelaufen ist.
Als nächster passender Baustein eignet sich unsere Anleitung zu systemd-Services, weil du dort den anderen großen Linux-Weg für Automatisierung kennenlernst. Für Rechte- und Benutzerfragen rund um Skripte, Logdateien und Verzeichnisse passt außerdem Linux-Benutzer, Gruppen und Rechte verstehen.
Weiterführende Anleitungen und Quellen
- systemd-Service erstellen und verwalten
- Linux-Benutzer, Gruppen und Rechte verstehen
- SSH-Key-Authentifizierung einrichten ? Linux und Windows
- Alle Linux-Anleitungen auf s-edv.com
Quellen: crontab(5) ? man7.org, cron(8) ? man7.org, crond(8) ? man7.org, run-parts(8) ? man7.org.