Web

Cronjob einrichten: Crontab Syntax, Beispiele und Fehlerbehebung

Talha Aslan 20 Minuten Lesezeit 1 Aufrufe

Was ist ein Cronjob und wie richten Sie ihn ein?

Ein Cronjob ist eine geplante Aufgabe, die der Dienst cron auf Linux und Unix Systemen automatisch zu der Minute, Stunde, dem Tag, Monat und Wochentag startet, die Sie festlegen. Sie richten einen Cronjob ein, indem Sie mit crontab -e Ihre Tabelle öffnen, eine Zeile mit fünf Zeitfeldern und dem vollständigen Befehlspfad eintragen und speichern.

Wiederkehrende Arbeit läuft dank cron, ohne dass jemand eine Taste drückt. Denken Sie an nächtliche Backups, Berichte am Morgen, das Leeren eines Caches oder geplante Ereignisse in WordPress. Ein Onlineshop hängt zum Beispiel bei Lagerabgleich, Warenkorb Erinnerungen per E-Mail und der Erzeugung der Sitemap oft an einem Cronjob. Fällt cron aus, bleibt also vieles liegen, das Sie für "automatisch" gehalten haben.

In dieser Anleitung behandeln wir die Syntax, die Befehle rund um crontab, typische Fallen der Umgebung, die Oberfläche in cPanel, die Umstellung von wp-cron.php in WordPress und den Schutz vor Überschneidungen mit flock. Wir sind ein Team für digitales Marketing und Webentwicklung, kein Hostinganbieter. Deshalb stützen wir jeden Befehl auf offizielle Dokumentation wie die Handbuchseite crontab(5). Das letzte Wort hat allerdings die Ausgabe von man 5 crontab auf Ihrer eigenen Distribution, denn die Implementierungen unterscheiden sich im Detail.

Wie arbeitet cron im Hintergrund?

Cron ist ein Dienst, der beim Systemstart anläuft und dann im Hintergrund wartet. Jede Minute prüft er seine Zeitpläne und startet die Zeilen, die zu dieser Minute passen. Diese Tabellen heißen dann crontab, kurz für "cron table".

Zunächst kann jeder Benutzer eine eigene crontab besitzen. Zudem gibt es die systemweite Datei /etc/crontab sowie die Dateien im Verzeichnis /etc/cron.d/. Eine Benutzer crontab öffnen Sie nicht wie eine normale Textdatei. Stattdessen nutzen Sie den Befehl crontab. Er prüft nach dem Bearbeiten die Syntax und meldet die neue Tabelle an den Dienst.

Jede aktive Zeile in einer crontab ist entweder eine Zuweisung einer Umgebungsvariablen oder ein geplanter Befehl. Zeilen mit einer Raute (#) am Anfang sind Kommentare, und cron überspringt sie. Sie können also jeden Cronjob direkt darüber dokumentieren.

Die Handbuchseite betont außerdem ein Detail, das oft übersehen bleibt. Konkret verlangt cron, dass jeder Eintrag mit einem Zeilenumbruch endet. Drücken Sie nach der letzten Zeile nicht die Eingabetaste, startet dieser Cronjob unter Umständen nie.

Kurz gesagt ist die Logik einfach: Der Dienst beobachtet die Uhr, und die Tabelle sagt, was wann läuft. Fast alle Probleme entstehen daher in der Schreibweise der Zeile oder weil sich der Befehl in der Umgebung von cron anders verhält.

Wie lesen Sie die Syntax einer crontab?

Eine Zeile in der Benutzer crontab besteht aus fünf Zeitfeldern und dem anschließenden Befehl. Sie lesen die Felder von links nach rechts in dieser Reihenfolge:

  1. Minute: 0 bis 59.
  2. Stunde: 0 bis 23.
  3. Tag des Monats: 1 bis 31.
  4. Monat: 1 bis 12 oder die ersten drei Buchstaben des englischen Monatsnamens (jan, feb usw.).
  5. Wochentag: 0 bis 7, wobei 0 und 7 für Sonntag stehen. Namen wie mon oder tue funktionieren ebenso.
# minute stunde tag-im-monat monat wochentag befehl30 3 * * * /usr/local/bin/naechtliches-backup.sh

Die Zeile oben startet das Skript jeden Tag um 3:30 Uhr. Das Sternchen bedeutet also "jeder Wert in diesem Feld". Folglich bleiben Tag, Monat und Wochentag uneingeschränkt.

Eine Regel im Handbuch überrascht allerdings viele. Schränken Sie sowohl den Tag des Monats als auch den Wochentag ein, läuft der Cronjob, sobald eines der beiden Felder passt. Konkret heißt 0 9 13 * 5 nicht "Freitag, der 13.". Die Zeile läuft an jedem 13. eines Monats und zusätzlich an jedem Freitag um 9:00 Uhr. Brauchen Sie eine solche Bedingung, prüfen Sie das Datum daher besser im Skript selbst.

Was bedeuten Sternchen, Komma, Bindestrich und Schrägstrich?

Vier Sonderzeichen machen die Zeitfelder flexibel. Zudem lassen sie sich kombinieren, sodass recht genaue Zeitpläne in einer einzigen Zeile entstehen.

  • Sternchen (*): Jeder Wert vom ersten bis zum letzten. Ein Sternchen im Stundenfeld bedeutet "jede Stunde".
  • Komma (,): Bildet eine Liste. 0 8,12,18 * * * läuft dreimal täglich, um 8, 12 und 18 Uhr.
  • Bindestrich (-): Legt einen Bereich fest, beide Enden eingeschlossen. 0 9-17 * * 1-5 läuft werktags zu jeder vollen Stunde der Bürozeit.
  • Schrägstrich (/): Definiert eine Schrittweite. */15 * * * * läuft alle 15 Minuten, 0-30/10 dagegen in den Minuten 0, 10, 20 und 30.

Bei Schrittweiten sollten Sie allerdings genau hinsehen. */7 im Minutenfeld wirkt wie "alle sieben Minuten". Die Zählung beginnt jedoch jede Stunde wieder bei 0, deshalb fällt die letzte Lücke nach Minute 56 kürzer aus. Schritte, die 60 glatt teilen (5, 10, 15, 20, 30), liefern somit verlässlichere Ergebnisse.

Manche Implementierungen kennen außerdem zusätzliche Syntax. Das Handbuch von cronie beschreibt zum Beispiel eine Tilde (~), die einen Zufallswert innerhalb eines Bereichs wählt. Diese Erweiterung gibt es allerdings nicht überall. Wollen Sie eine portable Zeile, bleiben Sie also bei den vier Zeichen oben.

Wofür stehen @reboot, @daily und die anderen Kurzformen?

Statt jedes Mal fünf Felder zu schreiben, können Sie die Kurznamen aus dem Handbuch nutzen. Sie machen Tabellen zudem lesbarer, vor allem wenn ein ganzes Team damit arbeitet.

  • @reboot: Läuft einmal nach dem Neustart des Systems.
  • @yearly und @annually: Einmal im Jahr, entspricht 0 0 1 1 *.
  • @monthly: Einmal im Monat, entspricht 0 0 1 * *.
  • @weekly: Einmal pro Woche, entspricht 0 0 * * 0.
  • @daily: Einmal am Tag, entspricht 0 0 * * *.
  • @hourly: Einmal pro Stunde, entspricht 0 * * * *.

Der Haken dabei: @daily meint Mitternacht. Stauen sich viele Aufgaben um Mitternacht, tragen Festplatte und Datenbank die Last in derselben Minute. Deshalb empfehlen wir, schwere Arbeit auf krumme Minuten wie 17 2 * * * zu verteilen.

@reboot ist praktisch, aber begrenzt. Während des Starts sind Netzwerk, Datenbank oder eingebundene Laufwerke womöglich noch nicht bereit. Für eine Anwendung, die dauerhaft laufen muss, passt daher ein Dienst unter systemd besser als cron. Diesen Weg zeigen wir in unserer Anleitung zum Deployment von Node.js mit Nginx und systemd.

Wie richten Sie einen Cronjob Schritt für Schritt ein?

Auf einem VPS oder Server mit SSH Zugang ist Ihr erster Cronjob in wenigen Minuten fertig. Haben Sie die Grundeinrichtung noch nicht erledigt, beginnen Sie zunächst mit unserer Anleitung zur Ersteinrichtung von Ubuntu Server. Dann gehen Sie so vor:

  1. Führen Sie die Aufgabe zuerst von Hand aus. Scheitert sie im Terminal, scheitert sie auch in cron.
  2. Ermitteln Sie den vollständigen Pfad jedes Programms. Notieren Sie dazu die Ausgabe von command -v php oder which php.
  3. Öffnen Sie Ihre Tabelle mit crontab -e. Beim ersten Aufruf fragen manche Systeme nach dem gewünschten Editor.
  4. Schreiben Sie eine Kommentarzeile, darunter die Zeitplanzeile, und leiten Sie die Ausgabe in eine Logdatei um.
  5. Speichern und schließen Sie die Datei. Eine Meldung ähnlich "installing new crontab" bestätigt, dass die Tabelle geladen ist.
  6. Prüfen Sie die Zeile mit crontab -l und lesen Sie nach dem ersten Lauf die Logdatei.
# Datenbank Backup jede Nacht um 02:1717 2 * * * /usr/local/bin/db-backup.sh >> /home/deploy/logs/db-backup.log 2>&1

Wollen Sie nicht auf den ersten Lauf warten, setzen Sie vorübergehend */2 * * * * und prüfen das Log zwei Minuten später. Danach stellen Sie dann den Zeitplan auf den eigentlichen Wert zurück. Wie oft Backups laufen und wohin sie gehen, planen Sie am besten mit unserer Anleitung zur Backup Strategie für Websites.

Worauf achten Sie bei crontab -e, -l und -r?

Laut Handbuchseite crontab(1) decken drei Optionen fast die gesamte tägliche Arbeit ab. Eine davon löscht allerdings mit einem Tastendruck die ganze Tabelle.

BefehlWas er tutRisiko und Tipp
crontab -eÖffnet die Tabelle im Editor aus VISUAL oder EDITOR.Prüft beim Speichern die Syntax und bietet bei Fehlern erneutes Bearbeiten an.
crontab -lGibt die aktuelle Tabelle aus.Leiten Sie die Ausgabe in eine Datei um, dann haben Sie eine Sicherung.
crontab -rEntfernt die aktuelle Tabelle vollständig.Keine Rückfrage, und nur eine Taste neben -e.
crontab -i -rFragt vor dem Löschen nach y oder Y.Eine sichere Gewohnheit, sofern Ihr System die Option kennt.
crontab -u benutzer -lZeigt die Tabelle eines anderen Benutzers.Nur ein privilegierter Benutzer (root) darf das.

Weil "e" und "r" auf der Tastatur nebeneinander liegen, passiert ein versehentliches crontab -r öfter, als man denkt. Daher raten wir zu einer Kopie vor jeder Änderung:

crontab -l > ~/crontab-sicherung-$(date +%F).txt

Diese Zeile führen Sie im Terminal aus, nicht in der crontab. Warum, erklären wir weiter unten im Abschnitt zum Prozentzeichen.

Worin unterscheiden sich Benutzer crontab und System crontab?

Es gibt mehrere Orte für Cronjobs, und jeder hat ein eigenes Zeilenformat und eine eigene Logik für Besitzrechte. Das Handbuch zählt Aufgaben in /etc/crontab und /etc/cron.d/ zu den Systemaufgaben. Diese Dateien erwarten deshalb nach den Zeitfeldern ein Feld mit dem Benutzernamen.

OrtWer bearbeitetFeld für BenutzerPasst am besten für
Benutzer crontab (crontab -e)Inhaber des KontosNein, läuft als dieser BenutzerSkripte des Websitebetreibers, Shared Hosting
/etc/crontabrootJaWartung der Distribution; eigene Änderungen gering halten
/etc/cron.d/dateiroot oder PaketverwaltungJaAufgaben einer Anwendung in einer eigenen Datei bündeln
Cron Jobs in cPanelDas Konto in cPanelNeinShared Hosting ohne SSH Zugang
# /etc/cron.d/beispiel-app* * * * * www-data /usr/bin/php /var/www/example.com/artisan schedule:run

Ein vergessenes Benutzerfeld ist vor allem in Systemdateien der häufigste Fehler. Cron hält dann das erste Wort Ihres Befehls für den Benutzernamen. Andererseits versucht cron, den Benutzernamen als Befehl auszuführen, wenn Sie dieses Feld in eine Benutzer crontab schreiben. Prüfen Sie also immer, wo die Zeile steht.

Warum findet cron Ihren Befehl nicht, und wie beheben Sie PATH?

"Im Terminal klappt es, in cron nicht" liegt fast immer an der Umgebung. Beim Anmelden lädt Ihre Shell Profildateien, PATH, Spracheinstellungen und Versionsmanager. Cron lädt davon dagegen sehr wenig.

Laut Handbuch setzt cron SHELL auf /bin/sh. LOGNAME und HOME übernimmt es aus dem Benutzerkonto des Tabelleninhabers. PATH erhält einen kurzen Standardwert, der von der Distribution abhängt und deutlich kürzer ist als Ihr PATH nach dem Login. Folglich fehlen Programme aus /usr/local/bin wie composer, wp oder ein node aus einem Versionsmanager innerhalb von cron womöglich.

Sie haben drei Wege zur Lösung:

  • Setzen Sie eine eigene PATH Zeile an den Anfang der Tabelle.
  • Definieren Sie SHELL=/bin/bash, wenn Ihre Skripte Syntax nutzen, die nur bash versteht.
  • Am robustesten: Schreiben Sie jedes Programm mit vollem Pfad, in der Zeile und im Skript.
SHELL=/bin/bashPATH=/usr/local/bin:/usr/bin:/binMAILTO=""*/10 * * * * /usr/local/bin/beispiel-aufgabe.sh

Wollen Sie wissen, was cron wirklich sieht? Tragen Sie einmalig * * * * * env > /tmp/cron-umgebung.txt ein, lesen Sie die Datei eine Minute später und löschen Sie die Zeile dann wieder. So arbeiten Sie mit echten Daten statt mit Vermutungen.

Warum sind absolute Pfade so wichtig?

Wenn ein Cronjob läuft, ist das Arbeitsverzeichnis nicht der Ordner, in dem Sie gerade im Terminal stehen. Meist ist es stattdessen das Heimatverzeichnis des Benutzers. Deshalb scheitern relative Befehle wie ./backup.sh oder php artisan in cron oder greifen auf falsche Dateien zu.

Die Regel ist einfach. Schreiben Sie in der crontab sowohl das Programm als auch die Datei mit vollem Pfad. Liest oder schreibt Ihr Skript Dateien, wechseln Sie zu Beginn ausdrücklich ins Arbeitsverzeichnis und brechen ab, falls das scheitert.

#!/bin/bashset -euo pipefailcd /var/www/example.com || exit 1/usr/bin/php artisan schedule:run

Die Zeile set -euo pipefail verhindert, dass das Skript nach einem Fehler einfach weiterläuft. Stellen Sie sich einen Datenbankdump vor, der scheitert, während das Skript trotzdem das alte Backup löscht und "fertig" meldet. Das bemerken Sie sonst erst am Tag der Wiederherstellung. Details zu Dump und Wiederherstellung finden Sie in unserer Anleitung zu mysqldump und pg_dump.

Bei PHP gilt dieselbe Sorgfalt. Shared Hosting bringt oft mehrere PHP Versionen mit, und ein schlichtes php zeigt womöglich nicht auf die Version Ihrer Website. Wie Sie die aktive Version prüfen, erklären wir in unserer Anleitung zur PHP Version in cPanel. Nutzen Sie dann auch in der Zeile von cron den vollen Pfad dieser Version.

Wie leiten Sie die Ausgabe von cron in eine Logdatei um?

Standardmäßig schickt cron jede Ausgabe eines Cronjobs per E-Mail an den Inhaber der Tabelle. Die Variable MAILTO legt diese Adresse dann fest. Fehlt auf dem Server ein Mailsystem, geht die Ausgabe verloren. Ist eines vorhanden, füllt sich Ihr Postfach mit Hunderten nutzloser Nachrichten. Deshalb sollten Sie die Ausgabe bewusst steuern.

  • >> /pfad/aufgabe.log 2>&1: Hängt normale Ausgabe und Fehler an die Datei an.
  • > /dev/null 2>&1: Verwirft jede Ausgabe. Nutzen Sie das nur für Aufgaben, die Sie anderweitig überwachen.
  • MAILTO="": Schaltet die E-Mail für alle Aufgaben dieser Tabelle ab.

Die Reihenfolge von 2>&1 am Ende ist entscheidend. Zunächst leiten Sie die Standardausgabe in die Datei, dann den Fehlerkanal auf die Standardausgabe. Drehen Sie die Reihenfolge um, verschwinden die Fehler trotzdem.

Zudem wachsen auch Logdateien mit der Zeit. Für dauerhaft laufende Aufgaben empfehlen wir, sie mit logrotate zu rotieren oder jede Zeile im Skript mit einem Datum zu versehen. Cron führt außerdem eigene Aufzeichnungen. Unter Debian und Ubuntu finden Sie diese im Systemlog unter "CRON", auf Distributionen mit systemd lesen Sie sie mit journalctl. Für eine größere Auswertung können Sie zudem unsere Logfile Analyse nutzen.

Warum zerstört ein Prozentzeichen die Zeile?

Eine der unbekanntesten Regeln im Handbuch betrifft das Prozentzeichen. Ein nicht maskiertes % im Befehlsteil wird zum Zeilenumbruch, und alles nach dem ersten Prozentzeichen geht als Standardeingabe an den Befehl. Deshalb läuft eine Zeile mit date +%F im Terminal tadellos, bricht in cron aber mittendrin ab.

# Falsch: alles nach % geht als Eingabe an den Befehl0 1 * * * /usr/bin/tar czf /backup/site-$(date +%F).tgz /var/www/example.com# Richtig: Prozentzeichen mit Backslash maskieren0 1 * * * /usr/bin/tar czf /backup/site-$(date +\%F).tgz /var/www/example.com

Sauberer ist es, die Datumsformatierung komplett ins Skript zu verlagern. Dann bleibt die Zeile in der crontab schlicht, und das Skript verhält sich im Terminal und in cron gleich. Genau diesen Aufbau bevorzugen wir: Die crontab beantwortet das "Wann", das Skript das "Wie".

Ähnlich tückisch sind Anführungszeichen. Cron übergibt die Zeile an /bin/sh, daher steigt das Fehlerrisiko, je mehr verschachtelte Anführungszeichen, Variablen und Sonderzeichen zusammenkommen. Lagern Sie also jede Logik, die nicht in eine Zeile passt, in eine eigene Skriptdatei aus. Das erleichtert Lesen und Fehlersuche gleichermaßen.

Wie legen Sie einen Cronjob in cPanel an?

Im Shared Hosting fehlt oft der SSH Zugang. Dann legen Sie einen Cronjob über die Oberfläche von cPanel an. Laut Dokumentation von cPanel finden Sie die Seite im Bereich Advanced unter dem Namen Cron Jobs.

  1. Melden Sie sich in cPanel an und öffnen Sie Cron Jobs im Bereich Advanced.
  2. Tragen Sie im Feld Cron Email eine Adresse ein oder lassen Sie es leer, wenn Sie keine Benachrichtigungen möchten.
  3. Wählen Sie im Menü Common Settings ein fertiges Intervall. Es füllt Minute, Stunde, Tag, Monat und Wochentag automatisch aus.
  4. Geben Sie im Feld Command den vollständigen Befehlspfad ein und fügen Sie den Cronjob hinzu.
  5. Bestehende Aufgaben bearbeiten oder löschen Sie über die Liste weiter unten auf derselben Seite.

Die Dokumentation gibt zwei klare Warnungen. Erstens sollen Sie genug Zeit zwischen den Läufen lassen, damit eine Aufgabe fertig wird. Sonst startet der Server womöglich einen neuen Lauf, während der alte noch arbeitet. Zweitens sollen Sie rm in cron sehr vorsichtig einsetzen, denn ein falscher Pfad kann Daten im Heimatverzeichnis löschen.

Soll ein bestimmter Cronjob keine E-Mail senden, hängen Sie >/dev/null 2>&1 an den Befehl. Der PHP Pfad im Befehl hängt vom Anbieter ab; nutzen Sie daher den Pfad aus dessen Dokumentation. Manche Anbieter begrenzen zudem sehr häufige Aufgaben. Fragen Sie in dem Fall den Support, statt das Limit zu raten.

Wie ersetzen Sie den WordPress Cron durch einen echten Cronjob?

Das System WP-Cron, das WordPress für geplante Beiträge, Plugin Updates und Mailwarteschlangen nutzt, ist kein echtes cron. Die Entwicklerdokumentation von WordPress erklärt, dass es bei jedem Seitenaufruf anspringt. Auf Websites mit wenig Besuch laufen Aufgaben daher verspätet, auf stark besuchten Websites prüft WordPress dagegen viel öfter als nötig.

Die Lösung besteht darin, den Auslöser beim Seitenaufruf abzuschalten und die Arbeit dem Zeitplaner des Systems zu übergeben. Zunächst tragen Sie laut Dokumentation diese Zeile in wp-config.php ein:

define( 'DISABLE_WP_CRON', true );

Danach richten Sie einen echten Cronjob ein. Die offizielle Seite zeigt ein Beispiel, das wp-cron.php per HTTP aufruft, und nennt */15 * * * * für ein Intervall von 15 Minuten. Ist WP-CLI auf dem Server installiert, starten Sie fällige Ereignisse auch ohne HTTP Anfrage direkt über die Kommandozeile:

*/15 * * * * cd /home/benutzer/public_html && /usr/local/bin/wp cron event run --due-now >> /home/benutzer/logs/wp-cron.log 2>&1

Der Pfad zu wp unterscheidet sich je nach Server, also prüfen Sie ihn mit command -v wp. Setzen Sie DISABLE_WP_CRON, vergessen aber den Cronjob, erscheinen geplante Beiträge nicht und Mails bleiben liegen. Hakt der Mailversand in WordPress, hilft Ihnen unsere Anleitung zu WP Mail SMTP.

Wo fangen Sie an, wenn ein Cronjob nicht läuft?

Läuft ein Cronjob nicht wie erwartet, spart eine feste Prüfreihenfolge Zeit gegenüber zufälligen Änderungen. Wir empfehlen diese Reihenfolge:

  1. Läuft der Dienst? Prüfen Sie das mit systemctl status cron oder in der RHEL Familie mit systemctl status crond.
  2. Steht die Zeile wirklich in der Tabelle? Sehen Sie sich crontab -l an und achten Sie auf den richtigen Benutzer.
  3. Hat cron die Aufgabe gestartet? Suchen Sie im Systemlog zur passenden Minute nach einem Eintrag mit "CRON".
  4. Stimmen die Pfade? Kontrollieren Sie, dass Programme und Dateien volle Pfade haben.
  5. Stimmen die Rechte? Machen Sie das Skript mit chmod +x ausführbar und prüfen Sie, ob der Benutzer die Dateien erreicht.
  6. Stimmen die Zeilenenden? Unter Windows bearbeitete Skripte tragen CRLF Zeilenenden, die zum Fehler "bad interpreter" führen. Wandeln Sie sie in LF um und lassen Sie nach der letzten Zeile der crontab einen Zeilenumbruch.
  7. Gibt es ein Prozentzeichen? Ein nicht maskiertes % zerteilt den Befehl.
  8. Ist der Zugriff gesperrt? Existiert cron.allow, muss Ihr Benutzer dort stehen. Existiert nur cron.deny, darf er dort nicht stehen.

Ändern Sie pro Schritt nur eine Sache. Ändern Sie drei Einstellungen gleichzeitig, wissen Sie nämlich nicht, welche das Problem gelöst oder welche ein neues verursacht hat.

Wie verschieben Zeitzonen Ihren Zeitplan?

"Ich habe 9:00 Uhr eingestellt, aber er lief um 7:00 Uhr" ist fast immer ein Thema der Zeitzone. Cron richtet sich nach der Systemuhr und der lokalen Zeitzone des Servers. Viele Cloudserver kommen zum Beispiel mit UTC. Deutschland liegt dagegen je nach Jahreszeit eine oder zwei Stunden vor UTC. Ein Eintrag 0 9 * * * auf einem UTC Server läuft folglich deutlich später nach deutscher Zeit.

Sie haben zwei Möglichkeiten:

  • Sie stellen die Zeitzone des Servers mit timedatectl set-timezone Europe/Berlin um und starten den Dienst cron neu.
  • Sie lassen den Server auf UTC und berechnen die Zeitpläne in UTC. Für Systeme, die mehrere Länder bedienen, sorgt das für weniger Überraschungen.

Manche Implementierungen unterstützen die Variable CRON_TZ für eine Zeitzone pro Tabelle, und das Handbuch beschreibt sie. Allerdings kennt nicht jede Distribution diese Variable. Suchen Sie deshalb vorher in Ihrer eigenen Ausgabe von man 5 crontab. Auch die Zeitumstellung verdient Vorsicht, denn in diesen Nächten kann sich eine Stunde wiederholen oder ausfallen.

Eine abdriftende Uhr ist außerdem ein weiteres Risiko. Geht die Systemuhr ein paar Minuten vor oder nach, laufen Aufgaben zur falschen Zeit, und Zeitstempel in Logs passen nicht mehr zusammen. Sorgen Sie daher für eine aktive Zeitsynchronisation. Details stehen in unserem Beitrag NTP und Zeitsynchronisation auf Linux Servern.

Wie verhindern Sie überlappende Läufe mit flock?

Ein Cronjob, der alle fünf Minuten startet, braucht manchmal sieben. Dann startet cron eine zweite Kopie, bevor die erste fertig ist. Schreiben beide Kopien in dieselben Dateien oder Tabellen, können Daten beschädigt werden. Genau davor warnt auch die Dokumentation von cPanel.

Unter Linux löst flock aus dem Paket util-linux dieses Problem mit einer Sperrdatei. Laut Handbuchseite flock(1) sorgt die Option -n dafür, dass flock sofort scheitert, statt zu warten, wenn die Sperre belegt ist. Läuft die vorherige Kopie also noch, startet die neue gar nicht erst.

*/5 * * * * /usr/bin/flock -n /tmp/lagerabgleich.lock /usr/local/bin/lagerabgleich.sh >> /home/deploy/logs/lager.log 2>&1

Das Handbuch beschreibt zudem zwei weitere Optionen:

  • -w sekunden: Wartet so viele Sekunden auf die Sperre und gibt dann auf.
  • -E code: Legt den Exitcode fest, wenn die Sperre nicht frei ist. Der Standardwert ist 1. So unterscheiden Sie Sperrkonflikte von echten Fehlern.

Geben Sie außerdem jedem Cronjob eine eigene Sperrdatei. Teilen sich zwei verschiedene Aufgaben eine Sperre, blockiert die eine die andere ohne Grund. Zudem gibt der Kernel die Sperre frei, sobald der Prozess endet oder abstürzt, also müssen Sie Sperrdateien nie von Hand löschen.

Worauf achten Sie bei der Sicherheit von Cronjobs?

Cron startet Befehle regelmäßig, auch wenn Sie nicht da sind. In falschen Händen wird diese Fähigkeit zu einem Werkzeug, um sich dauerhaft im System festzusetzen. Deshalb gehören crontab Dateien zu den ersten Stellen, die eine Sicherheitsprüfung ansieht.

  • Geringste Rechte: Lassen Sie den Cronjob mit einem Benutzer laufen, der gerade genug Rechte hat, nicht als root. Die Aufgabe einer Webanwendung gehört zum Benutzer dieser Anwendung.
  • Rechte am Skript: Dürfen andere Benutzer ein Skript ändern, das root ausführt, erhalten sie indirekt die Rechte von root. Daher sollten nur Sie als Inhaber Skript und Ordner beschreiben können.
  • Passwörter: Schreiben Sie Datenbankpasswörter nicht in die Zeile der crontab, denn sie tauchen sonst in der Prozessliste und in Logs auf. Nutzen Sie eine Konfigurationsdatei, die nur der Inhaber lesen kann.
  • Zugriffslisten: Begrenzen Sie über cron.allow und cron.deny, wer crontab nutzen darf.
  • Regelmäßige Kontrolle: Entdecken Sie eine unbekannte Zeile, vor allem eine, die etwas von außen lädt und ausführt, werten Sie das als ernstes Warnsignal.

Den Zugang zum Server einzuschränken ist zugleich der erste Schutz für cron. Zur Härtung von SSH lesen Sie unsere Anleitung zu Swap und SSH Absicherung. Gegen Brute Force Versuche hilft unsere Anleitung zu Fail2ban.

Häufige Ausdrücke für Cronjobs im Überblick

Die folgende Tabelle sammelt die Zeitpläne, die wir auf Websites am häufigsten brauchen, samt Lesart. Passen Sie die Werte an Ihre Arbeit an und legen Sie schwere Aufgaben auf krumme Minuten.

AusdruckBedeutungTypischer Einsatz
*/5 * * * *Alle 5 MinutenWarteschlangen und Lagerabgleich
*/15 * * * *Alle 15 MinutenGeplante Ereignisse in WordPress
0 * * * *Zu jeder vollen StundeCache vorwärmen, Wechselkurse
17 2 * * *Täglich um 02:17Datenbank Backup
0 9 * * 1-5Werktags um 09:00Täglicher Verkaufsbericht
30 3 * * 0Sonntags um 03:30Wöchentliches Aufräumen der Logs
0 4 1 * *Am 1. des Monats um 04:00Monatliche Rechnungen oder Archiv
@rebootEinmal nach dem StartTemporäre Ordner vorbereiten

Denken Sie daran, dass die Uhrzeiten der Zeitzone des Servers folgen. Prüfen Sie außerdem vor dem Livegang die nächsten Laufzeiten auf Papier oder mit einem verlässlichen Rechner. Dieser einfache Schritt verhindert, dass ein "monatlicher" Cronjob jeden Tag läuft.

Wann sollten Sie cron nicht selbst verwalten?

Cron ist mächtig, verzeiht aber wenig. In manchen Fällen überlassen Sie die Arbeit besser Ihrem Hostinganbieter oder Ihrer Serveradministration. Ehrlich gesagt raten wir unseren Kunden das häufig.

  • Bei Managed Hosting plant der Anbieter Backups und Wartung meist bereits selbst. Dieselbe Aufgabe doppelt einzurichten führt dann zu Konflikten.
  • Braucht die Aufgabe Rechte von root und fehlt Ihnen Erfahrung damit, kann ein Fehler das ganze System treffen.
  • Steuert der Cronjob einen kritischen Ablauf wie Zahlungen, Rechnungen oder Kundendaten, richten Sie ihn nicht ohne Überwachung, Alarme und Plan für den Rückweg ein.
  • Setzt Ihr Shared Hosting ein Limit für die Häufigkeit, sprechen Sie mit dem Support, statt es auszureizen.

Fragen Sie schon bei der Wahl des Hostings nach Zugang zu cron, SSH und der Backup Politik; das erspart viele dieser Probleme. Eine Checkliste finden Sie in unserem Beitrag zur Auswahl von Webhosting. Soll Ihre Website von Anfang an auf solidem Fundament stehen, planen wir geplante Aufgaben auch im Rahmen unseres Webdesign Angebots mit ein.

Checkliste: Was prüfen Sie vor dem Livegang eines Cronjobs?

Einen Cronjob einzurichten wirkt wie eine Aufgabe für eine einzige Zeile. Ob diese Zeile aber jahrelang still und zuverlässig läuft, hängt von ein paar Gewohnheiten ab. Zusammengefasst gehen Sie bei jeder neuen Aufgabe diese Liste durch:

  1. Führen Sie den Befehl zuerst von Hand im Terminal aus.
  2. Nutzen Sie volle Pfade für Programme und Dateien.
  3. Leiten Sie die Ausgabe in eine Logdatei um.
  4. Maskieren Sie Prozentzeichen oder verlagern Sie sie ins Skript.
  5. Schützen Sie lange laufende Aufgaben mit flock -n.
  6. Prüfen Sie Zeitzone und Zeitsynchronisation.
  7. Lassen Sie die Aufgabe mit dem Benutzer laufen, der die geringsten nötigen Rechte hat.
  8. Sichern Sie vor jeder Änderung die Tabelle mit crontab -l.

Diese acht Schritte verhindern die meisten Probleme mit cron, bevor sie überhaupt auftreten. Somit bleibt ein gut eingerichteter Cronjob unsichtbar: Backups entstehen, Berichte kommen an, Beiträge in WordPress gehen pünktlich online, und Sie müssen sich um nichts davon kümmern.

Häufig gestellte Fragen

Wie oft kann ein Cronjob höchstens laufen?
Ein klassischer Cronjob läuft höchstens einmal pro Minute, denn der Dienst prüft seine Tabellen im Minutentakt. Brauchen Sie eine Steuerung im Sekundenbereich, ist cron das falsche Werkzeug. Besser passt dann ein dauerhaft laufender Dienst oder ein Worker für Warteschlangen. Im Shared Hosting setzen Anbieter zudem oft ein Mindestintervall, also prüfen Sie deren Dokumentation.
Wo liegt die crontab, und darf ich sie direkt bearbeiten?
Benutzer crontabs liegen in einem Ordner unter /var/spool, der genaue Pfad hängt von der Distribution ab. Direkt bearbeiten sollten Sie diese Dateien allerdings nicht. Der Befehl crontab -e öffnet die Datei, prüft beim Speichern die Syntax und informiert den Dienst. Für Systemaufgaben bearbeiten Sie dagegen Dateien unter /etc/cron.d mit Rechten von root.
Kann ich mit crontab -r gelöschte Aufgaben wiederherstellen?
Nein, crontab -r entfernt die Tabelle ohne Rückfrage, und cron selbst bietet keine Funktion zum Rückgängigmachen. Haben Sie die Ausgabe von crontab -l zuvor in eine Datei gesichert, spielen Sie diese mit crontab und dem Dateinamen wieder ein. Ohne Kopie brauchen Sie ein Serverbackup oder Hilfe Ihres Hostinganbieters. Sichern Sie daher vor jeder Änderung.
Macht DISABLE_WP_CRON WordPress schneller?
Teilweise, denn WordPress prüft fällige Aufgaben dann nicht mehr bei jedem Seitenaufruf. Der größere Gewinn ist allerdings die Zuverlässigkeit, weil Aufgaben unabhängig vom Besucheraufkommen nach Ihrem Zeitplan laufen. Setzen Sie die Zeile aber ohne echten Cronjob, bleiben geplante Beiträge und Mails komplett liegen. Prüfen Sie nach der Umstellung die ersten Läufe im Log.
Sollte ich cron oder einen Timer von systemd nutzen?
Für einfache, wiederkehrende Aufgaben reicht cron, und es ist fast überall verfügbar, auch im Shared Hosting. Ein Timer von systemd bietet zusätzlich Abhängigkeiten, das Nachholen verpasster Läufe und Protokolle direkt im Journal. Auf einem VPS mit Zugang als root passt ein Timer daher gut zu komplexen Aufgaben, im Shared Hosting bleibt cron meist die praktische Wahl.
Woran erkenne ich, dass mein Cronjob wirklich läuft?
Am zuverlässigsten ist es, wenn der Cronjob seine Ausgabe mit Zeitstempel in eine Logdatei schreibt. Zusätzlich sehen Sie im Systemlog an den Einträgen mit CRON, ob der Dienst die Aufgabe gestartet hat. Bei kritischen Aufgaben aktualisieren Sie nach Erfolg den Zeitstempel einer Datei und lassen ein Monitoring diesen prüfen. So fallen stille Ausfälle früh auf.
  • Cronjob
  • crontab
  • Linux Server
  • cPanel
  • WordPress
  • flock
  • Serververwaltung
Teilen:
Talha Aslan

Google Partner und Experte für digitales Marketing. Seit 2012 praktisch in SEO, Google Ads, Webdesign und E-Commerce Projekten; jeder Beitrag hier stammt aus dieser Erfahrung.

Nächstes Projekt

Sprechen wir über Ihr Projekt.

Ihre Anfrage geht direkt an Talha Aslan und Team: Strategie von Talha, Umsetzung durch ein erfahrenes Team. Das Erstgespräch ist kostenlos, wir hören zu und melden uns mit einer klaren Roadmap.