Cronjob unter Linux einrichten: crontab Schritt für Schritt

Entwickler-Arbeitsplatz bei Nacht mit Tastatur und Monitor, auf dem ein unscharfes Linux-Terminal leuchtet

Einen Cronjob unter Linux einrichten heißt: Du rufst den Befehl crontab -e auf, und der Zeitplan-Dienst cron (auf Debian/Ubuntu das Paket cron, auf Fedora/RHEL cronie) übernimmt die Ausführung. Der Befehl öffnet die persönliche Zeitplan-Tabelle deines Benutzers in einem Editor. Dort schreibst du pro Aufgabe eine Zeile aus fünf Zeitfeldern plus Befehl, zum Beispiel 0 3 * * * /usr/bin/backup.sh für einen täglichen Lauf um 3 Uhr. Speichern genügt – der cron-Dienst übernimmt den Rest automatisch.

Was ist cron – und wann brauchst du es?

cron ist ein Daemon, also ein Hintergrunddienst, der auf praktisch jedem Linux-System mitläuft. Laut Debian-Handbuchseite cron(8) wacht er jede Minute auf, prüft alle hinterlegten Crontabs und liest geänderte Dateien selbstständig neu ein – ein Neustart des Dienstes nach dem Bearbeiten ist nicht nötig. Ist eine Aufgabe fällig, startet er sie ohne dein Zutun. Die Liste dieser Aufgaben heißt Crontab (von „cron table“). Typische Einsätze: nächtliche Backups, das Aufräumen von Log-Dateien, das regelmäßige Abrufen von Mails oder das Ausführen eines Wartungsskripts.

Du brauchst dafür einen Shell-Zugang und – für systemweite Jobs – Root-Rechte. Ob der Dienst läuft, prüfst du mit systemctl status cron (Debian/Ubuntu) beziehungsweise systemctl status crond (Fedora/RHEL). Fehlt cron ganz, installierst du es unter Debian/Ubuntu mit sudo apt install cron.

Cronjob unter Linux einrichten in vier Schritten

  1. Crontab öffnen: crontab -e eingeben. Beim ersten Aufruf fragt Linux nach einem Editor – nano ist für Einsteiger die einfachste Wahl.
  2. Job-Zeile schreiben: Unter die Kommentarzeilen kommt deine Aufgabe, aufgebaut aus fünf Zeitfeldern und dem auszuführenden Befehl (Aufbau siehe nächster Abschnitt).
  3. Speichern und schließen: In nano mit Strg+O speichern, Enter bestätigen, mit Strg+X verlassen. cron meldet „installing new crontab“ und der Job ist aktiv. Hast du einen Syntaxfehler eingebaut, lehnt crontab die Datei ab und bietet an, sie erneut zu bearbeiten.
  4. Kontrollieren: Mit crontab -l lässt du dir alle Einträge deines Benutzers anzeigen und prüfst, ob die Zeile korrekt gespeichert wurde.

Wichtig: crontab -r löscht die komplette Crontab sofort und ohne Rückfrage. Nutze stattdessen crontab -e und entferne nur die betreffende Zeile, wenn du einen einzelnen Job loswerden willst. Die Option -i ergänzt -r um eine Sicherheitsabfrage, so beschreibt es die Handbuchseite crontab(1). Eine schnelle Sicherung vor größeren Umbauten: crontab -l > ~/crontab-backup.txt, zurückspielen mit crontab ~/crontab-backup.txt.

Welcher Editor startet, steuern die Umgebungsvariablen VISUAL und EDITOR. Wer die Auswahl beim ersten Aufruf verklickt hat, setzt ihn einmalig mit EDITOR=nano crontab -e. Die Crontab selbst liegt unter /var/spool/cron/ – die Dateien dort nicht direkt bearbeiten, sondern immer über crontab, sonst fehlt die Syntaxprüfung.

Die crontab-Syntax verstehen

Jede Job-Zeile besteht aus fünf durch Leerzeichen getrennten Zeitfeldern und dem Befehl:

* * * * * /pfad/zum/befehl
| | | | |
| | | | +-- Wochentag (0-7, 0 und 7 = Sonntag)
| | | +---- Monat (1-12)
| | +------ Tag des Monats (1-31)
| +-------- Stunde (0-23)
+---------- Minute (0-59)

Vier Sonderzeichen steuern die Wiederholung:

ZeichenBedeutungBeispiel
*jeder Wert des Feldes* * * * * = jede Minute
,mehrere feste Werte0 8,20 * * * = 8 und 20 Uhr
-Bereich0 9 * * 1-5 = werktags 9 Uhr
/Intervall (Schrittweite)*/15 * * * * = alle 15 Minuten

Statt Zahlen akzeptiert cron in den Feldern Monat und Wochentag auch die ersten drei Buchstaben der englischen Namen, etwa mon-fri oder jan,jul; Groß- und Kleinschreibung spielt keine Rolle.

Eine Regel überrascht fast jeden: Sind Tag des Monats und Wochentag beide eingeschränkt (keines der beiden steht auf *), läuft der Job, sobald eines der Felder passt – nicht erst, wenn beide zutreffen. So dokumentiert es die Handbuchseite crontab(5). 0 8 13 * 5 startet deshalb nicht nur an einem Freitag, dem 13., sondern an jedem 13. und an jedem Freitag. Wer die Kombination braucht, lässt den Wochentag auf * und prüft ihn im Befehl: 0 8 13 * * [ "$(date +\%u)" = 5 ] && /usr/local/bin/job.sh.

Für gängige Rhythmen gibt es zusätzlich Kürzel, die die fünf Felder ersetzen: @hourly, @daily, @weekly, @monthly und @reboot. Letzteres startet den Befehl einmal nach jedem Systemstart – praktisch, um einen Dienst automatisch hochzufahren.

Praxis-Beispiele zum Übernehmen

  • 30 2 * * * /usr/bin/backup.sh – jede Nacht um 2:30 Uhr das Backup-Skript ausführen.
  • */10 * * * * /home/marcel/check.sh – alle zehn Minuten eine Prüfung laufen lassen.
  • 0 0 1 * * /usr/local/bin/report.sh – am 1. jedes Monats um Mitternacht einen Bericht erzeugen.
  • 0 9 * * 1 /usr/bin/apt update – jeden Montag um 9 Uhr die Paketliste aktualisieren.
  • @reboot /home/marcel/start-dienst.sh – den Dienst nach jedem Neustart automatisch starten.

Wer sich beim Rhythmus unsicher ist, testet den Ausdruck vorab auf einem Cron-Rechner wie crontab.guru, bevor der Job scharf geschaltet wird.

Wenn der Cronjob nicht läuft

Das mit Abstand häufigste Problem: Der Job funktioniert im Terminal, aber nicht unter cron. Der Grund ist fast immer die abgespeckte Umgebung, in der cron startet. Diese drei Ursachen decken die meisten Fälle ab:

  • Fehlende absolute Pfade. cron kennt nur ein minimales PATH. Ein Skript findet dann Befehle wie python3 oder rsync nicht. Lösung: In der Job-Zeile und im Skript vollständige Pfade angeben (/usr/bin/python3) oder oben in der Crontab PATH=/usr/local/bin:/usr/bin:/bin setzen.
  • Skript nicht ausführbar oder ohne Shebang. Setze das Ausführungs-Recht mit chmod +x skript.sh und beginne das Skript mit einer Shebang-Zeile wie #!/bin/bash, damit cron weiß, womit es die Datei starten soll.
  • Keine Ausgabe sichtbar. cron schickt Ausgaben standardmäßig als lokale Mail, die du meist nie siehst. Leite Ausgabe und Fehler in eine Log-Datei um: /pfad/befehl >> /var/log/meinjob.log 2>&1. Der Anhang 2>&1 erfasst dabei auch Fehlermeldungen.

Weitere Stolperfallen, die im Terminal nie auffallen:

  • Prozentzeichen im Befehl. cron wandelt ein unmaskiertes % in einen Zeilenumbruch um und reicht alles dahinter als Standardeingabe weiter. Der typische Fall ist ein Dateiname mit Datum: tar czf /backup/home-$(date +\%F).tar.gz /home funktioniert, ohne den Backslash bricht die Zeile mitten im Befehl ab.
  • Bash-Syntax in der Job-Zeile. cron setzt SHELL standardmäßig auf /bin/sh, auf Debian und Ubuntu ist das dash. Konstrukte wie [[ … ]] oder source scheitern dort. Entweder SHELL=/bin/bash oben in die Crontab schreiben oder die Logik in ein Skript mit Bash-Shebang auslagern.
  • Letzte Zeile ohne Zeilenumbruch. cron verlangt, dass jeder Eintrag mit einem Newline-Zeichen endet. Fehlt es in der letzten Zeile, wird dieser Eintrag je nach cron-Variante ignoriert oder beim Speichern abgelehnt – nach dem letzten Befehl deshalb einmal Enter drücken.
  • Überlappende Läufe. Dauert ein Job länger als sein Intervall, startet cron die nächste Instanz trotzdem. Bei Backups oder Synchronisationen verhindert flock aus util-linux das: */5 * * * * /usr/bin/flock -n /tmp/sync.lock /usr/local/bin/sync.sh. Mit -n bricht der zweite Aufruf sofort ab, statt zu warten (Handbuchseite flock(1)).
  • Zugriff verweigert. Meldet crontab -e, du dürftest cron nicht nutzen, greift /etc/cron.allow oder /etc/cron.deny. Existiert cron.allow, dürfen nur die dort eingetragenen Benutzer Crontabs anlegen. Diese Dateien regeln nur den Befehl crontab, nicht die Ausführung bereits vorhandener Jobs.

Die Mails, die cron bei jeder Ausgabe verschickt, lassen sich mit MAILTO="" in der ersten Zeile abschalten oder mit [email protected] umleiten – sinnvoll allerdings nur, wenn auf dem System ein Mailserver eingerichtet ist. Und ob cron den Job überhaupt gestartet hat, verrät das System-Log (cron protokolliert über die Syslog-Facility cron) – unter Debian/Ubuntu mit grep CRON /var/log/syslog, auf systemd-Systemen mit journalctl -u cron.

Benutzer-Crontab, /etc/crontab und cron.d

Es gibt nicht die eine Crontab. Wer zum ersten Mal einen Cronjob unter Linux einrichten will, ist mit der persönlichen Benutzer-Crontab über crontab -e richtig aufgehoben – sie gilt nur für den eigenen Account und braucht keine Root-Rechte. Daneben existieren systemweite Varianten:

  • /etc/crontab und /etc/cron.d/: systemweite Jobs. Diese Zeilen haben ein zusätzliches sechstes Feld vor dem Befehl – den Benutzer, unter dem der Job laufen soll.
  • /etc/cron.daily/, cron.hourly/, cron.weekly/: Verzeichnisse für Skripte, die automatisch im genannten Takt laufen. Skript hineinlegen, ausführbar machen, fertig – ohne eigene Zeitfelder.

Beide Systemwege haben Regeln, an denen selbst Erfahrene hängen bleiben. Dateien in /etc/cron.d/ und /etc/crontab müssen root gehören und dürfen weder für die Gruppe noch für andere beschreibbar sein, sonst ignoriert cron sie. Außerdem darf der Dateiname unter Debian nur Buchstaben, Ziffern, Unterstriche und Bindestriche enthalten – keinen Punkt. Eine Datei /etc/cron.d/backup.cron wird nie ausgeführt, /etc/cron.d/backup schon. Dieselbe Namensregel gilt für Skripte in /etc/cron.daily/, weil diese über run-parts gestartet werden: aufraeumen.sh bleibt liegen, aufraeumen läuft (Handbuchseite run-parts(8)). Ob ein Skript erfasst wird, verrät run-parts --test /etc/cron.daily, ohne es auszuführen.

Ist zusätzlich anacron installiert, wie auf vielen Desktop-Systemen, übernimmt dieses laut Debian-Handbuch die Verzeichnisse cron.daily, cron.weekly und cron.monthly. Der Vorteil: Anacron holt die Läufe nach, wenn der Rechner zur geplanten Zeit ausgeschaltet war. Stündliche Skripte bleiben bei cron.

Die Zeitumstellung behandelt Debians cron ebenfalls gesondert: Wird die Uhr um weniger als drei Stunden zurückgestellt, laufen Jobs in der doppelten Stunde nicht zweimal; beim Vorstellen werden übersprungene Jobs kurz danach nachgeholt. Wer auf einem Server mit UTC-Uhrzeit trotzdem nach deutscher Zeit planen will: cronie (Fedora/RHEL) kennt dafür laut crontab(5) die Variable CRON_TZ.

Ein fremder Benutzer lässt sich als Root mit sudo crontab -u name -e bearbeiten – nützlich auf Servern mit mehreren Konten.

Hintergrund: cron oder systemd-Timer?

Auf modernen Distributionen gibt es mit systemd-Timern eine Alternative zu cron. Sie brauchen zwar zwei Dateien pro Aufgabe (eine .service– und eine .timer-Datei), bieten dafür aber an, verpasste Läufe per Persistent=true nachzuholen, und ein sauberes Log über journalctl. Beides ist kein Automatismus: Laut Handbuchseite systemd.timer(5) steht Persistent= standardmäßig auf false, und AccuracySec= erlaubt ohne eigene Angabe eine Abweichung von einer Minute. Welche Timer aktiv sind und wann sie zuletzt liefen, zeigt systemctl list-timers. cron überspringt verpasste Termine dagegen stillschweigend und protokolliert nur mager.

Die Faustregel: Für einfache, wiederkehrende Aufgaben ist cron schneller eingerichtet und überall verfügbar – auch außerhalb der systemd-Welt. Für kritische Abläufe wie Backups oder Deployments, bei denen dir Nachvollziehbarkeit und Nachhol-Verhalten wichtig sind, lohnt der Umstieg auf systemd-Timer. Für den Einstieg und die meisten Heimserver-Aufgaben reicht cron vollkommen.

Quellen

Häufige Fragen

Wie öffne ich die Crontab unter Linux?

Mit dem Befehl crontab -e öffnest du die persönliche Crontab deines Benutzers im Editor. Beim ersten Aufruf wählst du einen Editor – nano ist für Einsteiger am einfachsten. Nach dem Speichern ist der Job sofort aktiv.

Warum läuft mein Cronjob nicht, obwohl er im Terminal funktioniert?

Fast immer liegt es an der minimalen Umgebung von cron: Das PATH ist kürzer als in deiner Shell. Nutze in Skripten absolute Pfade wie /usr/bin/python3, mache das Skript mit chmod +x ausführbar und leite die Ausgabe mit >> logdatei 2>&1 um.

Was bedeuten die fünf Sternchen in einer Cron-Zeile?

Die fünf Felder stehen für Minute (0-59), Stunde (0-23), Tag des Monats (1-31), Monat (1-12) und Wochentag (0-7). Ein Stern bedeutet jeden Wert. So steht 0 3 * * * für täglich um 3 Uhr.

Wie zeige ich meine bestehenden Cronjobs an?

Mit crontab -l listest du alle Einträge deines Benutzers auf. Vorsicht bei crontab -r: Das löscht die gesamte Crontab ohne Rückfrage. Zum Entfernen einzelner Jobs stattdessen crontab -e nutzen und nur die Zeile löschen.

Soll ich cron oder systemd-Timer verwenden?

Für einfache, wiederkehrende Aufgaben ist cron schneller eingerichtet und überall verfügbar. Für kritische Abläufe wie Backups bieten systemd-Timer besseres Logging über journalctl und holen verpasste Läufe mit Persistent=true nach.

Marcel Meyer

# wer schreibt hier

Marcel Meyer schraubt seit über zehn Jahren an Rechnern, Netzwerken und Servern — beruflich wie privat. Hier übersetzt er IT-Grundlagen in verständliche Schritte.

→ Mehr über mich