Kurztipp: Cronjob-Debugging
Die Tage hatte ich das Problem, dass ein selbst geschriebenes Skript, welches Festplatten-Temperaturen überwacht und an Icinga reportet, als Cronjob nicht funktioniert. Manuell aufgerufen funktionierte es einwandfrei:
1# check_hddtemp.sh /dev/sda
2OK: /dev/sda has a temperature of 32 degrees celsius (thresholds 40/50)
Per Cronjob meldete mir Icinga leider andere Werte:
1CRITICAL: hddtemp had a error - check hard drive name (/dev/sda)!
Um Cronjobs zu debuggen, empfiehlt es sich erstmal, das Log-Level des Cron-Dienstes zu erhöhen. Unter Debian muss dazu die Datei /etc/default/cron editiert werden:
1# vi /etc/default/cron
2...
3# Extra options for cron, see cron(8)
4# For example, set a higher log level to audit cron's work
5# EXTRA_OPTS="-L 2"
6EXTRA_OPTS="-L 2"
Nachdem die Änderungen übernommen wurden, wird der Dienst neu gestartet:
1# service cron restart
Im Log sollte man jetzt sehen, wann welche Skripte ausgeführt werden:
1# tail -f /var/log/syslog
2...
313:00:01 /USR/SBIN/CRON[5047]: (root) CMD (bash /opt/icinga_inventory.sh)
413:00:16 /USR/SBIN/CRON[5045]: (root) END (bash /opt/icinga_inventory.sh)
Das Skript wird also ausgeführt und läuft 15 Sekunden - also schon mal kein abgebrochenes Programm aufgrund fehlender Rechte oder dergleichen.
Cronjobs werden in aller Regel ohne Umgebungsvariablen und leerer PATH-Variable gestartet. Was passiert, wenn das Skript ohne Umgebungsvariablen und leerer PATH-Variable gestartet wird?
1# PATH="" ./check_hddtemp.sh /dev/sda
2./check_hddtemp.sh: 37: cut: not found
3./check_hddtemp.sh: 37: sed: not found
4
5# PATH="/bin:/usr/bin" ./check_hddtemp.sh /dev/sda
6OK: /dev/sda has a temperature of 32 degrees celsius (thresholds 40/50)
Schau an - da haben wir doch schon die Problemursache! Jetzt kann man entweder das Skript um absolute Pfade erweitern oder der crontab eine PATH-Variable mitgeben. Absolute Pfade in Skripten sind nicht immer die beste Lösung, wenn das Skript auch auf anderen Rechnern lauffähig sein soll. Hier könnten sich die Pfade ändern, was wieder Modifikationen am Skript bedeuten würde (hier ist das zwar nicht so schlimm, weil Standard-Tools im Skript verwendet werden, geht aber ums Prinzip. 😛). Schöner ist es, das Ganze per PATH-Variable zu steuern:
1# crontab -e
2...
3PATH="/bin:/usr/bin"
4...
Und siehe da, seitdem geht das Festplatten-Temperaturmonitoring auch per Cron. 🙂