Cron

aus Wikipedia, der freien Enzyklopädie

Der Cron-Daemon dient der zeitbasierten Ausführung von Prozessen in Unix und unixartigen Betriebssystemen wie Linux, BSD oder macOS, um wiederkehrende Aufgaben – Cronjobs – zu automatisieren.

Häufig führt der Cron-Daemon regelmäßig Computerprogramme für die Instandhaltung des Systems aus, üblicherweise auf Serversystemen, welche rund um die Uhr laufen. Beispiele sind Dienste für das Archivieren und Löschen von Logdateien oder um Systemprogramme periodisch und automatisch zu aktualisieren.

Auf Arbeitsplatzrechnern, Laptops und Rechnern, welche nicht durch einen Dauerbetrieb gekennzeichnet sind, kommen meist andere Varianten wie anacron zum Einsatz. Das im Ursprung aus den 1970er-Jahren stammende Cron wird in der Funktion auf unixartigen Rechnern zunehmend durch umfangreichere Systemprogramme mit integrierten Zeitfunktionen wie systemd abgelöst.

Crontab

Die auszuführenden Anweisungen werden in einer benutzereigenen Tabelle gespeichert, der sogenannten Crontab. Der Begriff leitet sich ab von griechisch chronos = ‚die Zeit‘ und lateinisch tabula = ‚die Tafel‘ oder ‚das Brett‘ bzw. englisch table für ‚Tabelle‘ und bedeutet demnach so viel wie „Zeittafel“ (also „Stundenplan“). Diese Tabelle besteht aus sechs Spalten; die ersten fünf dienen der Zeitangabe (Minute, Stunde, Tag, Monat, Wochentag), alle weiteren Zeichen bis zum Zeilenumbruch werden als der auszuführende Befehl aufgefasst. Jedes Mal, wenn ein spezifischer Zeitpunkt erreicht wird, wird der entsprechende Befehl, meist ein Shellskript, ausgeführt.

Benutzer können ihre eigenen individuellen Crontab-Dateien anlegen. Dies erfolgt mit Zusatzprogrammen wie dem gleichlautenden Programm crontab, und die damit aufgerufenen Programme werden unter den jeweiligen Benutzerrechten ausgeführt. Üblicherweise gibt es parallel dazu eine systemweite Crontab-Datei (normalerweise in /etc oder ein Unterverzeichnis von /etc), die nur Systemadministratoren bearbeiten können und deren Befehle unter den Rechten des Systemadministrators ausgeführt werden.

Einige Implementierungen von Cron, wie sie in der 4. Auflage des BSD von Paul Vixie geschrieben und in vielen Linux-Distributionen enthalten sind, fügen dem Format ein sechstes Feld hinzu: einen Benutzernamen, durch den der angegebene Job vorbehaltlich der Existenz des Benutzers und seiner Berechtigungen durchlaufen wird. Dies ist nur in den systemweiten Crontabs erlaubt, nicht in anderen, die jeweils von einem einzelnen Benutzer zu konfigurieren sind. Das sechste Feld wird manchmal für Jahre statt eines Benutzernamens verwendet; der nnCron Daemon für Windows tut dies. Vixie cron verwendet allerdings nicht die sechste Spalte als ein Jahr, und wenn es als Jahr verwendet wird, wird das Jahr als der Befehl ausgeführt und führt zu einem Fehler.

Der Eintrag eines * bedeutet, dass die jeweilige Spalte einen beliebigen Wert haben kann. Mit / werden Schrittweiten definiert, mit - werden Bereiche und mit , Elemente einer Aufzählung separiert. Für „Tag der Woche“ (Feld 5) sind sowohl 0 als auch 7 für Sonntag erlaubt, obwohl einige Versionen von Unix wie AIX die Ziffer 7 in der Manpage nicht als zulässig auflisten. Während normalerweise der Job ausgeführt wird, sofern alle Felder der Zeit/Datum-Spezifikation mit dem aktuellen Datum und der Uhrzeit übereinstimmen, gibt es eine Ausnahme: Wenn sowohl „Tag des Monats“ (Feld 3) als auch „Tag der Woche“ (Feld 5) beschränkt sind (nicht *), muss nur ein Kriterium für das aktuelle Datum erfüllt werden.

Beispiele

Minute Stunde Tag des Monats Monat Wochentag Bedeutung
* * * * * Jede Minute, rund um die Uhr, sieben Tage die Woche
0 0 * * * Täglich null Uhr
5 * * * * Fünf Minuten nach jeder vollen Stunde
*/5 * * * * Alle 5 Minuten
1-59/2 * * * * Jede ungerade Minute
5-59/20 * * * * 5, 25 und 45 Minuten nach jeder vollen Stunde
59 23 * * 0 Jeden Sonntag um 23:59 Uhr. Manche Cron-Syntax erlaubt neben 0 für Sonntag auch 7 für Sonntag.
20,30 1 * * 1-5 Montags bis Freitags jeweils um 01:20 und 01:30 Uhr
0 1 1-7 12 1 Das Programm wird um 1:00 an jedem Tag zwischen 1. bis 7. Dezember UND zusätzlich an jeden Montag im Dezember aufgerufen, da hier der Sonderfall greift, dass nur entweder der Tag des Monats oder der Tag der Woche übereinstimmen muss (siehe oben).

Cron wird durch eine Crontab-Datei gesteuert. Dies ist eine einfache Textdatei in der neben der Zeitinformation auch die auszuführenden Shell-Befehle eingetragen sind. Dabei wird pro Zeile die Zeitinformation und daran anschließend in der gleichen Zeile das aufzurufende Programm eingetragen, üblicherweise inklusive Angabe des kompletten Pfades. Die Spaltentrennung erfolgt durch Leerzeichen. Kommentarzeilen beginnen mit dem Symbol # am Anfang einer Zeile. Die grundlegende Struktur der crontab besitzt folgenden Aufbau:

┌───────────── Minute (0 - 59)
│ ┌───────────── Stunde (0 - 23)
│ │ ┌───────────── Tag des Monats (1 - 31)
│ │ │ ┌───────────── Monat (1 - 12)
│ │ │ │ ┌───────────── Wochentag (0 - 6)
│ │ │ │ │
* * * * *  /Pfad/Programmname

Beispielsweise führt folgende Zeile in der Crontab dazu, dass das Programm /bin/prog.sh jeden Samstag (Tag = 6) um 23:45 aufgerufen wird:

# Crontab Beispiel
45 23 * * 6 /bin/prog.sh

Geschichte

Frühe Versionen

Cron, geschrieben von Brian W. Kernighan, war in Unix Version 7 ein Systemdienst (später als Daemon), der aufgerufen wurde, wenn sich das Betriebssystem im Mehrbenutzermodus befand. Kernighans Algorithmus war einfach: Die Crontab wurde einmal in der Minute eingelesen und ausgewertet und Befehle, deren Ausführung für diese Minute geplant war, mit Root-Rechten ausgeführt.

Diese Version von Cron war einfach und robust, verbrauchte jedoch auch Ressourcen, wenn nichts zu tun war. Bei einem in den späten 1970er Jahren an der Purdue University durchgeführten Lasttest wurde festgestellt, dass die Anwendung zu viel Last auf dem System – einer VAX, die sich die Mitarbeiter teilten – erforderte.

Mehrbenutzerfähigkeit

Die nächste Version von Cron wurde mit der Veröffentlichung von Unix System V geschaffen, um die Fähigkeiten von Cron für alle Benutzer und nicht nur für den Superuser eines Unix-Systems zu erweitern. Es mag trivial erscheinen, da die meisten Unix- und Unix-ähnlichen Systeme über leistungsstarke Prozessoren und nur eine kleine Anzahl von Benutzern verfügen. Zu diesem Zeitpunkt erforderte der Einsatz auf einem 1-MIPS-System mit rund 100 Benutzerkonten einen neuen Ansatz.

In einer Ausgabe der Fachzeitschrift Communications of the ACM vom August 1977 veröffentlichten W.R. Franta und Kurt Maly einen Artikel mit dem Titel An efficient data structure for the simulation event set[1], worin sie eine Datenstruktur für Ereigniswarteschlangen für diskrete ereignisgesteuerte Simulationssysteme beschreiben, die nachweislich den am häufigsten verwendeten Algorithmen mit einfach verketteten Listen überlegen sind (“performance superior to that of commonly used simple linked list algorithms”) und eine Worst-Case-Komplexität von Fehler beim Parsen (MathML mit SVG- oder PNG-Rückgriff (empfohlen für moderne Browser und Barrierefreiheitswerkzeuge): Ungültige Antwort („Math extension cannot connect to Restbase.“) von Server „https://wikimedia.org/api/rest_v1/“:): {\displaystyle O\left(\sqrt{n}\right)} besitzt, wobei n die Anzahl der Ereignisse in der Warteschlange bezeichnet.

Der Student Robert Brown erkannte nach Durchsicht dieses Artikels die Parallele zwischen Cron und ereignisorientierter Simulation und schuf eine Implementierung der Franta-Maly Event list manager (ELM) für Experimente. Ereignisorientierte Simulationen laufen in sogenannter „virtueller Zeit“ ab. Die anstehenden Ereignisse aus der Warteschlange werden dabei so schnell wie möglich ausgeführt und haben Auswirkungen auf die aktuelle, virtuelle Zeit des nächsten Ereignisses. Die Ausführung des Ereignissimulators in Echtzeit („real time“) trat anstelle der Ausführung mit virtueller Zeit. Diese Version des Crons verbrachte den Großteil der Zeit in Inaktivität und wurde erst dann aktiv, wenn die Ausführung der nächsten Aufgabe anfiel.

Zum Graduiertenkolleg kam 1978 u. a. der Doktorand Keith Williamson hinzu und wurde Systemmitarbeiter im Fachbereich Informatik. Als erste Aufgabe, „zum Aufwärmen“, bat Brown ihn, den Prototyp Cron zu einem Produktionsumgebungsservice weiterzuentwickeln. Dieses Mehrbenutzer-Cron ging Ende 1979 an der Purdue University in Gebrauch. Diese Version von Cron ersetzte vollständig die /etc/cron, die in der Informatik-Abteilung VAX 11/780 mit 32/V im Einsatz war.

Der Algorithmus, der für dieses Cron eingesetzt wurde, verhält sich wie folgt:

  1. Beim Start des Systems nach einer Datei namens „.crontab“ in den Home-Verzeichnissen aller Kontoinhaber suchen
  2. Für jedes gefundene crontab wird der nächste Zeitpunkt in der Zukunft bestimmt, an dem ein Befehl ausgeführt werden soll.
  3. Platziere diese Befehle auf der Franta-Maly Event-Liste mit der entsprechenden Zeit und ihren „fünf Feld“-Zeit-Spezifikationen.
  4. Tritt in die Hauptschleife ein:
    1. Suche den Eintrag an der Spitze der Warteschlange und berechne, wie weit in der Zukunft er ausgeführt werden soll.
    2. Tritt für diesen Zeitraum in Ruhezustand.
    3. Beim Erwachen und nach Überprüfung der korrekten Zeit, führe die Aufgabe an der Spitze der Warteschlange aus (im Hintergrund) mit den Rechten des Benutzers, der die Aufgabe erstellt hat.
    4. Bestimme den Zeitpunkt in der Zukunft, um den Befehl auszuführen und schreibe Ihn wieder in die Event-Liste mit dem errechneten Zeitwert.

Zusätzlich reagierte der Daemon auf SIGHUP-Signale und plante halbstündlich spezielle Ereignisse zum erneuten Einlesen der Crontab ein. Ausgaben auf den Standardaus- sowie Fehlerausgaben wurden per E-Mail an den Besitzer der Crontab gesandt. Der Ressourcenverbrauch dieser Implementierung von Cron war nur noch von der Menge und Häufigkeit der geplanten Aufgaben abhängig, mit Ausnahme der Überwachung der Crontab.

Williamson schloss sein Studium ab, verließ die Universität mit einem Master of Science der Informatik, schloss sich den Bell Laboratories in Murray Hill in New Jersey an und nahm seine Fassung von Cron dorthin mit. In den Bell Laboratories integrierten er und andere den Unix-Befehl at in Cron, verschoben die Crontab-Dateien aus dem Benutzerverzeichnis in ein gemeinsames, Host-spezifisches Spool-Verzeichnis und führten ein dadurch notwendig gewordenes Kommando crontab ein, mit dem Benutzer ihre Crontab-Dateien in dieses Spool-Verzeichnis kopieren konnten.

Diese Version von Cron erschien später weitgehend unverändert in Unix System V und BSD sowie deren Derivaten, im Betriebssystem Solaris von Sun Microsystems, IRIX von Silicon Graphics, HP-UX von Hewlett-Packard sowie IBM AIX. Eigentlich hätte die Software von der Purdue Research Foundation lizenziert werden müssen, da diese die Entwicklung finanzierte, zur damaligen Zeit wurde jedoch kein Augenmerk darauf gelegt.

Moderne Versionen

Mit dem Aufkommen des GNU-Projekts und Linux erschienen neue crons. Die häufigste von ihnen ist die Vixie cron, die ursprünglich von Paul Vixie 1987 geschrieben wurde. Version 3 von Vixie cron wurde Ende 1993 veröffentlicht. Version 4.1 wurde in ISC Cron umbenannt und im Januar 2004 veröffentlicht. Version 3 wird mit einigen geringfügigen Bugfixes in den meisten Linux-Distributionen und BSD verwendet.

Im Jahr 2007 entstand noch der Red-Hat-Fork von vixie-cron 4.1, das Cronie Projekt, und im Jahr 2009 anacron 2.3. Allerdings ist anacron kein unabhängiger cron-Daemon, er stützt sich zur Ausführung auf einen anderen cron-Daemon.

Weitere populäre Implementierungen sind dcron und fcron. dcron war das Werk von DragonFly BSD Gründer Matt Dillon, derzeit wird der Code von Jim Pryor gepflegt.

Alternativen

  • at führt Jobs (einmalig) zu einer bestimmten Uhrzeit aus.
  • anacron setzt keinen ständig laufenden Rechner voraus und prüft beim Einschalten, ob ein Job hätte ausgeführt werden müssen, und holt das mit eingestellter Verzögerung nach.
  • fcron enthält die Fähigkeiten von cron und anacron und weitergehende Optionen.
  • launchd ist der Cron-Ersatz bei macOS/Darwin.
  • Quartz ist ein Job Scheduling Framework für Java, welches eine an Cron angelehnte Syntax verwendet.
  • incron ist ein Fileevent basierter Cron.
  • systemd kann Cron unter Linux ersetzen[2]

Literatur

  • Æleen Frisch: Essential System Administration: Help for UNIX System Administrators. O’Reilly, 2002, S. 90–100.
  • Michael S. Keller: Take Command: cron: Job Scheduler. Linux J. 1999, 65es, Article 15 (September 1999). (Onlineversion)

Weblinks

Wikibooks: Linux-Praxisbuch: crontab – Lern- und Lehrmaterialien

Einzelnachweise

  1. W.R. Franta, Kurt Maly: An Efficient Data Structure for the Simulation Event Set. August 1977, abgerufen am 1. Februar 2022 (englisch).
  2. systemd.timer (30. Januar 2014)