Cronjob

Cronjob

Inhaltsverzeichnis

Der Hausmeister, den Sie nie sehen

02:30 Uhr. Sie schlafen.

Irgendwo in Ihrem Server geschieht das Folgende: Eine Datenbank wird gesichert, Logs werden rotiert, ein Bericht landet im Postfach Ihres Geschäftsführers. Niemand hat einen Knopf gedrückt. Niemand sitzt davor. Trotzdem läuft alles.

Verantwortlich dafür: ein Cronjob. Ein zeitgesteuerter Hintergrundauftrag, der zur festgelegten Minute ausgeführt wird, ohne dass jemand zuschaut.

 

Illustration einer Crontab mit Zeitangabe 30 2 * * *, Uhr, Server, Laptop und nächtlichem Backup als Cronjob.

Ein Cronjob startet zeitgesteuerte Serveraufgaben wie Backups automatisch zur festgelegten Uhrzeit im Hintergrund.

 

Definition

Ein Cronjob ist ein zeitgesteuerter Hintergrundauftrag auf Unix- und Linux-Systemen. Der cron-Daemon liest dafür sogenannte Crontab-Dateien und führt die darin definierten Befehle automatisch aus, wenn ihre Zeit gekommen ist.

Jede Benutzerin und jeder Benutzer kann eigene Cronjobs anlegen. Daneben existieren Systemjobs auf Ebene der Dateien /etc/crontab, /etc/cron.d/* sowie der periodischen Verzeichnisse wie /etc/cron.daily.

Klingt simpel. Ist es auch. Bis Sie die erste Sommerzeitumstellung erleben.

 

Architektur: zwei Teile, ein Auftrag

Ein Cronjob lebt von zwei Komponenten:

  1. Der Daemon cron (oft crond): Ein Hintergrundprozess, der im Minutentakt prüft, welcher Job jetzt fällig ist, und ihn dann startet. Standardmäßig läuft die Befehlszeile unter /bin/sh. Wer Bash-Syntax braucht, setzt in der Crontab SHELL=/bin/bash.
  2. Die Crontab: Eine Textdatei mit Zeitmustern und Befehlen. Benutzer-Crontabs verwalten Sie mit crontab -e. System-Crontabs liegen unter /etc/crontab und in /etc/cron.d/. Letztere haben ein zusätzliches Feld: den Benutzernamen, unter dem der Job läuft.

Viele Distributionen liefern zusätzlich vier periodische Verzeichnisse: /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly. Wer ein ausführbares Skript hineinlegt, muss sich um die Zeitsteuerung nicht mehr kümmern. Der Aufruf erfolgt über run-parts, ausgelöst durch einen passenden Eintrag in /etc/crontab, durch Anacron oder durch systemd.

 

Die Crontab-Syntax: fünf Felder, eine kleine Welt

Die fünf Felder

Eine klassische Cronzeile besteht aus fünf Zeitfeldern und der auszuführenden Befehlszeile:

# m h dom mon dow command
5 2 * * * /usr/local/bin/backup.sh
  • m: Minute (0 bis 59)
  • h: Stunde (0 bis 23)
  • dom: Tag im Monat (1 bis 31)
  • mon: Monat (1 bis 12 oder Namen wie jan, feb)
  • dow: Wochentag (0 bis 7, wobei 0 und 7 beide für Sonntag stehen)

Erlaubt sind: * (beliebig), Bereiche wie 8-11, Listen wie 1,2,5,9, Schrittweiten wie */5 oder 0-23/2 sowie Namen wie mon,wed,fri.

Die Stolperfalle: OR-Logik bei Tag und Wochentag

Hier irren sich erfahrene Admins regelmäßig: Wenn beide Felder dom und dow eingeschränkt sind, also kein * enthalten, genügt es, wenn eines von beiden passt.

30 4 1,15 * 5 # 4:30 Uhr am 1. und 15. des Monats UND zusätzlich jeden Freitag

Wer „am 1. und 15., aber nur wenn das ein Freitag ist“ ausdrücken will, kommt mit Cron-Syntax allein nicht hin. Das ist keine Schwäche, das ist POSIX.

Was noch zu wissen ist

  • Das Prozentzeichen % in der Befehlszeile ist tückisch. Alles nach dem ersten unescapeden % wandert in den STDIN des Programms, nicht in die Argumente. Mit \% entschärfen.
  • Schrittweiten gelten nur innerhalb des jeweiligen Felds. */23 im Stundenfeld bedeutet: 00:00 und 23:00. Nicht: alle 23 Stunden.
  • Namen statt Zahlen erhöhen die Lesbarkeit: mon-fri ist schneller verstanden als 1-5.

Die Kurzform: Nicknames

Statt fünf Felder geht auch die sprechende Variante:

  • @reboot (einmalig nach jedem Systemstart)
  • @hourly, @daily, @weekly, @monthly, @yearly bzw. @annually

@daily ist nichts anderes als 0 0 * * *. Nur eben lesbarer.

System-Crontab und /etc/cron.d

In System-Crontabs kommt ein sechstes Feld hinzu: der Benutzername. So weiß cron, unter welchem Konto der Job laufen soll.

# m h dom mon dow user command
1 5 * * * root run-parts /etc/cron.daily

 

Umgebung, E-Mail, Zeitzonen

Die karge Umgebung von cron

Was Admins immer wieder zum Verzweifeln bringt: Die interaktive Shell-Umgebung existiert in cron nicht. Cron setzt SHELL=/bin/sh, HOME und LOGNAME. Ihr persönliches PATH, Ihre Aliases, Ihre Profilskripte: alle weg.

Konsequenz: Volle Pfade in jedem Befehl. Und wenn Sie unsicher sind, was cron sieht, dumpen Sie es:

* * * * * env > ~/cronenv

Einmal warten, einmal nachlesen, das Mysterium ist gelöst.

MAILTO: Cron will Ihnen etwas sagen

Wenn ein Job auf STDOUT oder STDERR etwas ausgibt, schickt cron diese Ausgabe per E-Mail an den Crontab-Besitzer. Mit MAILTO=admin@example.com steuern Sie um, mit MAILTO="" ist Ruhe. Auch MAILFROM, CONTENT_TYPE und CONTENT_TRANSFER_ENCODING sind in vielen Implementierungen verfügbar.

Wichtige Konsequenz: Ein stummer Job ist nicht zwingend ein erfolgreicher Job. Er ist nur einer, der nichts gesagt hat.

Zeitzonen mit CRON_TZ

Einige Implementierungen, etwa Cronie, kennen CRON_TZ=Europe/Berlin. Damit werden die Zeitangaben in der Crontab in dieser Zone interpretiert. Hilfreich, wenn Sie Server weltweit betreiben und die Wartung nicht mitten in der lokalen Nacht stattfinden soll.

Aber: Nicht jedes System versteht CRON_TZ. Das Setzen von TZ in der Crontab beeinflusst oft nur die Umgebung des laufenden Prozesses, nicht die Terminierung selbst. Manpage lesen. Immer.

 

Sommerzeit: zwei Stunden, die niemand mag

Zweimal im Jahr passiert dem Cron-Daemon etwas, das ihn aus dem Takt bringt:

  • Im März verschwindet eine Stunde. Ein Job, der auf 02:30 Uhr geplant ist, läuft schlicht nicht.
  • Im Oktober gibt es eine Stunde zweimal. Derselbe Job kann doppelt ausgeführt werden.

Was bedeutet das in der Praxis? Wenn Ihr Job idempotent ist, also folgenlos wiederholbar, kein Drama. Wenn er Mails versendet, Geld bewegt oder Datenbanken migriert, kann eine Doppelausführung teuer werden.

Lösung: Lockfiles. Idempotenz. Oder Jobs außerhalb der kritischen Stunden 02:00 bis 03:00 planen.

Die wahre Vorsicht ist nicht Vermeidung. Sie ist Vorbereitung.

 

Crontab verwalten

  • Bearbeiten: crontab -e öffnet die Crontab im Editor aus $EDITOR oder $VISUAL.
  • Anzeigen: crontab -l
  • Löschen: crontab -r, mit -i sicherheitshalber mit Nachfrage.

Niemals die Spool-Dateien (etwa unter /var/spool/cron/) direkt bearbeiten. Cron erwartet definierte Übergabewege. Wer manuell schreibt, riskiert, dass Änderungen nicht erkannt werden oder Berechtigungen brechen.

Zugriffskontrolle

Über /etc/cron.allow (Whitelist) und /etc/cron.deny (Blacklist) bestimmen Sie, wer cron überhaupt nutzen darf. Existiert cron.allow, hat sie Vorrang. Root ist immer berechtigt.

 

Periodisches mit run-parts

Die periodischen Verzeichnisse cron.hourly, cron.daily, cron.weekly, cron.monthly werden meist über run-parts abgearbeitet. Das Werkzeug führt der Reihe nach alle ausführbaren Dateien im Verzeichnis aus.

Achtung: Manche Implementierungen ignorieren Dateien mit Endung (also backup.sh statt backup). Wer es genau wissen will, testet vorher:

run-parts --test /etc/cron.daily

 

Anacron: für Maschinen, die nicht durchlaufen

Ein Cronjob, der nachts um 03:00 Uhr feuern soll, läuft nur dann, wenn der Rechner zu dieser Zeit eingeschaltet ist. Bei Servern selbstverständlich, bei Laptops nicht.

Hier kommt Anacron ins Spiel: Es prüft beim Start, welche periodischen Jobs in der Zwischenzeit fällig gewesen wären, und holt sie nach. Konfiguriert wird das in /etc/anacrontab:

  • START_HOURS_RANGE: das Zeitfenster, in dem Anacron arbeiten darf (etwa 6-8).
  • RANDOM_DELAY: eine Zufallsverzögerung in Minuten, damit nicht alle Maschinen einer Flotte gleichzeitig loslegen.
  • Jobs werden seriell abgearbeitet, einer nach dem anderen.

Auf modernen Systemen ist Anacron oft an systemd gekoppelt. Das exakte Nachhol-Verhalten weicht dann leicht ab. Im Zweifel: Manpage Ihrer Distribution konsultieren.

 

systemd-Timer: die moderne Alternative

Wer auf einem aktuellen Linux-System neue Automatisierung baut, hat eine zweite Option: systemd-Timer. Ein .timer löst einen .service aus. Das klingt sperriger, hat aber Vorteile:

  • Logging direkt im Journald, kein Bastelei mit Umleitungen.
  • Abhängigkeiten: Timer können auf andere Units warten.
  • Präzise Calendar-Ausdrücke wie OnCalendar=Mon..Fri 08:00 oder sogar mehrere Termine pro Timer.
  • Persistenz: Ähnlich wie Anacron, aber sauberer integriert.

Die Syntax ist eine andere Welt. Nachzulesen in systemd.timer(5) und systemd.time(7).

Cron wird deshalb nicht sterben. Aber für neue Projekte lohnt der Blick.

 

Welche Implementierung läuft eigentlich?

  • Cronie ist auf vielen Linux-Distributionen Standard. Eine Weiterentwicklung von Vixie-Cron mit PAM, SELinux, CRON_TZ, RANDOM_DELAY und mehr. Details im Cronie-Projekt auf GitHub.
  • Vixie-Cron ist die historische Basis. Debian pflegt eine eigene Variante mit Distribution-spezifischen Erweiterungen wie /etc/cron.d.

Was Cron nicht ist

Zwei Dinge tauchen unter dem Label „Cron“ auf, sind es aber nicht:

  • Jenkins verwendet eine cron-ähnliche Syntax, ergänzt sie aber um den H-Operator. H streut Jobs hashbasiert, um Lastspitzen zu vermeiden. Praktisch, aber nicht POSIX.
  • Quartz aus der Java-Welt hat eine Sekunden-Spalte (also sechs bis sieben Felder) und Spezialzeichen wie ?, L, W, #.

Merksatz: Ein Ausdruck aus Jenkins oder Quartz lässt sich nicht eins zu eins in die System-Crontab kopieren. Wer das versucht, bekommt entweder einen Fehler oder, schlimmer, einen Job zur falschen Zeit.

 

Praxisbeispiele zum Mitnehmen

Vorab: Volle Pfade verwenden. Und SHELL/PATH setzen, wenn der Job auf eine reichere Umgebung angewiesen ist.

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

Loggt Ausgabe in eine Datei und sendet bei Fehlern zusätzlich Mail.

Wochentage um 08:00 Uhr

0 8 * * 1-5 /usr/local/bin/reports.sh

Alle fünf Minuten

*/5 * * * * /usr/local/bin/healthcheck.sh

Einmal beim Systemstart

@reboot /usr/local/bin/warmup.sh

Zwei Server, zwei Zeitzonen

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

Funktioniert nur, wenn die Implementierung CRON_TZ kennt.

System-Crontab mit Benutzerfeld

In /etc/crontab:

# m h dom mon dow user command
15 3 * * * www-data /usr/local/bin/refresh_cdn.sh

 

Wenn der Job nicht läuft

Die häufigsten Ursachen, in der Reihenfolge ihrer Verbreitung:

  • Umgebung: PATH fehlt, Aliase greifen nicht, Profil wird nicht geladen.
  • Rechte: Skript nicht ausführbar oder falscher Eigentümer.
  • Pfade: Relative statt absolute Pfade.
  • % ohne Escape: STDIN bekommt, was Sie für Argumente hielten.
  • Sommerzeit: Siehe oben.
  • Endungen in cron.daily: run-parts ignoriert sie auf manchen Systemen.

Cron loggt, aber wohin?

Cron schreibt Start-Meldungen und Fehler nach Syslog oder ins Journal. Die eigentliche Job-Ausgabe geht per Mail oder in eine Datei, die Sie explizit angeben:

0 * * * * /path/to/job.sh >>/var/log/job.log 2>&1

Wer Journald-Integration ohne Umwege will, ist bei systemd-Timern besser aufgehoben.

 

Sicherheit ist kein Add-on

  • Least Privilege: Jeder Job läuft mit den Rechten, die er braucht. Mehr nicht. Für Systemjobs das user-Feld nutzen.
  • Zugriff steuern: /etc/cron.allow und /etc/cron.deny setzen klare Grenzen.
  • Idempotenz und Sperren: Doppelstarts verhindern, etwa per flock oder Lockfile. Spätestens bei Sommerzeitumstellung danken Sie sich selbst.
  • Pfad-Hygiene: Hartkodierte absolute Pfade in jedem Befehl. Kein Verlass auf PATH.
  • Überwachung: Eigene Logs, MAILTO, im Zweifel eine externe Monitoring-Lösung. Ein Job, der schweigt, ist kein Job, der läuft.

 

Cron versus at: zwei Werkzeuge, ein Unterschied

Cron ist für wiederkehrende Aufträge da. Für das eine, einmalige „in zwei Stunden bitte“ gibt es at und seinen Daemon atd. Der Debian-Leitfaden stellt beide nebeneinander.

Verwechseln Sie sie nicht. Cron ist der Hausmeister auf Schicht, at ist der Bote für eine einzige Lieferung.

 

Checkliste: ein Cronjob, der nicht beißt

  1. Shell und Pfad explizit in der Crontab setzen.
  2. Volle Pfade in jedem Befehl.
  3. Ausgabe loggen oder per MAILTO empfangen.
  4. OR-Semantik von Tag und Wochentag verstanden haben.
  5. Sommerzeit-Risiko durch Idempotenz oder Sperren abfangen.
  6. Crontab-Umgebung einmal mit env > ~/cronenv sichtbar machen.
  7. Zugriff über cron.allow/cron.deny kontrollieren.
  8. Distribution kennen: /etc/cron.d, CRON_TZ, run-parts-Konventionen prüfen.
  9. Bei Komplexität: systemd-Timer in Betracht ziehen.
  10. Niemals Jenkins- oder Quartz-Ausdrücke in eine System-Crontab kopieren.

 

Der Kerngedanke

Cron ist alt. Cron ist eigenwillig. Cron hat eine Syntax, die niemand auf Anhieb liest.

Und trotzdem läuft auf praktisch jedem Linux-Server der Welt ein Cron-Daemon. Weil er das tut, was Software selten tut: er ist da, wenn er da sein soll, und er ist still, wenn er still sein soll.

Wer Cron beherrscht, beherrscht eine der ältesten und zuverlässigsten Automatisierungsformen der Informatik. Wer ihn unterschätzt, lernt es spätestens nachts um 02:30 Uhr.

Welcher Ihrer Jobs läuft eigentlich gerade, ohne dass Sie es wissen?

Weitere passende Glossareinträge

Ein Clickdummy macht digitale Oberflächen früh begehbar, damit Nutzerflüsse, Zustände und Schwachstellen vor der Entwicklung getestet werden.
Die Conversion Rate zeigt, welcher Anteil der Besucher eine gewünschte Handlung ausführt; entscheidend ist die richtige Bezugsgröße.
CamelCase verbindet mehrere Wörter ohne Leerzeichen und macht Wortgrenzen durch Großbuchstaben sichtbar; im Code, in APIs und Hashtags.
Eine Corporate Design Agentur entwickelt das sichtbare System, das einer Marke Wiedererkennung, Vertrauen und ein klares Gesicht gibt.
Ein Corporate LLM bringt KI ins Unternehmen, ohne sensible Daten, Wissen und Verantwortung aus der Hand zu geben.
Ein Cheatsheet bündelt wichtige Regeln, Befehle und Beispiele kompakt, damit Wissen schnell gefunden und sicher angewendet werden kann.
Ein Call-to-Action (CTA) führt Nutzer gezielt zur nächsten Handlung und verbindet klare Sprache, sichtbares Design und messbare Conversion.
Ein Cache speichert häufig benötigte Inhalte vor, damit Websites schneller laden, stabiler bleiben und Serverressourcen geschont werden.
Back to top