Cron
Um unter Linux regelmäßig wiederkehrende Aufgaben ausführen zu lassen, kann man sich Crons bedienen. Cron besteht aus zwei Teilen, dem Cron-Daemon, der für das automatische Starten der definierten Programme, bzw. für das Ausführen der Befehle zuständig ist, und der Crontab, in der die Programm- und Befehlsaufrufe (die so genannten Cronjobs) definiert werden.
Installation
Es gibt viele cron-Implementierungen, aber keine von ihnen wird standardmäßig installiert, da das Basissystem systemd Timer nutzt.
Pakete in den offiziellen Repositories:
Pakete im AUR:
- bcronAUR
- dcronAUR
- vixie-cronAUR
Konfiguration
Damit cronie beim Systemstart geladen wird, muss der entsprechende Service nach der Installation des Systems noch gestartet werden.
systemctl enable cronie # aktiviert den Service lediglich systemctl start cronie # startet den Service manuell
Die eigentliche Konfiguration findet innerhalb der Crontabs statt, so dass der Cron-Service selbst nicht weiter konfiguriert werden muss.
Crontab
In einer Crontab werden entweder systemweit oder benutzerbezogen Befehls- und Programmaufrufe definiert, die bei Eintreten der Startvoraussetzung (Zeitangabe) ausgeführt werden. Alle Ausgaben der einzelnen Cronjobs werden per System-Mail dem Benutzer zugestellt, mit dessen Rechten der Cronjob läuft.
Der Editor, mit dem die Crontab-Datei bearbeitet wird, ist standardmäßig vi. Wenn man einen anderen Editor verwenden möchte, ist dies problemlos möglich, indem man die Variablen „VISUAL“ und "EDITOR" definiert und exportiert.
In der Crontab wird je Zeile ein Cronjob definiert. Leerzeilen und Zeilen, die mit einer Raute (#) beginnen, werden ignoriert.
Ausgeführt werden Cronjobs mit der Shell „/etc/sh“. Es werden lediglich die Variablen $HOME, $USER und $SHELL gesetzt. Eigene Funktionen und Aliase werden nicht automatisch interpretiert.
Cronjobs werden immer ausgeführt, wenn der Rechner eingeschaltet ist. Der User, der den Cronjob angelegt hat, muss nicht eingeloggt sein.
Wenn der Rechner zu einem Zeitpunkt ausgeschaltet ist, der für einen Cronjob definiert wurde, wird der Cronjob mittels anacron ausgeführt. Das Programm anacron ist Bestandteil von cronie.
Zeitnotation
Jeder Cronjob besteht am Anfang der Zeile aus fünf Zeitangaben. Dies sind in dieser Reihenfolge:
- Minute
- Stunde
- Monatstag
- Monat
- Wochentag
Es können hier neben genauen Angaben auch Zeitspannen (Bindestrich) oder intervalle (Slash) angegeben werden. Wenn bezüglich des Tages mehrere Angaben gemacht werden, wird der Cronjob bei Erreichen eines der beiden Zeitpunkte ausgeführt. Als Wochentag „fri“ (für „Friday“, zu Deutsch: „Freitag“) und als Tag „13“ führt den Cronjob an jedem Freitag und am jedem Dreizehnten eines Monats aus, und nicht nur an jedem Freitag, den 13.
Einige Beispiele, auszuführen ist hier immer der Befehl „command“:
# täglich um 06:40 Morgens 40 6 * * * command # alle zwei Stunden zu Stundenbeginn 0 */2 * * * command # alle zwei Stunden zwischen 23 und 07 Uhr, sowie um 08 Uhr Morgens 0 23-7/2,8 * * * command # täglich um 08:30, 12:30 und 16:30 Uhr 30 8,12,16 * * * command # um 11 Uhr morgens am Neunten eines Monats, sowie jeden # Montag, Dienstag und Mittwoch 0 11 9 * mon-wed command # Jeden Montagmorgen um 9 Uhr 0 9 * * mon command # um 04 Uhr morgens am ersten Januar 0 4 1 jan * command
Programmpfade
In der Crontab wird standardmäßig nur ein sehr rudimentärer Pfad gesetzt. Für viele Anwendungsfälle ist das so vollkommen ausreichend. Wenn es allerdings Programme gibt, die unänderbar auf bestimmte Programme zugreifen, und sich dabei darauf verlassen, dass die Orte der Programme im Pfad stehen, kann es zu Ausfällen führen. Aus diesem Grund sollte man vor allen Ausführ-Definitionen den Pfad definieren
PATH=$PATH:/eigener/programmpfad
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/bin/perlbin/site:/usr/bin/perlbin/vendor:/usr/bin/perlbin/core:/opt/qt/bin
Im ersten Beispiel wird der cron-Standardpfad um eine eigene Definition (hier „/eigener/programmpfad“) erweitert. Pfade werden in der Pfad-Definition mittels Doppelpunkt getrennt. Im zweiten Beispiel wird der Pfad komplett durch eine eigene Definition ersetzt. Weitere Informationen über den Pfad befinden sich Wiki-Artikel Umgebungsvariablen.
E-Mail-Benachrichtigung
Standardmäßig schickt der cron-Service bei Ausgaben der Cronjobs diese als E-Mail an den Besitzer der Crontab, aus welcher heraus der Cronjob ausgeführt wurde. Dieses Verhalten kann man mit der Variablen MAILTO beeinflussen. Man kann sowohl eine Mailadresse, wie auch einen Systemuser als Empfänger angeben.
MAILTO=user@example.com * * * * * echo test
Es wird nun minütlich eine E-Mail mit der Ausgabe des Cronjobs an user@example.com geschickt, anstatt an denjenigen User, dem die Crontab gehört. Hierbei wird der im System vorhandene MTA verwendet. Wenn man also eine E-Mail an einen Nicht-Systemuser sendet, sollte man darauf achten, dass der Server vollwertig als Mailserver fungiert, oder der Empfängermailserver keine Filterung vornimmt, da eine Mail von einem praktisch unkonfigurierten MTA für gewöhnlich direkt verworfen, oder als Spam markiert wird.
Das Bearbeiten einer Crontab
Wenn man am Terminal die Crontab zum Bearbeiten öffnet, wird die Crontab nicht direkt geöffnet, sondern vom System ausgelesen, und unter einem temporären Namen abgelegt. Das System merkt sich diesen Namen und „beobachtet“ die Datei. Dann wird der eingestellte Editor mit dieser temporären Datei geöffnet. Die Crontab des Useraccounts, mit dem man aktuell arbeitet wird mittels folgenden Befehls bearbeitet.
crontab -e
Man bearbeitet nun diese temporäre Datei. Nach Bearbeiten und Speichern der Datei und dem Schließen des Editors erkennt das System, dass die Datei geändert wurde, liest sie neu ein, und schreibt die Einträge in der Datei zurück in die Crontab. Danach wird im Terminal-Fenster ein entsprechender Hinweis ausgegeben, dass die Crontab bearbeitet und neu erstellt wurde, oder eben, dass keine Änderungen an der Crontab vorgenommen wurden.
Die Crontab selbst liegt unter „/var/spool/cron/benutzername“ und sollte nicht direkt bearbeitet werden.
Arten von Crontabs
Generell gibt es zwei Arten von Crontabs: benutzerbezogene und systemweite Crontabs.
Benutzerbezogen
Um für den aktuell angemeldeten Benutzer einen Cronjob zu erstellen, bzw. die Crontab zu bearbeiten, bedient man sich des Programms „crontab“. Wenn man sich die Crontab anzeigen lassen möchte, ruft man das Programm mit dem Parameter „-l“ auf. Zum Bearbeiten der Crontab benutzt man den Parameter „-e“.
crontab -l
*/10 * * * * /home/user/.bin/checkscript.sh whattocheck 0 7 * * mon backuptool /media/target >> /home/user/backuplog 2>&1 0 8 1 12 * DISPLAY=:0 leafpad /home/user/wichtig.txt
In diesem Fall wird die Crontab des Users angezeigt. Es sind zwei Cronjobs definiert. Der erste Cronjob wird im Zehn-Minuten-Takt ausgeführt, und besteht aus dem Script „/home/user/.bin/checkscript.sh“ mit dem Parameter „whattocheck“.
Der zweite Cronjob wird jeden Montag um sieben Uhr morgens ausgeführt und ist das Programm „backuptool“ mit dem Parameter „/media/target“. Zusätzlich wird bei diesem Cronjob die Ausgabe komplett in die Datei „/home/user/backuplog“ umgeleitet.
Der dritte Cronjob wird am 01.12. um acht Uhr morgens ausgeführt. Dieser Befehl kann in einer grafischen Oberfläche (kde, gnome, xfce, lxde...) ausgeführt werden. Der Editor „leafpad“ wird benutzt, um eine Datei /home/user/wichtig.txt anzuzeigen.
Auch root verfügt über eine Crontab. In dieser Crontab befinden sich standardmäßig nur Aufrufe für weitere cron-spezifische Funktionen. Dies sollte auch nicht geändert werden, da hiermit ein Großteil der Funktionalität verloren geht, die cron ausmacht und dies teilweise auch systemkritische Folgen haben kann.
Systemweit
Es gibt neben der Crontabs noch vier Verzeichnisse, in denen Scripts abgelegt werden können, die dann vom cron-Daemon entsprechend des Verzeichnisses ausgeführt werden.
- /etc/cron.daily
- /etc/cron.hourly
- /etc/cron.monthly
- /etc/cron.weekly
Die Scripts werden automatisch mit den Rechten des Users ausgeführt, mit dem der cron-Daemon läuft, normalerweise ist dies root. Die Scripts sind ganz normale Shellscripts, wobei der Dateiname keinen Punkt enthalten darf. Wenn man also weiß, dass man einen Cronjob einmal wöchentlich ausführen muss, erstellt man ein Shellscript, und verlinkt/kopiert es nach „/etc/cron.weekly“. Der cron-Daemon kümmert sich dann um die Ausführung.
Vor- und Nachteile
Zu den Vorteilen von cron zählen die einfache Wartbarkeit, sowie die Möglichkeit, je User beliebig viele Cronjobs, die unabhängig vom Login-Status des Users laufen, definieren zu können. Durch die „/etc/cron.*“-Verzeichnisse ist es zudem sehr einfach möglich, regelmäßige Cronjobs zu erstellen.
In der Regelmäßigkeit liegt auch die Stärke von cron. Anhand der vielfältigen Kombinationsmöglichkeiten bei der Definition des Ausführzeitpunktes kann man genau einplanen, wann ein Cronjob ausgeführt werden soll. Es besteht ebenfalls die Möglichkeit, dass ein Cronjob unter gewissen Umständen nicht ausgeführt werden soll.
Es können mit cron keine einmaligen Aufgaben ausgeführt werden (beispielsweise kann man zwar definieren, dass ein Cronjob einmal im Jahr zu einem bestimmten Zeitpunkt laufen soll, nicht aber „einmalig am 14. Oktober um 13:37 Uhr – oder sobald der Computer danach wieder eingeschaltet ist, und danach nie wieder“).
Alternative Lösungen
Neben dem klassichen cron-System gibt es auch noch andere Möglichkeiten, Aufgaben zeitgesteuert zu starten.
Auf jeden Fall ausführen
Da Cronjobs nur ausgeführt werden, wenn der Computer zu dem definierten Zeitpunkt in Betrieb ist, kann es vorkommen, dass ein Cronjob nie ausgeführt wird. Wenn man zum Beispiel ein Backup auf 04 Uhr Nachts gelegt hat, aber zwischen 03:50 und 04:30 der Computer grundsätzlich nicht in Betrieb ist, wird das Backup nie ausgeführt.
Für Aufgaben, die auf jeden Fall ausgeführt werden sollen, kann man anacron verwenden, dies ist ein cron-Daemon, der etwas anders funktioniert. Statt einer genauen Zeitangabe für eine Aufgabe, wird ein Zeitraum in Tagen definiert, in dem der Befehl ein Mal ausgeführt werden muss. Wenn der Zeitraum erreicht oder überschritten wurde, wird der Befehl dann ausgeführt. Das Programm anacron ist Bestandteil von cronie.
Einmalig ausführen
Will man Befehle nur einmalig ausführen, kann man hierzu at verwenden. at ist im „Extra“-Repository verfügbar. Damit at beim Booten gestartet wird, bitte systemctl enable atd.service ausführen.
Hier definiert man einen genauen Zeitpunkt für einen Befehl, und hat dabei vielfältige Möglichkeiten bei der Angabe der Zeit.
- „now + 20 mins“ führt den Befehl in 20 Minuten aus.
- „tomorrow -20 mins“ führt den Befehl morgen zur selben Uhrzeit abzüglich 20 Minuten aus
- „tuesday 13:37“ führt den Befehl nächsten Dienstag um 13:37 Uhr aus
- „now“ führt den Befehl sofort aus
- „tomorrow noon“ führt den Befehl am nächsten Tag mittags aus