Immer wiederkehrende Aufgaben wie Sicherungen des Datenbestands oder das Archivieren von Logfiles selbst zu erledigen, wäre ebenso öde wie unzuverlässig. Zu schnell geraten langweilige Routineaufgaben in Vergessenheit – nicht nur bei Nerds und Geeks, denen gerne nachgesagt wird, sie meiden redundante Abläufe wie die Schweinepest oder Kloputzen. Glücklicherweise gibt es Cron Jobs, die Webworkern im Allgemeinen und Nerds im Besonderen wiederkehrende Aufgaben abnehmen.
Den Prototypen des vollkommenen Nerds haben die Macher der Fernsehserie The Big Bang Theory geschaffen. Sheldon Cooper argumentiert, er müsse nur einmal Spaß haben, um dann mit anderen Aufgaben fortfahren zu können. Das sei genauso wie mit Finnisch: Diese Sprache werde er schließlich auch nicht ein zweites Mal lernen – einmal genüge vollkommen.
Nerds wie Sheldon Cooper hassen Redundanz und planen sorgfältig – QUELLE: Screenshot
Darüberhinaus hat Sheldon jedoch auch einen strikten Zeitplan, wann und wo er die leider unvermeidbaren redundanten Aufgaben erledigt. Wäre Sheldon ein unixoider Server – und wer die Serie kennt, weiß, dass das kein allzu abwegiger Gedanke ist – würde er diesem Plan sicherlich mithilfe des cron-Dienstes folgen.
Was ist cron
Cron ist ein so genannter Daemon. Das ist bei Unix und bei unixartigen Betriebssystemen wie Linux und Mac OS X eine Jobsteuerung, die im Hintergrund möglichst ressourcenschonend wiederkehrende Aufgaben ausführt. Häufig führen Cron Jobs Programme aus, die entscheidend dazu beitragen, dass ein System funktionsfähig bleibt.
Neben cron sind zum Beispiel httpd (antwortet als Webserver auf http-Anfragen) und syslogd (legt Nachrichten von Programmen in Logdateien ab) bekannte Unix-Daemons, die wie cron ebenfalls im Serverbereich eine große Rolle spielen. Typische Aufgaben von cron sind beispielsweise das Erstellen von Backups und das Löschen oder Verschieben von Logdateien, aber auch automatisiert veröffentlichte Blogposts lassen sich damit im Handumdrehen realisieren.
Das Ganze läuft wie gesagt nicht nur unter Unix, sondern unter anderem auch unter Mac OS X oder Linux. Das kommt uns sehr gelegen, da sich dieser Artikel vor allem an Einsteiger wendet, wollen wir nicht gleich an einem Live-Webserver mit Root-Zugriff herumspielen, sondern bewegen uns lieber auf sicherem Terrain und probieren cron auf dem eigenen Rechner aus. Windows-Benutzer sind leider etwas benachteiligt, können sich aber natürlich eine Linux-Distribution in einer virtuellen Maschine installieren. Eine weitere Alternative ist die lokale Installation eines Webservers – etwa WampServer – auf Windows (Anmerkung der Redaktion).
Dann sind wir auch schon startbereit, denn cron ist sowohl auf dem Mac als auch unter Linux bereits vorinstalliert.
Der Name „cron“ ist abgeleitet von Chronos, dem griechischen Gott der Zeit. „cron-Daemon“ drückt also schon perfekt aus, was cron macht: Nach zeitlichen Mustern im Hintergrund Befehle aufrufen. Die entsprechenden Anweisungen erteilen wir indirekt über crontabs, das sind benutzereigene Tabellen, in denen die Cron-Befehle gespeichert sind.
Crontabs
Wir werden nun am Beispiel der fiktiven Serienfigur Sheldon Cooper einen Wochenplan als Cron Jobs anlegen. Dazu editieren wir eine bestimmte Textdatei, die crontab (cron-Tabelle). Der einfachste Weg, einen solchen crontab zu öffnen, ist der Befehl crontab -e
, den wir einfach in die Konsole eintippen. Eventuell sehen wir in der sich öffnenden Datei schon eine Zeile, in der etwa folgendes steht:
# m h dom mon dow command
Es handelt sich hierbei um eine grobe und zugegebenermaßen sehr kryptische Bedienungsanleitung. Übersetzt würde die Zeile vielleicht so lauten:
# Minute Stunde Tag Monat Wochentag Kommando
Es wird schon durchschaubarer. Am besten wird die Syntax aber an einem Beispiel klar. Wir nehmen uns dazu wieder Dr. Sheldon Cooper und seinen Wochenplan vor: Jeden Samstag um exakt 20:15 Uhr ist Waschtag.
15 20 * * 6 laundrynight
In Prosaform würde dies lauten, dass Sheldon immer zur fünfzehnten Minute und zwanzigsten Stunde an jedem Wochentag mit der Nummer 6 den Befehl laundrynight
ausführt. Die Woche beginnt für cron mit dem Sonntag, welcher die Nummer 0 hat. Jeder weitere Tag wird bis 6, dem Samstag, hochgezählt. Beim Monat und dem „Monatstag“ werden keine Einschränkungen vorgenommen, was durch das Sternchen ausgedrückt wird. Wie in anderen Sprachen handelt es sich hier um eine Wildcard, ein Platzhalter, der alle an dieser Stelle möglichen Werte repräsentiert.
Wöchentliche Halo-Session in der Nerds Community QUELLE: Screenshot
Schauen wir uns einen weiteren Fall an. Sheldon und die drei anderen Nerds halten jeden Mittwoch um 20:00 Uhr eine gemeinsame Halo-Session ab. Da es für die Verdeutlichung einer bestimmten Eigenheit der cron-Syntax dienlich ist, nehmen wir ferner an, dass diese Halo-Session zusätzlich immer am Siebten jedes Monats stattfindet.
15 20 7 * 3 halonight
Würden wir im Gegensatz dazu annehmen, dass Halo-Night nicht am Dritten jedes Monats, sondern nur am dritten Oktober zusätzlich zu jedem Samstag stattfände, hätten wir ein Problem, denn das lässt sich nicht so einfach umsetzen. Vermuten würde man eine Kombination wie diese:
15 20 7 10 3 halonight
Doch das wird nicht funktionieren. Stattdessen wäre Halo-Night zwar am 3. Oktober, aber zusätzlich nicht jeden Mittwoch im Jahr, sondern nur die vier oder fünf Mittwoche im Oktober. Sheldon wäre darüber nicht sehr glücklich.
Aber woran liegt das? Nun, man könnte sagen, dass die Monats- und Wochentagangaben mit OR verknüpft sind. Das bedeutet, dass sich diese beiden Bedingungen insofern nicht ins Gehege kommen, als dass der obere Ausdruck sowohl für den siebten Tag im Monat als auch für den dritten in der Woche zutrifft. Und nicht, dass der Ausdruck nur für den siebten Tag im Monat, der gleichzeitig der dritte der Woche ist, gilt; was einer AND-Verknüpfung entspräche. Eine solche AND-Verknüpfung besteht aber zwischen dem Monat und dem Monatstag und zwischen dem Monat und dem Wochentag. So gilt folgender Ausdruck nur für die Freitage, welche im Juni liegen:
15 20 * 6 5 dosomething
Ganz schön kompliziert, denkt man sich. Doch eigentlich ist das System recht intuitiv und nur das Erklären lässt die grauen Zellen rauchen. Trotzdem hier zur Veranschaulichung noch eine Skizze, die nochmals die Verknüpfungen verdeutlicht.
# m h dom mon dow command# | | |# | | |# -AND- |# | | |# | | |# | -AND-# | |# | |# ----OR---
Bei dieser ASCII-Skizze handelt es sich um einen reinen Kommentar und sie kann deshalb auch als Gedankenstütze direkt ins crontab übernommen werden.
Weitere Feineinstellungen
Ein Cron Job besteht also aus sechs Argumenten, die jeweils mit Leerzeichen voneinander abgegrenzt sind. Ab dem fünften Leerzeichen wird alles Darauffolgende als Kommando interpretiert, das bedeutet, wir können in die Kommandos selbst so viele Leerzeichen packen wie wir wollen, ohne dass dadurch der Cron Job invalide wird.
# Jeden Freitag ist Vintage Video Game Night:0 19 * * 5 videogamenight --flavour vintage
Interessant ist das vor allem auch dann, wenn wir mit einem Cron Job mehrere Aufgaben erledigen möchten. In dem Fall hängen wir die einzelnen Kommandos einfach mit einer &&
-Verknüpfung aneinander.
Launen und Marotten?
In Sheldons Leben gibt es auch ein klein wenig Willkür, aber natürlich ist auch diese zeitlich streng geregelt. So trinkt er heiße Schokolade nur in Monaten, die im Namen ein „r“ enthalten. cron bietet für solche Bedingungen eine verkürzte Notationsmöglichkeit.
* * * 1,2,3,4,9,10,11,12 * hotchocolatetime
Zufälligerweise liegen diese Monate in einer Reihe, so dass wir uns auch einer weiteren Vereinfachung bedienen können:
* * * 1-4,9-12 * hotchocolatetime
Routinen für Zwangsneurotiker
Keimfreiheit à la Sheldon Cooper – QUELLE: Screenshot
Sheldon hätte wohl am liebsten alles absolut steril, so auch seine Hände, was der Grund dafür ist, dass er sich diese andauernd wäscht. Nehmen wir an, das Händewaschen passiert alle zehn Minuten. Wie drücken wir das in einem Cron Job aus? Ganz einfach:
*/10 * * * * washhands
In jeder Minute, die ein Vielfaches der Zehn ist, wird washhands
ausgeführt. Das funktioniert natürlich auch mit Stunden, Tagen und Monaten.
Immer am dritten Donnerstag – Cron Jobs und Regeln
Für Sheldon und seine Kumpels gibt es genau einen Tag im Monat, an dem etwas Unvorhersehbares passieren kann. Dieser Tag nennt sich Anything-can-happen-thursday und findet immer am dritten Donnerstag im Monat statt. Im Gegensatz zu seinen Freunden findet Sheldon diese Gewohnheit eher überflüssig, was auf seine Furcht vor Überraschungen zurückzuführen ist.
Vielleicht ist seine Abneigung gegen die Regel aber auch schlicht darin begründet, dass man diese nicht in einem Cron Job ausdrücken kann. Man kann sich zwar im Kommando-Bereich einen Workaround schaffen, doch grundsätzlich gibt es eine solche Regeldeklaration in cron nicht. Man kann also mit cron nicht alle erdenklichen Aufgaben abdecken.
Asynchrone Aufträge übernimmt Daemon anacron
Wenn Sheldon einmal verschlafen sollte und erst um neun Uhr aufsteht – somit seine geplante Frühstückszeit verpasst, müsste er bis zum Mittagessen hungern, denn der Cron Job wird nur zur definierten Zeit ausgeführt, wenn das System aktiv ist. Termine werden niemals nachgeholt. Solche asynchronen Aufträge lassen sich beispielsweise mit dem verwandten Daemon anacron lösen.
Im Server-Bereich ist dieser Daemon eher unrelevant, da Server sowieso nach Möglichkeit eine Uptime von 99,99% haben sollten. Der heimische Rechner wird aber nicht den ganzen Tag laufen. Für die Regelung des privaten Zeitplans ist anachron also in manchen Fällen vielleicht die bessere Wahl.
Beispiele mit Realweltbezug
Entfernen wir uns zum Schluss von nerdigen Serienhelden und schauen uns Beispiele an, die etwas mehr Bezug zur realen Welt haben. Die einfachste Möglichkeit, jeden Sonntagabend ein Backup zu machen, wäre so möglich:
0 22 * * 0 datum=`date -I` ; tar -zcf backup_$datum.tgz ./public_html
Dieser Cron Job erstellt automatisch ein gepacktes Archiv des Ordner public_html. Die Variable $datum
ist dabei Teil des Dateinamens und ganz praktisch, wenn wir später ein Backup aus einem ganz bestimmten Zeitraum suchen.
Aber wir wollen nicht nur unsere Dateien auf dem Webspace sichern, sondern auch die MySQL-Datenbank:
0 4 * * * date=`date -I` ; mysqldump -u DBUSER -p DBPASS –all-databases | gzip >/irgendwo/mysqlbackup_$date.sql.gz
Es wird jeden Tag morgens um vier Uhr ein Backup aller Datenbanken des Users DBUSER mit dem Passwort DBPASS angelegt. Auch hier wird alles in ein Archiv gepackt, das wieder das Datum als Teil des Dateinamens enthält.
Scripte automatisch laufen lassen
Was man auch immer wieder hört, ist, dass viele nach einer Möglichkeit suchen, ein bestimmtes Skript automatisch zu einer bestimmten Zeit ausführen zu lassen. Mit Cron Jobs ist das die denkbar einfachste Übung:
0 0 * * 1 /pfad/zum/skript.php
Die skript.php kann nun beispielsweise eine wöchentliche Linkliste ins Blog stellen und veröffentlichen, ohne dass wir mittels seltsamer PHP-Workarounds selbst Hand anlegen müssen.
(mm),
10 Antworten
Hi, sehr cooler Beitrag cronjobs mit Sheldon. Keep up the good work
Hallo danke für die detaillierte anleitung… ich hätte da noch eine frage ist es möglich über cron jobs minütlich in ein verzeichnis zu wechseln und dort dann ein script zu starten ?
also: 1 * * * * /pfad/zum/script/start script
@Gerri
>st es möglich über cron jobs minütlich in ein verzeichnis zu wechseln und dort dann ein script zu starten ?
Wozu sollte man denn in einen Pfad wechseln um ein dort liegendes Script zu starten?
Man kann doch das Script direkt mit Pfadangabe starten lassen, z.B.:
Minute Stunde Tag Monat Wochentag Kommando Opt
———————————————————————–
1 * * * * ./pfad/zum/script/minecraft.sh start
lieben Gruß aus Hessen
Zu “Immer am dritten Donnerstag – Cron Jobs und Regeln”
Selbstverständlich gibt es auch dafür den passenden Cron-Ausdruck: “THU#3”.
Ein gelungener Artikel, der den Nutzen von Cronjobs gut veranschaulicht. Meines Wissens nach muss jedoch bei PHP Skripten der Kompiler mit angegeben werden. Also statt “0 0 * * 1 /pfad/zum/skript.php” dann zum Beispiel “0 0 * * 1 /usr/bin/php /pfad/zum/skript.php”.
Muss es nicht, wenn in der Datei ein Interpreter in der ersten Zeile steht. Im fall von PHP als “#!/usr/bin/php”. Dann funktioniert es auch ohne die Angabe in der Cron-Zeile.
Ja, das stimmt. Doch mit der von mir angesprochenen Methode ist gewährleistet, dass alle PHP-Dateien, was die erste Zeile angeht, weiterhin einheitlich sind und man nicht durcheinander kommt, was die Angabe des Interpreters angeht.
Den Artikel finde ich gut.
Aber ich suche nach einem Ausdruck, wo ich einen Job zu einem bestimmten Zeitpunkt aussetzen kann
Z.B ich habe einen Job der alle 2 Min. läuft 0 0/2 * * * ?.
Der Job muss an einem bestimmten Sonntag aussetzen.
Weißt du, ob ich das mit reinbringen kann!
Gruß
Usama
Das Beispiel mit der Absicherung der Datenbank funktioniert so nicht, da statt “-p” “–password” angegeben werden muss und “-all-databases” direkt nach “mysqldump” kommen muss.
Bis auf diesen kleinen Fehler, ein guter Artikel!
http://crontab.guru ist ganz nützlich, wenn man mal wieder vergessen hat, welches Feld für die Minuten und Stunden zuständig ist.