MWCodebymw.de ↗
Terminal

cron – Aufgaben, die von selbst laufen (und warum sie es oft nicht tun)

Nächtliches Backup, wöchentlicher Bericht, stündliche Bereinigung: Fünf Zahlen und ein Befehl reichen. Der häufigste Fehler ist dabei nicht die Zeitangabe, sondern eine Umgebung, die ganz anders aussieht als dein Terminal.

Jede wiederkehrende Aufgabe, die du von Hand machst, vergisst du irgendwann. cron ist auf jedem Linux-Server der einfachste Weg, das abzustellen.

crontab -e      # Aufgaben des aktuellen Nutzers bearbeiten
crontab -l      # anzeigen

Die fünf Zahlen

┌── Minute (0–59)
│ ┌── Stunde (0–23)
│ │ ┌── Tag im Monat (1–31)
│ │ │ ┌── Monat (1–12)
│ │ │ │ ┌── Wochentag (0–7, 0 und 7 = Sonntag)
│ │ │ │ │
* * * * *  befehl

Beispiele, die ich tatsächlich benutze:

0 3 * * *        /usr/local/bin/backup.sh          # täglich um 3:00
*/15 * * * *     /usr/local/bin/sync.sh            # alle 15 Minuten
0 8 * * 1        /usr/local/bin/wochenbericht.sh   # montags um 8:00
0 0 1 * *        /usr/local/bin/monatsabschluss.sh # am 1. jedes Monats

Statt der fünf Zahlen gehen auch Kurzformen: @daily, @hourly, @weekly, @reboot.

Die drei Gründe, warum es nicht läuft

Die Zeitangabe ist selten das Problem. Diese drei sind es:

1. PATH ist fast leer. Im Terminal findet die Shell php, rsync oder node, weil dein Profil den Pfad gesetzt hat. cron lädt dein Profil nicht. Deshalb: immer vollständige Pfade schreiben.

# ⚠️ findet php womöglich nicht
0 3 * * * php /var/www/wartung.php

# ✅ eindeutig
0 3 * * * /usr/bin/php /var/www/wartung.php

Welcher Pfad das ist, sagt dir which php.

2. Das Arbeitsverzeichnis ist das Heimatverzeichnis. Relative Pfade im Skript zeigen dann ins Leere. Entweder im Skript cd an den Anfang setzen oder im Eintrag:

0 3 * * * cd /var/www && /usr/bin/php wartung.php

3. Das Prozentzeichen hat eine Sonderbedeutung. In einer crontab-Zeile ist % ein Zeilenumbruch für die Eingabe des Befehls. Ein date +%Y-%m-%d bricht deshalb ab — du musst es maskieren: date +\%Y-\%m-\%d. Das kostet erfahrungsgemäß eine halbe Stunde Suche, wenn man es nicht weiß.

Ausgabe nicht verlieren

Standardmäßig schickt cron alles, was das Skript ausgibt, per Mail an den Nutzer. Auf einem Server, der kein Mailsystem hat, verschwindet es damit spurlos. Deshalb schreibe ich in eine Datei:

0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Das 2>&1 ist der entscheidende Teil: Es leitet auch die Fehlerausgabe in dieselbe Datei. Ohne das steht im Log nur, was gut lief.

Testen, ohne einen Tag zu warten

Der ehrlichste Test ist, die Umgebung von cron nachzustellen:

env -i /bin/sh -c '/usr/local/bin/backup.sh'

env -i startet ohne jede Umgebungsvariable. Läuft dein Skript so durch, läuft es auch unter cron. Läuft es nicht, hast du genau das Problem gefunden, das dich sonst erst morgen früh erreicht hätte.

Wann nicht cron?

Wenn die Aufgabe länger läuft als das Intervall, starten mehrere Durchläufe parallel. Dagegen hilft eine Sperrdatei über flock:

*/15 * * * * /usr/bin/flock -n /tmp/sync.lock /usr/local/bin/sync.sh

Das -n heißt: Läuft schon einer, überspringe diesen Durchlauf, statt zu warten.

Du hast auf deinem Server wiederkehrende Aufgaben, die du noch von Hand machst? Das ist meistens eine Stunde Arbeit und danach für immer erledigt. Schreib mir.

Quellen

#Terminal#cron#Automatisierung#Server#Backup

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →