Cron Jobs & Automatisierung
Cron Jobs & Automatisierung
Cron ist der Standard-Scheduler unter Linux, um Aufgaben zeitgesteuert auszuführen. Dieses Guide erklärt alles von einfachen Cronjobs bis zu komplexen Automatisierungen.
Grundkonzept
Cron führt Befehle zu festgelegten Zeiten aus:
- Cron-Daemon (crond) läuft im Hintergrund
- Crontab ist die Konfigurationsdatei für Jobs
- Jeder User kann seine eigene Crontab haben
- System-weite Crontabs in /etc/cron.d/
Crontab-Syntax
┌───────────── Minute (0-59)
│ ┌───────────── Stunde (0-23)
│ │ ┌───────────── Tag des Monats (1-31)
│ │ │ ┌───────────── Monat (1-12)
│ │ │ │ ┌───────────── Wochentag (0-7, 0 und 7 = Sonntag)
│ │ │ │ │
* * * * * Befehl
Sonderzeichen
| Zeichen | Bedeutung | Beispiel |
|---|---|---|
* |
Jeder Wert | * * * * * = jede Minute |
, |
Liste | 1,15,30 = Minute 1, 15 und 30 |
- |
Bereich | 1-5 = Montag bis Freitag |
/ |
Intervall | */15 = alle 15 Einheiten |
Beispiele
# Jede Minute
* * * * * /script.sh
# Jede Stunde (Minute 0)
0 * * * * /script.sh
# Täglich um 3:00 Uhr
0 3 * * * /script.sh
# Jeden Montag um 9:00 Uhr
0 9 * * 1 /script.sh
# Alle 15 Minuten
*/15 * * * * /script.sh
# Alle 2 Stunden
0 */2 * * * /script.sh
# Werktags um 8:30 Uhr
30 8 * * 1-5 /script.sh
# Am 1. jeden Monats um Mitternacht
0 0 1 * * /script.sh
# Jeden Sonntag um 2:00 Uhr
0 2 * * 0 /script.sh
# Zweimal täglich (8:00 und 20:00)
0 8,20 * * * /script.sh
# Alle 5 Minuten zwischen 9-17 Uhr
*/5 9-17 * * * /script.sh
Spezielle Strings
@reboot # Einmal beim Systemstart
@yearly # Jährlich (0 0 1 1 *)
@monthly # Monatlich (0 0 1 * *)
@weekly # Wöchentlich (0 0 * * 0)
@daily # Täglich (0 0 * * *)
@hourly # Stündlich (0 * * * *)
Crontab verwalten
Crontab bearbeiten
# Eigene Crontab bearbeiten
crontab -e
# Crontab eines anderen Users (als root)
sudo crontab -e -u username
Crontab anzeigen
# Eigene Crontab
crontab -l
# Eines anderen Users
sudo crontab -l -u username
Crontab löschen
# Eigene Crontab löschen
crontab -r
# Mit Bestätigung
crontab -i -r
System-Crontabs
/etc/crontab
Systemweite Crontab mit User-Angabe:
# m h dom mon dow user command
0 3 * * * root /usr/local/bin/backup.sh
/etc/cron.d/
Einzelne Dateien für verschiedene Jobs:
# /etc/cron.d/backup
0 3 * * * root /usr/local/bin/backup.sh
Periodische Verzeichnisse
Scripts in diesen Ordnern werden automatisch ausgeführt:
- /etc/cron.hourly/ - Stündlich
- /etc/cron.daily/ - Täglich
- /etc/cron.weekly/ - Wöchentlich
- /etc/cron.monthly/ - Monatlich
# Script muss ausführbar sein!
sudo chmod +x /etc/cron.daily/mein-script
Umgebungsvariablen
Cron hat eine minimale Umgebung! Setze Variablen am Anfang der Crontab:
# In crontab:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
# Jobs folgen...
0 3 * * * /backup.sh
Wichtig bei Scripts
# Im Script absolute Pfade verwenden!
#!/bin/bash
/usr/bin/mysqldump -u root database > /backup/db.sql
/usr/bin/gzip /backup/db.sql
Oder PATH im Script setzen:
#!/bin/bash
export PATH=/usr/local/bin:/usr/bin:/bin
# ...
Output & Logging
Email-Benachrichtigung
# An bestimmte Adresse
MAILTO=admin@example.com
0 3 * * * /backup.sh
# Keine Emails
MAILTO=""
0 3 * * * /backup.sh
Output umleiten
# Stdout in Datei
0 3 * * * /backup.sh >> /var/log/backup.log 2>&1
# Stdout verwerfen, nur Fehler
0 3 * * * /backup.sh > /dev/null
# Alles verwerfen
0 3 * * * /backup.sh > /dev/null 2>&1
# Mit Timestamp loggen
0 3 * * * /backup.sh >> /var/log/backup.log 2>&1
Eigenes Logging im Script
#!/bin/bash
LOG=/var/log/backup.log
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG
}
log "Backup gestartet"
# ... Backup-Befehle ...
log "Backup beendet"
Cron-Alternativen
Systemd-Timer
Moderne Alternative zu Cron:
# /etc/systemd/system/backup.timer
[Unit]
Description=Tägliches Backup
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# Timer aktivieren
sudo systemctl enable --now backup.timer
# Timer anzeigen
systemctl list-timers
Anacron
Für Rechner, die nicht 24/7 laufen:
# /etc/anacrontab
# period delay identifier command
1 5 backup /usr/local/bin/backup.sh
7 10 weekly-task /usr/local/bin/weekly.sh
at (einmalige Ausführung)
# In 5 Minuten
echo "/script.sh" | at now + 5 minutes
# Zu bestimmter Zeit
at 15:30
> /script.sh
> Ctrl+D
# Jobs anzeigen
atq
# Job löschen
atrm 5
Praktische Beispiele
Tägliches Backup
# Crontab-Eintrag
0 3 * * * /home/user/scripts/backup.sh >> /var/log/backup.log 2>&1
#!/bin/bash
# /home/user/scripts/backup.sh
BACKUP_DIR=/backup/$(date +%Y-%m-%d)
mkdir -p $BACKUP_DIR
# Dateien sichern
tar -czf $BACKUP_DIR/home.tar.gz /home/
# Datenbank sichern
mysqldump -u root --all-databases > $BACKUP_DIR/mysql.sql
# Alte Backups löschen (älter als 7 Tage)
find /backup -type d -mtime +7 -exec rm -rf {} \;
Log-Rotation
# Täglich um 0:00
0 0 * * * /usr/sbin/logrotate /etc/logrotate.conf
Systemüberwachung
# Alle 5 Minuten Festplatte prüfen
*/5 * * * * /home/user/scripts/check-disk.sh
#!/bin/bash
# /home/user/scripts/check-disk.sh
THRESHOLD=90
USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $USAGE -gt $THRESHOLD ]; then
echo "Warnung: Festplatte zu $(USAGE)% voll!" | \
mail -s "Disk Alert" admin@example.com
fi
SSL-Zertifikate erneuern
# Zweimal täglich (Let's Encrypt empfiehlt das)
0 0,12 * * * certbot renew --quiet
System-Updates (vorsichtig!)
# Wöchentlich Security-Updates (Debian/Ubuntu)
0 4 * * 0 apt update && apt upgrade -y -o Dpkg::Options::="--force-confold"
Troubleshooting
Cronjob läuft nicht?
- Cron-Daemon läuft?
systemctl status cron
# oder
systemctl status crond
- Syntax prüfen
# Online-Tool: crontab.guru
- Berechtigungen
# Script ausführbar?
chmod +x /path/to/script.sh
# Cron-Zugriff erlaubt?
cat /etc/cron.allow
cat /etc/cron.deny
- Logs prüfen
# Cron-Logs
grep CRON /var/log/syslog
# oder
journalctl -u cron
- Manuell testen
# Als der User, der den Cronjob hat
/bin/bash -c "/pfad/zum/script.sh"
- Umgebung prüfen
# Cron hat minimale Umgebung!
# Im Script testen:
env > /tmp/cron-env.txt
Häufige Fehler
| Problem | Lösung |
|---|---|
| Script läuft manuell, aber nicht in Cron | Absolute Pfade verwenden |
| Keine Ausgabe | Output umleiten, MAILTO setzen |
| "Permission denied" | chmod +x script.sh |
| Falsche Zeit | Zeitzone prüfen, timedatectl |
| Script hängt | Timeout setzen: timeout 3600 /script.sh |
Best Practices
- Absolute Pfade überall verwenden
- Logging einbauen für Debugging
- Fehlerbehandlung im Script
- Locking um parallele Ausführung zu verhindern:
#!/bin/bash
LOCKFILE=/tmp/myscript.lock
if [ -f $LOCKFILE ]; then
echo "Script läuft bereits"
exit 1
fi
trap "rm -f $LOCKFILE" EXIT
touch $LOCKFILE
# ... Script ...
- Timeout setzen für lang laufende Jobs
- Testen vor dem Einsatz in Cron
- Dokumentieren was jeder Cronjob macht