Zum Inhalt springen
sw
en

Tippe um zu suchen

Linux

Cron Jobs – Automatisierung unter Linux

Cron ist der Standard-Aufgabenplaner unter Linux. Lerne Syntax, Praxisbeispiele, Logging und Troubleshooting für den IT-Allrounder-Alltag.

9 Min Lesezeit Fortgeschritten Zuletzt aktualisiert:

Was ist Cron?

Cron ist der klassische Aufgabenplaner unter Linux – das Gegenstück zum Windows Task Scheduler. Er wird als Daemon (crond bzw. cron) im Hintergrund ausgeführt und prüft jede Minute, ob ein geplanter Job ausgeführt werden muss.

Typische Anwendungsfälle in einem KMU:

  • Nächtliche Backups auf NAS oder Cloud
  • Log-Rotation und Bereinigung alter Dateien
  • Überwachungsskripte (Festplattenplatz, Dienste prüfen)
  • Berichte automatisch generieren und per Mail verschicken
  • Datenbank-Dumps vor Updates
  • Zertifikate erneuern (z.B. Let’s Encrypt via Certbot)

Cron ist auf praktisch jeder Linux-Distribution vorinstalliert. Auf modernen Systemen gibt es daneben auch systemd-Timer als Alternative – aber Cron ist einfacher, breiter bekannt und für die meisten Aufgaben mehr als ausreichend.


Crontab bearbeiten

Jeder Linux-User hat seine eigene Crontab (Cron-Tabelle). Die zentrale Anlaufstelle ist der Befehl crontab:

crontab -e      # Eigene Crontab im Editor öffnen (erstellt sie, falls nicht vorhanden)
crontab -l      # Aktuelle Crontab anzeigen
crontab -r      # Eigene Crontab löschen (Vorsicht – ohne Rückfrage!)
sudo crontab -e # Root-Crontab bearbeiten
crontab -u seya -l  # Crontab eines bestimmten Users anzeigen (als Root)

Beim ersten Aufruf von crontab -e wirst du nach einem Editor gefragt. nano ist für Einsteiger am bequemsten.


Die Crontab-Syntax

Der wichtigste Teil: Das Zeitformat. Jede Zeile in der Crontab hat diese Struktur:

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

Sonderzeichen

ZeichenBedeutungBeispiel
*Jeder Wert* * * * * = jede Minute
*/nAlle n Einheiten*/15 = alle 15 Minuten
n-mBereich8-17 = 08:00 bis 17:00
n,m,kListe1,15,30 = um Minute 1, 15 und 30

Praktische Beispiele

# Täglich um 02:00 Uhr Backup-Skript ausführen
0 2 * * * /opt/scripts/backup.sh

# Jeden Montag um 08:00 Wochenbericht erstellen
0 8 * * 1 /opt/scripts/wochenbericht.sh

# Alle 5 Minuten einen Monitoring-Check
*/5 * * * * /opt/scripts/check-dienste.sh

# Stündlich (immer zur vollen Stunde)
0 * * * * /opt/scripts/cleanup-tmp.sh

# Jeden Werktag (Mo–Fr) um 07:30
30 7 * * 1-5 /opt/scripts/tageskonfiguration.sh

# Am 1. jeden Monats um 03:00
0 3 1 * * /opt/scripts/monatsbericht.sh

# Jeden Sonntag um 22:00 den Server neu starten
0 22 * * 0 /sbin/reboot

# Beim Systemstart (nach Reboot)
@reboot /opt/scripts/startup.sh

Kurzformen mit @

Cron kennt auch sprechende Kurzformen:

KurzformEntsprichtBedeutung
@rebootEinmal beim Systemstart
@hourly0 * * * *Jede Stunde
@daily / @midnight0 0 * * *Täglich um Mitternacht
@weekly0 0 * * 0Wöchentlich, Sonntag Mitternacht
@monthly0 0 1 * *Monatlich, 1. des Monats
@yearly / @annually0 0 1 1 *Jährlich, 1. Januar

Systemweite Cron-Verzeichnisse

Neben den persönlichen Crontabs gibt es systemweite Verzeichnisse. Skripte, die du dort ablegst, werden automatisch zur entsprechenden Zeit ausgeführt – ohne expliziten Cron-Eintrag:

/etc/cron.hourly/    # Stündlich
/etc/cron.daily/     # Täglich
/etc/cron.weekly/    # Wöchentlich
/etc/cron.monthly/   # Monatlich

Skripte in diesen Verzeichnissen brauchen keinen Shebang-Zeitplan, müssen aber ausführbar sein:

# Skript ablegen und ausführbar machen
sudo cp mein-cleanup.sh /etc/cron.daily/
sudo chmod +x /etc/cron.daily/mein-cleanup.sh

Die systemweite Crontab /etc/crontab hat eine zusätzliche Spalte für den ausführenden User:

# /etc/crontab – Systemweite Crontab
# m  h  dom  mon  dow  user     command
  0  2  *    *    *    root     /opt/scripts/backup.sh
  30 6  *    *    1-5  deploy   /opt/app/deploy-check.sh

Output, Logging und Mail

Standardmässig sendet Cron die Ausgabe jedes Jobs per E-Mail an den ausführenden User – was auf Servern ohne Mail-Daemon zu Fehlern führt. Besser: Output explizit umleiten.

# Ausgabe (stdout + stderr) in Logdatei schreiben
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

# Fehler separat loggen
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>> /var/log/backup-errors.log

# Komplett unterdrücken (nur wenn du sicher bist, dass nichts schiefgeht)
0 2 * * * /opt/scripts/backup.sh > /dev/null 2>&1

MAILTO: Mail-Benachrichtigungen steuern

Am Anfang der Crontab kannst du das Verhalten für alle Jobs steuern:

# Alle Mails unterdrücken
MAILTO=""

# Mails an eine bestimmte Adresse senden
MAILTO="admin@firma.ch"

Umgebungsvariablen in Cron

Das ist der häufigste Stolperstein: Cron startet Jobs mit einer minimalen Umgebung. Deine ~/.bashrc oder ~/.profile wird nicht geladen. Das bedeutet:

  • PATH ist auf /usr/bin:/bin beschränkt
  • Keine eigenen Aliases oder Funktionen
  • Keine Umgebungsvariablen aus deiner Shell-Konfiguration

Lösung 1: Absolute Pfade in jedem Job verwenden:

# Schlecht (findet python3 eventuell nicht)
*/5 * * * * python3 /opt/scripts/check.py

# Gut (absoluter Pfad)
*/5 * * * * /usr/bin/python3 /opt/scripts/check.py

Lösung 2: PATH und Variablen am Anfang der Crontab definieren:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=de_CH.UTF-8
HOME=/home/seya

# Jetzt greifen die Variablen für alle nachfolgenden Jobs
0 2 * * * backup.sh

Lösung 3: Im Skript selbst auf die richtige Umgebung laden:

#!/bin/bash
source /home/seya/.profile
# ... Rest des Skripts

Praxisbeispiel: Backup-Skript mit Cron

Ein typisches Szenario: Täglich um 02:30 Uhr wichtige Verzeichnisse auf ein Netzwerklaufwerk sichern und alte Backups bereinigen.

#!/bin/bash
# /opt/scripts/backup-daily.sh

DATUM=$(date +%Y-%m-%d)
BACKUP_QUELLE="/var/www /etc /home/seya"
BACKUP_ZIEL="/mnt/nas/backups"
LOG="/var/log/backup-daily.log"

echo "=== Backup gestartet: $(date) ===" >> "$LOG"

for QUELLE in $BACKUP_QUELLE; do
    ZIEL="$BACKUP_ZIEL/$(basename $QUELLE)-$DATUM.tar.gz"
    tar -czf "$ZIEL" "$QUELLE" 2>> "$LOG"
    if [ $? -eq 0 ]; then
        echo "OK: $QUELLE -> $ZIEL" >> "$LOG"
    else
        echo "FEHLER: $QUELLE konnte nicht gesichert werden!" >> "$LOG"
    fi
done

# Backups aelter als 30 Tage loeschen
find "$BACKUP_ZIEL" -name "*.tar.gz" -mtime +30 -delete
echo "Alte Backups bereinigt." >> "$LOG"

echo "=== Backup beendet: $(date) ===" >> "$LOG"

Crontab-Eintrag dazu:

30 2 * * * /opt/scripts/backup-daily.sh

Skript ausführbar machen:

chmod +x /opt/scripts/backup-daily.sh

Praxisbeispiel: Festplattenplatz überwachen

#!/bin/bash
# /opt/scripts/check-disk.sh
# Warnung per Mail wenn Festplatte ueber 80% voll

SCHWELLWERT=80
EMPFAENGER="admin@firma.ch"

df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1}' | while read AUSLASTUNG FS; do
    PROZENT=${AUSLASTUNG%%%}
    if [ "$PROZENT" -ge "$SCHWELLWERT" ]; then
        echo "WARNUNG: $FS ist zu ${AUSLASTUNG} voll!" | mail -s "Festplatten-Warnung auf $(hostname)" "$EMPFAENGER"
    fi
done
# Alle 30 Minuten prüfen
*/30 * * * * /opt/scripts/check-disk.sh

Anacron: Für Systeme, die nicht immer laufen

Cron hat ein Problem: Wenn der Rechner zum geplanten Zeitpunkt ausgeschaltet war, wird der Job einfach übersprungen. Für Notebooks oder Server mit Wartungsfenstern gibt es Anacron.

Anacron prüft nicht die Uhrzeit, sondern wie lange ein Job zuletzt ausgeführt wurde. Wenn er zu lange nicht gelaufen ist, holt er ihn beim nächsten Start nach.

# /etc/anacrontab
# Periode  Verzögerung  Job-ID           Befehl
1          5            cron.daily       run-parts /etc/cron.daily
7          10           cron.weekly      run-parts /etc/cron.weekly
@monthly   15           cron.monthly     run-parts /etc/cron.monthly
  • Periode: Tage zwischen den Ausführungen
  • Verzögerung: Minuten Wartezeit nach Systemstart (verhindert, dass alle Jobs gleichzeitig starten)
  • Job-ID: Eindeutiger Name für die Timestamp-Datei

Anacron ist auf Ubuntu/Debian standardmässig installiert und kümmert sich automatisch um /etc/cron.daily, /etc/cron.weekly und /etc/cron.monthly.


Troubleshooting

Cron-Job läuft nicht – Checkliste

1. Ist cron überhaupt aktiv?

systemctl status cron    # Debian/Ubuntu
systemctl status crond   # RHEL/CentOS/Fedora

2. Cron-Logs einsehen

# Systemd-basierte Systeme
journalctl -u cron --since "1 hour ago"
journalctl -u cron | grep CRON

# Ältere Systeme (syslog)
grep CRON /var/log/syslog
grep CRON /var/log/cron

3. Skript manuell als gleicher User testen

# Genau so wie Cron es ausführen würde (minimale Umgebung)
env -i HOME=/home/seya /bin/bash /opt/scripts/mein-job.sh

4. Ausführbarkeit prüfen

ls -la /opt/scripts/mein-job.sh
# rwxr-xr-x muss gesetzt sein
chmod +x /opt/scripts/mein-job.sh

5. Shebang korrekt?

# Erste Zeile des Skripts muss sein:
#!/bin/bash
# oder
#!/usr/bin/env bash

6. Absolute Pfade verwenden?

Schau im Skript nach: Alle Befehle wie rsync, python3, mysqldump etc. mit vollem Pfad (/usr/bin/rsync) angeben oder PATH in der Crontab setzen.

Häufige Fehler

ProblemUrsacheLösung
Job startet nieFehlende ausführbare Rechtechmod +x skript.sh
command not foundPATH zu kurzAbsolute Pfade verwenden
Skript funktioniert manuell, nicht via CronUmgebungsvariablen fehlensource ~/.profile im Skript oder Vars in Crontab
Datum/Uhrzeit falschZeitzone des Serverstimedatectl prüfen, /etc/timezone
Jobs überlappen sichSkript läuft länger als IntervallLockfile-Mechanismus einbauen
% im Befehl zerschiesst JobSonderbedeutung in CrontabMit \% escapen oder in Skript auslagern

Cron vs. systemd-Timer

Seit systemd auf praktisch allen modernen Distributionen Standard ist, gibt es eine Alternative zu Cron: systemd-Timer. Hier ein kurzer Vergleich:

MerkmalCronsystemd-Timer
EinfachheitSehr simpel, eine ZeileZwei Dateien nötig (.service + .timer)
LoggingEigenes Logfile nötigAutomatisch in journald
AbhängigkeitenKeineKann auf andere Units warten
Missed JobsWerden übersprungenKönnen nachgeholt werden (Persistent=true)
VerbreitungÜberall vorhandenNur auf systemd-Systemen

Für einfache, regelmässige Tasks ist Cron nach wie vor die erste Wahl. Für komplexere Anforderungen (Abhängigkeiten, detailliertes Logging, Retries) lohnt sich ein Blick auf systemd-Timer.

Mehr zu Linux-Grundbefehlen findest du unter Linux – Grundbefehle, SSH-Automatisierung unter SSH – Grundlagen.


Weiterlernen

Kommentare

Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.

  • Lade Kommentare …
Kommentar schreiben