Anleitung

Crontab: Beispiele für Aufgabenpläne unter Linux, Syntax und typische Fehler

Aktualisiert: · Skillaria.Top

Crontab ist die Zeitplantabelle, nach der der Dienst cron Befehle startet: Jede Zeile besteht aus fünf Zeitfeldern (Minute, Stunde, Tag des Monats, Monat, Wochentag) und dem Befehl, zum Beispiel startet */5 * * * * /opt/backup.sh das Skript alle 5 Minuten. Bearbeitet wird die Tabelle mit crontab -e; die meisten Probleme entstehen durch die minimale Umgebung von cron, deshalb geben Sie vollständige Pfade an und leiten die Ausgabe in ein Protokoll um.

Cron ist der Standard-Aufgabenplaner unter Linux: Der Dienst cron liest einmal pro Minute die Zeitplantabellen (crontab) und startet die Befehle, deren Zeit gekommen ist. So werden nachts Backups erstellt, temporäre Dateien aufgeräumt, Zertifikate erneuert und Berichte verschickt. Im Folgenden finden Sie die Syntax, crontab Beispiele für typische Fälle und eine Analyse der Fehler, durch die eine Aufgabe „stillschweigend“ nicht ausgeführt wird.

Crontab öffnen und bearbeiten

Jeder Benutzer hat eine eigene Tabelle. Mit ihr arbeiten Sie über den Befehl crontab und nicht durch direktes Bearbeiten der Dateien in /var/spool/cron:

BefehlWas er macht
crontab -eeigene Tabelle im Editor öffnen (beim ersten Start fragt er nach dem Editor)
crontab -laktuelle Tabelle anzeigen
crontab -rTabelle vollständig löschen, ohne Rückfrage
crontab -i -rmit Rückfrage löschen (Debian/Ubuntu, RHEL)
sudo crontab -u alice -eTabelle eines anderen Benutzers bearbeiten
crontab dateiTabelle durch den Inhalt einer Datei ersetzen

Nach dem Speichern mit crontab -e prüft das Programm die Syntax und meldet crontab: installing new crontab. Steckt ein Fehler in einer Zeile, sehen Sie errors in crontab file, can't install und das Angebot, erneut zu bearbeiten. Den Dienst müssen Sie nicht neu starten — Änderungen werden automatisch übernommen.

Seien Sie vorsichtig mit -r: Die Tasten e und r liegen auf der Tastatur nebeneinander, und eine Sicherungskopie der Tabelle gibt es nicht. Eine nützliche Gewohnheit ist es, ein Backup anzulegen:

crontab -l > ~/crontab.bak
# wiederherstellen
crontab ~/crontab.bak

Crontab-Syntax: fünf Zeitfelder

Jede Zeile einer Aufgabe sieht so aus:

# ┌───────── Minute (0–59)
# │ ┌─────── Stunde (0–23)
# │ │ ┌───── Tag des Monats (1–31)
# │ │ │ ┌─── Monat (1–12 oder jan–dec)
# │ │ │ │ ┌─ Wochentag (0–7 oder sun–sat; 0 und 7 — Sonntag)
# │ │ │ │ │
  * * * * * Befehl

In jedem Feld können Sie folgende Sonderzeichen verwenden:

ZeichenBedeutungBeispiel
*beliebiger Wert* * * * * — jede Minute
,Liste0 9,18 * * * — um 9:00 und 18:00
-Bereich0 9-18 * * * — jede Stunde von 9 bis 18
/Schrittweite*/15 * * * * — alle 15 Minuten

Eine Schrittweite lässt sich mit einem Bereich kombinieren: 0 8-20/2 * * * — alle zwei Stunden von 8 bis 20 Uhr (8, 10, …, 20). Die Zeit richtet sich nach der Zeitzone des Systems — prüfen Sie sie mit timedatectl.

Crontab-Beispiele für jeden Tag

ZeitplanZeile in crontab
jede Minute* * * * *
alle 5 Minuten*/5 * * * *
alle 30 Minuten*/30 * * * * oder 0,30 * * * *
jede volle Stunde0 * * * *
alle 6 Stunden0 */6 * * *
jeden Tag um 3:000 3 * * *
jeden Tag um 23:4545 23 * * *
werktags um 9:000 9 * * 1-5
am Wochenende mittags0 12 * * 6,0
montags um 8:3030 8 * * 1
am 1. jedes Monats um 0:000 0 1 * *
einmal pro Quartal0 0 1 1,4,7,10 *
einmal im Jahr, 1. Januar0 0 1 1 *
alle 10 Minuten während der Arbeitszeit*/10 9-18 * * 1-5

Eine vollständige Zeile besteht aus dem Zeitplan und dem Befehl:

# Datenbank-Backup jede Nacht um 3:00
0 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1

# sonntags Temporärdateien löschen, die älter als 7 Tage sind
0 4 * * 0 /usr/bin/find /tmp/app -type f -mtime +7 -delete

# Website alle 5 Minuten prüfen
*/5 * * * * /usr/bin/curl -fsS https://example.com/health > /dev/null || /usr/local/bin/alert.sh

Spezielle Zeilen @reboot, @daily und andere

Statt fünf Feldern können Sie ein kurzes Synonym schreiben:

SynonymEntspricht
@rebooteinmal beim Start des Dienstes cron (nach dem Booten)
@hourly0 * * * *
@daily / @midnight0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly / @annually0 0 1 1 *
@reboot /home/alice/bin/start-tunnel.sh >> /home/alice/tunnel.log 2>&1

Für Dienste, die dauerhaft laufen und nach einem Absturz neu starten sollen, ist @reboot eine schwache Lösung: Besser ist eine Unit-Datei in systemd mit Restart=on-failure.

Wie Sie eine Aufgabe alle N Sekunden starten

Die kleinste Einheit von cron ist eine Minute. Wenn Sie häufiger starten müssen, gibt es zwei Vorgehensweisen. Die erste sind mehrere Zeilen mit einem Versatz über sleep:

* * * * * /opt/check.sh
* * * * * sleep 30; /opt/check.sh

Die zweite, korrektere Lösung ist ein systemd-Timer mit OnUnitActiveSec=30s. Läuft eine Aufgabe öfter als einmal pro Minute, ist meist ein Dienst oder ein Timer die richtige Wahl, nicht cron.

Systemweite Tabelle: /etc/crontab und /etc/cron.d

Neben den Tabellen der Benutzer gibt es systemweite. Ihr Format unterscheidet sich: Zwischen Zeit und Befehl steht der Benutzername, unter dem der Befehl läuft.

# /etc/cron.d/certbot-renew
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root certbot renew --quiet

Was wo liegt:

  • /etc/crontab — die zentrale systemweite Tabelle; unter Debian/Ubuntu starten von ihr aus die unten genannten Verzeichnisse.
  • /etc/cron.d/ — einzelne Dateien mit Aufgaben, praktisch zum Ablegen durch Pakete oder mit Ansible.
  • /etc/cron.hourly/, cron.daily/, cron.weekly/, cron.monthly/ — hier liegen ausführbare Skripte ohne eigenen Zeitplan; sie werden von run-parts (oder anacron) gestartet.

Eine Falle bei run-parts: Unter Debian und Ubuntu überspringt es Dateien, deren Name einen Punkt enthält. Das Skript backup.sh in /etc/cron.daily/ läuft deshalb nicht — nennen Sie es backup. Welche Dateien ausgeführt würden, prüfen Sie mit run-parts --test /etc/cron.daily.

Dateien in /etc/cron.d/ müssen dem Benutzer root gehören, dürfen für die Gruppe und andere nicht beschreibbar sein und mit einem Zeilenumbruch enden — sonst ignoriert cron sie.

Umgebung von cron: PATH, SHELL und Variablen

Der häufigste Grund für den Satz „im Terminal funktioniert es, in cron nicht“ ist die Umgebung. Cron startet Befehle über /bin/sh, ohne Ihre .bashrc und .profile, mit einem minimalen PATH (meist /usr/bin:/bin). Deshalb können docker, node oder php aus /usr/local/bin schlicht nicht gefunden werden.

Variablen können Sie am Anfang der Tabelle setzen:

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com
CRON_TZ=Europe/Moscow

0 6 * * * cd /srv/app && ./report.sh
  • MAILTO — wohin die Ausgabe einer Aufgabe geschickt wird; MAILTO="" schaltet E-Mails ab.
  • CRON_TZ — Zeitzone für den Zeitplan (wird von cronie in RHEL/Fedora unterstützt; in der Debian-Version von cron funktioniert diese Variable nicht).
  • Ersetzungen wie $HOME/bin in Werten der Variablen gibt es nicht — schreiben Sie Pfade vollständig aus.

Am zuverlässigsten ist es, in der Aufgabe absolute Pfade zu allen Programmen und Dateien anzugeben und in Skripten als erste Zeile einen Shebang zu setzen: #!/bin/bash.

Wo Sie die cron-Logs finden

Cron schreibt in das Journal die Tatsache, dass eine Aufgabe gestartet wurde, nicht aber deren Ausgabe:

# Debian/Ubuntu
grep CRON /var/log/syslog
# über das systemd-Journal
journalctl -u cron --since today      # Debian/Ubuntu
journalctl -u crond --since today     # RHEL, Fedora, Rocky
# RHEL ohne journald
tail -f /var/log/cron

Eine Startzeile sieht etwa so aus:

Oct 14 03:00:01 web1 CRON[21544]: (root) CMD (/usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1)

Um zu sehen, was die Aufgabe ausgegeben hat und mit welchem Fehler sie abbrach, leiten Sie sowohl stdout als auch stderr in eine Datei um: >> /var/log/job.log 2>&1. Ohne das geht die Ausgabe per Mail über den lokalen Mailer, und ist kein Mail-Agent installiert, geht sie verloren (im Journal erscheint dann No MTA installed, discarding output).

Warum cron eine Aufgabe nicht startet: typische Fehler

Befehl nicht gefunden

Symptom: im Protokoll der Aufgabe steht command not found. Ursache ist der eingeschränkte PATH. Lösung: der vollständige Pfad zum Programm (which docker zeigt ihn) oder eine Zeile PATH= am Anfang der Tabelle.

Prozentzeichen im Befehl

In crontab bedeutet das Zeichen % einen Zeilenumbruch: Alles nach dem ersten % wird dem Befehl über die Standardeingabe übergeben. Deshalb bricht die klassische Zeile mit einem Datum im Dateinamen ab:

# falsch — der Befehl wird am ersten % abgeschnitten
0 2 * * * tar czf /backup/site-$(date +%F).tar.gz /var/www
# richtig — mit Backslash maskieren
0 2 * * * tar czf /backup/site-$(date +\%F).tar.gz /var/www

Noch einfacher ist es, die Logik in ein Skript auszulagern, in dem % nicht maskiert werden muss.

Skript nicht ausführbar oder mit falschen Zeilenumbrüchen

Der Fehler Permission denied bedeutet, dass die Datei kein Ausführungsrecht x hat: Führen Sie chmod +x script.sh aus oder starten Sie explizit mit /bin/bash /opt/script.sh. Wurde das Skript unter Windows geschrieben, verursachen die Zeilenenden CRLF einen seltsamen Fehler /bin/bash^M: bad interpreter — behoben wird das mit sed -i 's/\r$//' script.sh oder dos2unix.

Relative Pfade und Arbeitsverzeichnis

Eine Aufgabe startet im Home-Verzeichnis des Benutzers. Liest das Skript ./config.ini, sucht es die Datei in ~. Setzen Sie vor dem Befehl cd /srv/app && oder verwenden Sie im Skript absolute Pfade.

Tag des Monats und Wochentag gleichzeitig

Sind beide Felder gesetzt, startet cron, sobald eines davon zutrifft, nicht beide zugleich. Die Zeile 0 9 13 * 5 läuft am 13. des Monats und jeden Freitag, nicht nur an einem Freitag, der der 13. ist. Die gewünschte Bedingung prüfen Sie innerhalb des Befehls:

0 9 13 * * [ "$(date +\%u)" = 5 ] && /opt/friday13.sh

Aufgaben überlappen sich

Dauert ein Backup länger als das Intervall, startet der nächste Lauf über den laufenden. Schutz bietet eine Sperre mit flock:

*/10 * * * * /usr/bin/flock -n /tmp/sync.lock /opt/sync.sh

Mit der Option -n beendet sich eine zweite Instanz sofort, wenn die erste noch läuft.

Der Dienst cron läuft nicht

Prüfen Sie systemctl status cron (in RHEL heißt der Dienst crond). In minimalen Images, etwa in Docker-Containern, gibt es den Dienst cron gar nicht — die Aufgaben in crontab werden dort schlicht von niemandem ausgeführt.

So debuggen Sie eine cron-Aufgabe

Starten Sie den Befehl in einer Umgebung, die cron möglichst ähnlich ist:

env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=$HOME /bin/sh -c '/opt/backup.sh'

Tritt hier ein Fehler auf, erscheint er auch in cron. Stellen Sie den Zeitplan vorübergehend auf * * * * *, leiten Sie die Ausgabe in eine Datei um und verfolgen Sie sie mit tail -f. Für die Prüfung des Zeitplans selbst helfen Online-Rechner für cron-Ausdrücke, das letzte Wort hat jedoch das Systemprotokoll.

Wer darf cron nutzen: cron.allow und cron.deny

Den Zugriff regeln die Dateien /etc/cron.allow und /etc/cron.deny. Existiert cron.allow, dürfen nur die darin genannten Benutzer eine crontab haben. Fehlt sie, aber cron.deny ist vorhanden, dürfen alle außer den genannten. Ein gesperrter Benutzer erhält bei crontab -e die Meldung You (bob) are not allowed to use this program.

Fazit

Eine Crontab besteht aus Zeilen mit fünf Zeitfeldern und dem Befehl: */5 * * * * — alle 5 Minuten, 0 3 * * * — jede Nacht, 0 9 * * 1-5 — werktags. Bearbeiten Sie die Tabelle mit crontab -e, verwenden Sie absolute Pfade, maskieren Sie %, schreiben Sie die Ausgabe in ein Protokoll und schützen Sie lange Aufgaben mit flock. Mit den hier gezeigten Beispielen lassen sich die meisten Serveraufgaben abdecken; Automatisierung und Aufgabenplanung werden im Kurs zu Linux praxisnah behandelt.

Häufige Fragen

Worin unterscheidet sich cron von anacron?

Cron startet Aufgaben zur genauen Zeit und überspringt sie, wenn der Rechner zu diesem Zeitpunkt ausgeschaltet war. Anacron sorgt dafür, dass tägliche, wöchentliche und monatliche Aufgaben nach dem Einschalten nachgeholt werden, deshalb eignet es sich für Notebooks und Desktops.

Was ist besser: cron oder systemd-Timer?

Cron ist einfacher und gibt es praktisch überall. systemd-Timer liefern Logs über journalctl, Abhängigkeiten, Ressourcenbegrenzung und die Option Persistent=true für verpasste Läufe, deshalb werden sie auf modernen Servern für wichtige Aufgaben immer häufiger gewählt.

Wo liegt die crontab eines Benutzers physisch?

Unter Debian und Ubuntu in /var/spool/cron/crontabs/name, unter RHEL und Fedora in /var/spool/cron/name. Diese Dateien sollten Sie nicht direkt bearbeiten, verwenden Sie crontab -e.

Wie deaktiviere ich eine Aufgabe in crontab vorübergehend?

Setzen Sie der Zeile über crontab -e ein # voran. Um alle Aufgaben eines Benutzers zu deaktivieren, speichern Sie die Tabelle mit crontab -l in einer Datei und entfernen Sie sie anschließend mit crontab -r.

Wie starte ich eine Aufgabe am letzten Tag des Monats?

Dafür gibt es kein eigenes Feld. Lassen Sie die Aufgabe an den Tagen 28 bis 31 laufen und prüfen Sie, ob morgen der 1. ist: 0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && /opt/job.sh.

Das Thema im Video lernen

Dieses Thema wird im Kurs „Linux: с нуля до уверенного администрирования“ ausführlich mit Praxis behandelt.

Zum Kurs