Cronjob einrichten: Crontab Syntax, Beispiele und Fehlerbehebung

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:
- Minute: 0 bis 59.
- Stunde: 0 bis 23.
- Tag des Monats: 1 bis 31.
- Monat: 1 bis 12 oder die ersten drei Buchstaben des englischen Monatsnamens (jan, feb usw.).
- 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.shDie 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-5läuft werktags zu jeder vollen Stunde der Bürozeit. - Schrägstrich (/): Definiert eine Schrittweite.
*/15 * * * *läuft alle 15 Minuten,0-30/10dagegen 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.@yearlyund@annually: Einmal im Jahr, entspricht0 0 1 1 *.@monthly: Einmal im Monat, entspricht0 0 1 * *.@weekly: Einmal pro Woche, entspricht0 0 * * 0.@daily: Einmal am Tag, entspricht0 0 * * *.@hourly: Einmal pro Stunde, entspricht0 * * * *.
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:
- Führen Sie die Aufgabe zuerst von Hand aus. Scheitert sie im Terminal, scheitert sie auch in cron.
- Ermitteln Sie den vollständigen Pfad jedes Programms. Notieren Sie dazu die Ausgabe von
command -v phpoderwhich php. - Öffnen Sie Ihre Tabelle mit
crontab -e. Beim ersten Aufruf fragen manche Systeme nach dem gewünschten Editor. - Schreiben Sie eine Kommentarzeile, darunter die Zeitplanzeile, und leiten Sie die Ausgabe in eine Logdatei um.
- Speichern und schließen Sie die Datei. Eine Meldung ähnlich "installing new crontab" bestätigt, dass die Tabelle geladen ist.
- Prüfen Sie die Zeile mit
crontab -lund 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>&1Wollen 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.
| Befehl | Was er tut | Risiko 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 -l | Gibt die aktuelle Tabelle aus. | Leiten Sie die Ausgabe in eine Datei um, dann haben Sie eine Sicherung. |
crontab -r | Entfernt die aktuelle Tabelle vollständig. | Keine Rückfrage, und nur eine Taste neben -e. |
crontab -i -r | Fragt vor dem Löschen nach y oder Y. | Eine sichere Gewohnheit, sofern Ihr System die Option kennt. |
crontab -u benutzer -l | Zeigt 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).txtDiese 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.
| Ort | Wer bearbeitet | Feld für Benutzer | Passt am besten für |
|---|---|---|---|
Benutzer crontab (crontab -e) | Inhaber des Kontos | Nein, läuft als dieser Benutzer | Skripte des Websitebetreibers, Shared Hosting |
/etc/crontab | root | Ja | Wartung der Distribution; eigene Änderungen gering halten |
/etc/cron.d/datei | root oder Paketverwaltung | Ja | Aufgaben einer Anwendung in einer eigenen Datei bündeln |
| Cron Jobs in cPanel | Das Konto in cPanel | Nein | Shared Hosting ohne SSH Zugang |
# /etc/cron.d/beispiel-app* * * * * www-data /usr/bin/php /var/www/example.com/artisan schedule:runEin 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.shWollen 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:runDie 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.comSauberer 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.
- Melden Sie sich in cPanel an und öffnen Sie Cron Jobs im Bereich Advanced.
- Tragen Sie im Feld Cron Email eine Adresse ein oder lassen Sie es leer, wenn Sie keine Benachrichtigungen möchten.
- Wählen Sie im Menü Common Settings ein fertiges Intervall. Es füllt Minute, Stunde, Tag, Monat und Wochentag automatisch aus.
- Geben Sie im Feld Command den vollständigen Befehlspfad ein und fügen Sie den Cronjob hinzu.
- 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>&1Der 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:
- Läuft der Dienst? Prüfen Sie das mit
systemctl status cronoder in der RHEL Familie mitsystemctl status crond. - Steht die Zeile wirklich in der Tabelle? Sehen Sie sich
crontab -lan und achten Sie auf den richtigen Benutzer. - Hat cron die Aufgabe gestartet? Suchen Sie im Systemlog zur passenden Minute nach einem Eintrag mit "CRON".
- Stimmen die Pfade? Kontrollieren Sie, dass Programme und Dateien volle Pfade haben.
- Stimmen die Rechte? Machen Sie das Skript mit
chmod +xausführbar und prüfen Sie, ob der Benutzer die Dateien erreicht. - 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.
- Gibt es ein Prozentzeichen? Ein nicht maskiertes
%zerteilt den Befehl. - Ist der Zugriff gesperrt? Existiert
cron.allow, muss Ihr Benutzer dort stehen. Existiert nurcron.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/Berlinum 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>&1Das 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.allowundcron.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.
| Ausdruck | Bedeutung | Typischer Einsatz |
|---|---|---|
*/5 * * * * | Alle 5 Minuten | Warteschlangen und Lagerabgleich |
*/15 * * * * | Alle 15 Minuten | Geplante Ereignisse in WordPress |
0 * * * * | Zu jeder vollen Stunde | Cache vorwärmen, Wechselkurse |
17 2 * * * | Täglich um 02:17 | Datenbank Backup |
0 9 * * 1-5 | Werktags um 09:00 | Täglicher Verkaufsbericht |
30 3 * * 0 | Sonntags um 03:30 | Wöchentliches Aufräumen der Logs |
0 4 1 * * | Am 1. des Monats um 04:00 | Monatliche Rechnungen oder Archiv |
@reboot | Einmal nach dem Start | Temporä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:
- Führen Sie den Befehl zuerst von Hand im Terminal aus.
- Nutzen Sie volle Pfade für Programme und Dateien.
- Leiten Sie die Ausgabe in eine Logdatei um.
- Maskieren Sie Prozentzeichen oder verlagern Sie sie ins Skript.
- Schützen Sie lange laufende Aufgaben mit
flock -n. - Prüfen Sie Zeitzone und Zeitsynchronisation.
- Lassen Sie die Aufgabe mit dem Benutzer laufen, der die geringsten nötigen Rechte hat.
- 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.



