So chaotisch Linuxer/innen auch manchmal sein mögen – meistens werkelt unbeachtet im Hintergrund ein Pünktlichkeitsfanatiker namens cron(d) auf ihren Rechnern. Ihn zu nutzen, kann eine Menge langweilige Arbeit ersparen.
Ob man seinen Rechner der MP3-Sammlung sei dank allmorgendlich als Wecker missbrauchen oder sich langweiliger, immer wiederkehrender Aufgaben bei der Systemadministration entledigen möchte – die Lösung des Problems heißt Cron, ein Dienst, der als Dämon namens cron oder crond still im Hintergrund vor sich hin werkelt.
Die Zentrale
Die zentrale Anlaufstelle, um sich der lästigen Pflichten zu entledigen, trägt den Namen /etc/crontab. Jede Minute kommt der Linux-Cron-Daemon angestolpert, um darin und in den persönlichen Crontabellen der User nachzuschauen, ob sich ein Auftrag findet, den es in dieser Minute zu erledigen gilt.
Während normalsterbliche Benutzer/innen sich des Programms crontab bedienen, das einen Editor aufruft und die syntaktische Korrektheit der Aufträge für cron überwacht, liegt die Verantwortung für die systemweite Crontabelle allein bei der Administratorin root und ihrem Lieblingseditor.
Auf den ersten Blick mag die Auftragsliste für Cron – Listing 1 zeigt ein Beispiel – etwas Erschrecken auslösen. Doch bei genauerer Betrachtung und/oder einem vergnüglichen Abend mit der ausnahmsweise auch für Nicht-Gurus gut verständlichen Manpage ( crontab) kommt man recht schnell hinter das Schema, das von Tabelle 1 erklärt wird.
Tabelle 1: Format eines Crontab-Eintrags
| Minute(n) | Stunde(n) | Tag(e) | Monat(e) | Wochentag(e) | User | auszuführender Befehl |
| mögliche Werte | ||||||
|---|---|---|---|---|---|---|
| 0–59 oder der Platzhalter *, der für alle Minuten von 0–59 steht | 0–23, * (“jede Stunde”) | 1–31, * (“jeden Tag im Monat”) | 1–12, * (“jeden Monat”), Jan–Dec oder jan–dec | 0–7, wobei sowohl 0 als auch 7 für Sonntag stehen können, * (“jeden Wochentag”), Sun–Sat oder sun–sat | nur in /etc/crontab: der Username der Benutzerin, mit deren Rechten der Befehl ausgeführt werden soll | |
Damit Cron seine Aufträge versteht, müssen sie in einem fest vorgegebenen sechs- (bei mit crontab erstellten, benutzerdefinierten Cron-Tabellen) bzw. siebenspaltigen (/etc/crontab) Tabellenformat aufgeschrieben werden. Ein Eintrag darf dabei keinen Zeilenumbruch enthalten und (in aller Regel) 1024 Zeichen nicht überschreiten.
Wer der Übersichtlichkeit wegen gern den einen oder anderen harten Zeilenumbruch einfügen will, kann das zwar tun, doch muss dann als letztes Zeichen vor dem Gebrauch der Enter-Taste ein \ stehen.
Als Spaltentrenner dienen normalerweise Leer- oder Tabulatorzeichen, und mit einem # am Anfang einer Zeile bestimmt man den Rest als wichtig für Menschen, jedoch unwichtig für Cron, also zum Kommentar.
Die systemweite Aufgabenliste für Cron in Listing 1 enthält demnach drei Aufträge: Täglich um 6.42 Uhr wird der Crondämon mit den Rechten von root das Kommando run-parts /etc/cron.daily ausführen. Jeden Sonntag (7) um 6.47 Uhr ist ein Lauf von run-parts /etc/cron.weekly fällig, und an jedem Ersten des Monats kommt fünf Minuten später (6.52 Uhr) noch ein run-parts /etc/cron.monthly hinzu.
Advanced Features
Neben den in Tabelle 1 angegebenen “einfachen” Angaben gibt es bei den unter Linux verwendeten Cron-Daemonen auch noch ein paar komplexere Möglichkeiten, Zeiten festzulegen:
- Ein Minus (–) legt einen Zeitraum fest: 1-3 (ohne Leerzeichen dazwischen!) kann, je nach Spalte, “ein bis drei Minuten nach der vollen Stunde”, “von 1 bis 3 Uhr”, die ersten drei Tage eines Monats, “Januar bis März” oder aber “Montag bis Mittwoch” bedeuten.
- Mit einem Komma lassen sich mehrere Zeitangaben trennen: 2,6 bedeutet in Spalte 1 “um zwei und sechs Minuten nach der in Spalte 2 angegebenen Stunde”, in Spalte 2 “um 2 sowie 6 Uhr und den in Spalte 1 angegebenen Minuten”, in der dritten Spalte “am 2. und 6. des Monats”, an vierter Stelle “im Februar und im Juni” sowie in der Wochentagsspalte “am Dienstag und am Samstag”. Dabei kann man auch Zeiträume kombinieren: 1-3,6,8-9 in der vierten (also der Monats-) Spalte steht für “Januar bis März, Juni, August und September”.
- Mit einem / und nachgestellter Zahl lassen sich Zeiträume “mit Lücken” angeben: */2 bedeutet – je nach Spalte – “alle 2 Minuten, Stunden, Tage, Monate, Wochentage”, 1-6/2 ist dasselbe wie 1,3,5.
Mit einem /etc/crontab-Eintrag wie
43 5,13,21 * * * listar /home/listar/bin/gen-archive
wird der Cron-Daemon z. B. mit den Rechten des Benutzers listar um 5.43 Uhr, um 13.43 Uhr und um 21.43 Uhr das Programm /home/listar/bin/gen-archive ausführen. Dieses Beispiel stammt von einem Mailinglisten-Server und zeigt, dass Cron nicht etwa nur Systemprogramme, sondern z. B. auch von der Administratorin selbst geschriebene Shellskripte ausführen kann.
Gerade bei solchen zusammengesetzten Zeitangaben wie der Stundenangabe 5,13,21 empfiehlt es sich, darauf zu achten, dass man keine zusätzlichen Leerzeichen versehentlich einfügt – bei Manipulationen an der /etc/crontab ist man schließlich selbst die letzte Kontrollinstanz.
Listing 1
Beispiel einer systemweiten <I>/etc/crontab<I>
# /etc/crontab: systemweite Crontab # Anders als bei jeder anderen Crontab benoetigen # Sie das Kommando `crontab' hier nicht, um eine # geaenderte Version dieser Datei zu installieren. # Dieses File enthaelt zudem ein Feld "Benutzername", # das in anderen Crontabelle fehlt. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 42 6 * * * root run-parts /etc/cron.daily 47 6 * * 7 root run-parts /etc/cron.weekly 52 6 1 * * root run-parts /etc/cron.monthly
Distributionschaos
Obwohl in der Kommandospalte natürlich jedes halbwegs sinnvolle Kommando stehen kann, hat es sich eingebürgert, die systemweiten Cron-Jobs etwas systematischer zu ordnen. Jede Aktion, die einmal täglich ausgeführt werden soll, wird in ein Shellskript gepackt und z. B. im Verzeichnis /etc/cron.daily (vgl. Tabelle 2) abgelegt (Ausführbarkeitsrechte nicht vergessen!), wöchentlich zu erledigende Aufgaben in /etc/cron.weekly usw.
Die globalen Verzeichnisse für Cron-Skripte haben folgenden Vorteil: Viele Programmpakete ziehen für Cron prädestinierte Aufgaben nach sich – ein News-Server möchte einmal am Tag News holen und alte Postings“auslaufen lassen”, die System-Log-Utilities syslogd und klogd sollten sicher gehen können, dass Logdateien einmal die Woche gestutzt oder besser rotiert werden, etc.
Eine clevere Installationsroutine sorgt folglich dafür, dass mit der Installation auch gleich der passende Cron-Job aufgesetzt wird. Schriebe sie einfach eine Zeile in /etc/crontab, sähe es da bald sehr unübersichtlich aus, und besonders geschickt deinstalliert sich so etwas auch nicht – abgesehen davon, dass sich nicht immer alles halbwegs übersichtlich mit einer Zeile ausdrücken lässt. Also kopiert oder generiert die Installationsroutine ein nettes Shellskript, das root gegebenenfalls auch anpassen kann, und legt es im passenden Verzeichnis ab.
Leider zeigt sich an dieser Stelle das Distributionschaos ganz besonders, allerdings glätten sich die Wogen bei den Namen der Cron-Skript-Verzeichnisse in aktuellen Distributionen zum Glück etwas.
Schlimmer sieht es aus, wenn man sich anschaut, auf welche Art und Weise der Cron-Daemon dafür sorgt, dass diese Skripte zu passenden Zeiten ausgeführt werden. Oft – wie in Listing 1 zu sehen – benutzen Distributoren hier das Kommando run-parts, um alle Skripte im jeweiligen Verzeichnis abzuarbeiten. Diese Verfahrensweise wird von Debian, Red Hat und Derivaten verwendet. Caldera tanzt ein bisschen aus der Reihe, indem man statt des Binaries run-parts das Shellskript cronloop verwendet.
SuSE hingegen gefiel dieses Verzeichniskonzept lange Zeit ganz und gar nicht: Bis Version 5.3 ruft /etc/crontab hier das Skript /root/bin/cron.daily auf, das täglich die zu erledigenden distributionsspezifischen Aufgaben herunter rattert und zu guter Letzt auch noch das Skript /root/bin/daily.local für lokale Problemstellungen abarbeitet. Als sei das nicht schon unübersichtlich genug, wird zudem noch fröhlich und unsystematisch in /etc/crontab rumgewurstelt.
Ab Version 6.0 schließen die Nürnberger einen Kompromiss und legen ebenfalls besagte Directories an. Während run-parts andernorten als universell einsetzbarer, von cron unabhängiger Skriptstarter konzipiert ist, werden die in den Cron-Verzeichnissen befindlichen Skripte bei SuSE 6.0 und neuer von einem einzigen spezialisierten Skript namens /usr/lib/cron/run-crons aufgerufen.
Tabelle 2: Systemweite Cron-Skripte
| Wann auszuführen? | stündlich | täglich | wöchentlich | monatlich | zu anderen Zeiten |
|---|---|---|---|---|---|
| Caldera Open Linux 1.2–2.4 | /etc/cron.d/Hourly/ | /etc/cron.d/Daily/ | /etc/cron.d/Weekly/ | /etc/cron.d/Monthly/ | /etc/cron.d/lib/ |
| Debian 1.3.1 | – | /etc/cron.daily/ | /etc/cron.weekly/ | /etc/cron.monthly/ | – |
| Debian 2.0–2.2 | – | /etc/cron.daily/ | /etc/cron.weekly/ | /etc/cron.monthly/ | /etc/cron.d/ |
| Red Hat 4.2–5.2 | /etc/cron.hourly/ | /etc/cron.daily/ | /etc/cron.weekly/ | /etc/cron.monthly/ | – |
| Red Hat 6.2 | /etc/cron.hourly/ | /etc/cron.daily/ | /etc/cron.weekly/ | /etc/cron.monthly/ | /etc/cron.d/ |
| SuSE 5.2–5.3 | – | /root/bin/cron.daily (Skript für distributionsspezifische Jobs), /root/bin/daily.local (lokale Anpassungen und Erweiterungen) | – | – | – |
| SuSE 6.0 | /etc/cron.hourly/ | /etc/cron.daily/ | /etc/cron.weekly/ | /etc/cron.monthly/ | – |
| SuSE 6.4 | /etc/cron.hourly/ | /etc/cron.daily/ | /etc/cron.weekly/ | /etc/cron.monthly/ | /etc/cron.d/ |
Variabel
Doch wenden wir uns wieder Listing 1 zu: Da wären schließlich noch die mysteriösen Zeilen
SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
zu erklären. Wer schon mal den Suchpfad für ausführbare Programme in der Shell geändert hat, findet hier alte Bekannte in leicht geänderter Funktion wieder: Variablen, die in der Form Variablenname=Wert angeben werden.
Mit der Umgebungsvariablen PATH legt man fest, dass ausführbare Dateien in den nach dem Gleichheitszeichen angegebenen und durch Doppelpunkt getrennten Verzeichnissen einfach nur mit ihrem Namen aufgerufen werden können. Liegt ein Programm außerhalb des Suchpfads, muss man es hingegen mit der kompletten Pfadangabe aufrufen.
Zwei ausführbare Dateien gleichen Namens kann es durchaus geben – sie müssen lediglich in verschiedenen Verzeichnissen liegen. Da der Cron-Daemon mit root-Rechten ausgestattet ist (Wie sonst sollte er imstande sein, Aufgaben mit den Berechtigungen unterschiedlicher User auszuführen?) und damit in recht gefährlichem Gebiet operiert, geht man auf Nummer sicher und gibt mit der Variable PATH in der Crontabelle explizit an, welche Verzeichnisse als Suchpfad zugelassen sind. Da das Verzeichnis /home/listar/bin im obigen Beispiel nicht in PATH stand, musste gen-archive mit kompletter Pfadangabe in die /etc/crontab geschrieben werden.
Tabelle 3 gibt einen Überblick über die wichtigsten in Cron-Tabellen benutzbaren Variablen.
Tabelle 3: Umgebungsvariablen in Cron-Tabellen
| Umgebungsvariable | Beschreibung | Beispiel | Erklärung |
|---|---|---|---|
| MAILTO | Normalerweise schickt Cron sämtlichen Output per E-Mail an die auftraggebende Benutzerin. MAILTO definiert einen alternativen Empfänger | MAILTO=trish,pjung@linux-user.de[verschiedene Cronjobs]MAILTO=""[weitere Cronjobs] |
Der Output der “verschiedenen Cronjobs” geht per Mail an die lokale Benutzerin trish sowie an die externe Mailadresse pjung@linux-user.de. Nachdem MAILTO noch einmal neu gesetzt wurde, gibt es für die “weiteren Cronjobs” niemanden mehr, der über Erfolg oder Misserfolg informiert wird. |
| PATH | Pfad, in dem nach von Cron auszuführenden Kommandos gesucht wird. Fest einkompiliert ist in den meisten Fällen /usr/local/bin:/usr/bin:/bin: | PATH=/home/trish/bin |
Cron findet für diese Cron-Tabelle nur noch Kommandos aus /home/trish/bin ohne explizite Pfadangabe. |
| SHELL | Shell, in der die Kommandos ausgeführt werden sollen. Voreingestellt ist /bin/sh und damit meistens ein Link auf die Bash. | SHELL=/usr/bin/tcsh |
Statt /bin/sh wird jetzt die tcsh verwendet. |
Wie hält er’s mit den Usern, sprich?
Während die Systemadministratorin in der systemweiten /etc/crontab peinlich selbst darauf achten muss, den Syntax-Ansprüchen des Cron-Daemons zu genügen, hat sie es leichter, wenn sie roots private Cron-Tabelle ändern will. Benutzerspezifische Wunschlisten an den Cron-Daemon werden – wie eingangs erwähnt – mit dem Programm crontab erstellt und gewartet.
Außer root hat kein User überhaupt die Möglichkeit, seine private Cron-Tabelle per Hand zu bearbeiten. Da der Cron-Daemon jede Minute angerückt kommt, um nach seinen Aufgaben zu sehen, vermeidet man so, dass ein unbedarfter Benutzer eine halbfertige oder syntaktisch vollkommen falsche Liste erstellt.
Tabelle 4: Wo stecken die persönlichen Cron-Tabellen?
Auch beim Verzeichnis, in dem die privaten Crontab-Dateien der User zu finden sind, herrscht fröhliche Uneinigheit unter den Distributoren. Immerhin können sich außer SuSE fast alle ein “Unterhalb von /var/spool/cron” abringen. Ein paar Stichproben… |
|
|---|---|
| Debian 1.3.1 ff. | /var/spool/cron/crontabs/ |
| Red Hat 4.2 | /var/spool/cron/ |
| Red Hat 5.0 | /var/spool/cron/crontabs/ |
| Red Hat 6.2 | /var/spool/cron/ |
| Caldera OpenLinux 1.2 ff. | /var/spool/cron/ |
| SuSE 4.4 ff. | /var/cron/tabs/ |
| Slackware 3.4 | /var/spool/cron/crontabs/ |
Stattdessen legt crontab eine Kopie der alten Crontab an, die die Benutzerin im von crontab automatisch aufgerufenen Editor verändern darf. Erst wenn sie den Editor endgültig schließt, führt crontab ein paar Syntaxprüfungen aus, bittet die Benutzerin ggf. um Korrektur und ersetzt zum Schluss die alte Cron-Tabelle durch die geänderte.
So hilfreich diese Kontrollinstanz ist – Wunder sollte man nicht erwarten. Zum einen überprüft crontab wirklich nur, ob die richtige Anzahl Spalten vorhanden sind (versehentlich eingefügte Leerzeichen u. a. machen eine neue Spalte auf) und ob die Angaben in den Zeitspalten plausibel sind. Einen Eintrag wie
88 4 * * * asdadad
(Achtung: Da private Crontabs immer spezifisch für einen User sind, fehlt die Spalte mit dem Benutzernamen!) mahnt crontab beim Abspeichern zwar mit dem Hinweis auf die falsche Minute (“bad minute“) an:
crontab: installing new crontab "/tmp/crontab.XXXXVYM64K":0: bad minute errors in crontab file, can't install. Do you want to retry the same edit?
Doch sobald man mit einem y wie “yes” reumütig zum Editor zurück kehrt und aus der 88 eine 8 macht, wird crontab die alte Crontabelle klaglos mit der neuen ersetzen, so wenig ein Kommando asdadad auch existieren mag.
Solange crontab jedoch syntaktische Fehler ausmachen kann, lässt es sich nicht so ohne weiteres überlisten. Hätten wir auf die Frage “Möchten Sie Ihre Änderungen noch einmal überarbeiten?” mit einem n geantwortet, wäre die temporäre Datei /tmp/crontab.XXXXVYM64K zwar erhalten geblieben, die Änderungen jedoch nicht in die echte Crontabelle übertragen worden.
Der Widerspenstigen Zähmung
Wie man mit man crontab erfährt, könnte man diese Datei mit einem Editor seiner Wahl in Ruhe korrigieren und mit
crontab /tmp/crontab.XXXXVYM64K
doch noch zu Ehren kommen lassen. Genausogut kann man jede andere vorgefertigte Datei zu installieren versuchen. Auch wenn sich diese Vorgehensweise sicher dazu eignet, eine sorgfältig erstellte Crontabelle nach einer Neuinstallation o. ä. wieder einzuspielen, wird man doch in der Regel zu
crontab -e
greifen, um seine private Cron-Tabelle zu editieren oder neu anzulegen. Hier kann es nicht schaden, die Grundlagen des vi-Editors zu kennen (mit der Tastenfolge ESC:q! kommt man ohne Speichern wieder raus), denn der ist in der Regel voreingestellt.
Wer diesen nicht mag, kann mit einer der (Shell-, nicht Cron-) Umgebungsvariablen EDITOR oder VISUAL seinen Lieblingseditor festlegen. Arbeitet man unter KDE, gibt man z. B. die Befehlsfolge
export EDITOR=kedit crontab -e
in einem Terminal-Fenster an. Nach dem Ausloggen oder in der Regel auch in einem anderen X-Terminal ist der neue Wert von EDITOR dann natürlich verschwunden.
Wer ihn dauerhaft haben möchte, schreibt die export-Zeile z. B. in die Datei .bashrc oder .bash_profile im Home-Verzeichnis. Für X-Terminals, die über einen Menüpunkt oder ein Icon aufgerufen werden, kann hier ein wenig Experimentieren erforderlich sein.
Allerdings sollte man beim dauerhaften Ändern dieser Variablen vorsichtig sein: Auch andere Programme richten sich danach, und wer kommt schon gleich auf die Idee, dass ein in der Textkonsole gestartetes Tool deshalb aufgibt, weil sich ein grafischer Editor nun mal nur unter X starten lässt? Für den Notfall sei hier auch das Gegengift erwähnt:
unset EDITOR
bringt die Variable wieder in den (nicht gesetzten) Urzustand, und export EDITOR=mcedit setzt stattdessen den vom Midnight Commander mc benutzten Editor, der ohne X auskommt.
So nützlich crontab also ist: Völlig unbedarftes Herangehen ist nicht unbedingt Erfolg versprechend. Eine gewisse Vereinfachung versprechen grafische Crontab-Editoren, denen wir uns im nächsten (Erscheinungs-)Jahr widmen. Wer trotz allem an seiner Crontabelle verzweifelt: Ein
crontab -r
(wie “remove”) löscht sämtliche Einträge unweigerlich.
Glossar
-
man 5
-
Wie in der Rubrik “Zu Befehl” im LinuxUser 02/2000 ausführlich erklärt, sind die Manpages nach Anwendungsgebiet in sogenannte Sektionen gegliedert. Mit crontab z. B. können zwei verschiedene Dinge gemeint sein: das Programm oder die Datei. Informationen zu ersterem findet man in Sektion 1 mit dem Befehl man 1 crontab oder kurz man crontab. Die Manpage zur Datei namens crontab hingegen ist in Sektion 5, also mit man 5 crontab, zu finden. In welchen Sektionen man etwas über crontab findet, erfährt man mit man -f crontab.
-
Shellskripte
-
Die Shell, ihres Zeichens Vermittlerin zwischen der Benutzerin an der Kommandozeile und dem Betriebssystemkern, bietet – je nachdem, welches Programm man dafür verwendet – oft weitreichende Manipulationsmöglichkeiten. Dazu gehört bei Kommandozeileninterpretern wie der unter Linux meist standardmäßig eingestellten Bash eine eingebaute Programmiersprache. Damit erstellte Programme heißen Skripte, da sie nicht erst mit einem extra Compiler in ein ausführbares Programm übersetzt werden müssen, sondern direkt von der Shell interpretiert werden.
-
Postings
-
Ein Posting ist ein Beitrag in einer News-Gruppe oder auf einer Mailingliste.
-
System-Log
-
Der Kernel und wichtige Systemprogramme lassen ihre Aktivitäten und Fehlerfälle vom “Kernel-Log-Dämon” klogd bzw. vom “System-Log-Daemon” syslogd mitprotokollieren. Aus diesen Logfiles (meist unter /var/log/ zu finden) kann die Systemadministratorin bei Problemen Rückschlüsse ziehen.
-
.
-
<B Der Punkt ist eine Abkürzung für das aktuelle Verzeichnis. Dies ist gerade beim Cron-Daemon mit seiner ungeschränkten Verfügungsgewalt eine recht gefährliche Pfadangabe.
Infos
[1] Artikel zu Cron aus dem Linux-Magazin 08/1998, S. 63 http://www.linux-magazin.de/ausgabe/1998/08/Cron/cron.html

