Allgemeines zu Cronjobs
Mittels Cronjobs können Aufgaben direkt auf dem Server, der diese ausführt, regelmäßig durchgeführt werden.
Anwendungen können beispielsweise der Versand von täglichen E-Mails, Geburtstags-Erinnerungen oder auch regelmäßige Wartungsaufgaben (Leeren von Caches, Benutzer-Löschungen, …) sein.
Dabei wird ein Programm angegeben, das zu definierten Zeiten mit den Rechten des Benutzers ausgeführt wird.
Die Ausgabe davon verschickt der Cron-Daemon via E-Mail an den ausführenden Benutzer.
Der Zeitpunkt wird mit fünf Parametern angegeben, die aus Zahlen oder einem “’*“‘ bestehen dürfen((vgl. [[wpde>cron]])):
* * * * * auszuführender Befehl
| | | | |
| | | | |
| | | | +---- Wochentag (0-7) (Sonntag =0 oder =7)
| | | +------ Monat (1-12)
| | +-------- Tag (1-31)
| +---------- Stunde (0-23)
+------------ Minute (0-59)
Beispielaufrufe:
#M S T M W Befehl
5 * * * * /usr/bin/message.sh #Befehl wird fünf Minuten nach jeder vollen Stunde aufgerufen.
*/5 * * * * /usr/bin/message.sh #Befehl wird alle 5 Minuten aufgerufen (die Schrittweite wird durch */Schrittweite angegeben).
59 23 * * 0 gzip /var/log/messages #Befehl wird einmal pro Woche sonntags um 23:59 Uhr ausgeführt.
0 0 * * * gzip /var/log/auth.log #Befehl wird täglich um 00:00 Uhr ausgeführt.
20,30 1 * * 1-5 /usr/bin/work.sh #Befehl wird montags bis freitags jeweils um 01:20 und 01:30 ausgeführt.
0 1 1-7 12 1 /usr/bin/work.sh #Befehl wird am 1. bis 7. Dezember sowie an jedem Montag im Dezember um ein Uhr nachts ausgeführt.
Regelmäßiger Aufruf von PHP-Skripten
Sollen PHP-Skripte ausgeführt werden, so gibt es zwei Alternativen:
- Aufruf des PHP-Skriptes als Webseite über HTTP: Dies ist eine einfache Methode, die keine weiteren Anpassungen benötigt. Allerdings kommt es zu Fehlern, falls der Webserver aus irgendwelchen Gründen gerade nicht erreichbar ist.
- Aufruf des PHP-Skriptes direkt: Hier wird PHP auf dem Server ausgeführt, welches dann den Pfad zum Skript übergeben bekommt. Dieser Aufruf ist zu bevorzugen, da diverse Beschränkungen beim Aufruf von PHP-Skripten wegfallen, benötigt allerdings auch Anpassungen.
Diese beiden Methoden sind äquivalent – in beiden Fällen wird das Skript regelmäßig ausgeführt.
Aufruf über HTTP
Beispielabruf:
/usr/bin/wget -O/dev/null -q "http://www.example.com/cron.php" &>/dev/null
Erläuterungen:
- “’/usr/bin/wget“‘: Programm, um Webseiteninhalte abzurufen
- “‘-O/dev/null“‘: der Inhalt, der abgerufen wurde, wird nach “’/dev/null“‘ geschrieben – und somit ignoriert
- “‘-q“‘: wget erzeugt keine Ausgaben, außer bei Fehlern
- “'“http://www.example.com/cron.php““‘: vollständige URL der Webseite, die abgerufen werden soll. Achtung: es muss die vollständige URL angegeben werden, nur “’/cron.php“‘ oder “’www.example.com“‘ ist nicht ausreichend! Außerdem muss die URL in Anführungszeichen hinterlegt werden, da andernfalls nur Teile davon tatsächlich verwendet werden!
- “’&>/dev/null“‘: Leite alle Ausgaben von wget nach /dev/null, so dass diese auch ignoriert werden
Dieser Cronjob erzeugt somit weder im Fehler-, noch im Erfolgsfall eine E-Mail mit Ausgaben.
Aufruf direkt vom Server
Folgender Aufruf kann hier verwendet werden:
/usr/bin/php -f /var/www/web0/html/example.com/cron.php
Erläuterungen:
- “’/usr/bin/php“‘: vollständiger Pfad zu PHP bzw. den PHP-Binaries
- “‘-f“‘: es folgt eine Datei, die PHP ausführen soll. Somit werden keine HTTP-Header generiert
- “’/var/www/web0/html/example.com/cron.php“‘: der vollständige Pfad zum PHP-Skript, das ausgeführt werden soll (vgl. [[sharedhosting:absoluter_pfad]]).
Dieser Aufruf ist unabhängig vom Zustand des Webservers. Auch existieren einige Beschränkungen, die auf PHP-Aufrufe per HTTP zutreffen, hier nicht.
Damit dies fehlerfrei funktioniert, sollte allerdings der Cronjob noch ergänzt werden.
Das PHP-Skript wird dabei ohne Pfadangabe aufgerufen. Dies hat insbesondere dann Auswirkungen, wenn andere Skripte über “’include()“‘ oder “’require()“‘ nachgeladen werden. Ist hier nur der relative Pfad angegeben (“‘./includes/db.php“‘), so klappt zwar ein Test per HTTP, der Cronjob schlägt allerdings fehl.
Um dieses Problem zu lösen, sollten entweder alle Pfade absolut über einen Basis-Pfad o.ä. angegeben werden:
<?php
define('BASEPATH', '/var/www/web0/html/example.com');
require_once(BASEPATH . '/includes/db.php');
Oder es wird vor allen anderen Aufrufen direkt am Anfang veranlasst, dass PHP ins ‚richtige‘ Arbeitsverzeichnis wechselt:
<?php
chdir(dirname(__FILE__));
require_once('./includes/db.php');
- “’chdir()“‘: Wechsle das aktuelle Arbeitsverzeichnis
- “’dirname()“‘: gib den Verzeichnisnamen zurück (im Gegensatz zu “’basename()“‘, welches nur den Dateinamen zurückgibt)
- “’_ FILE _“‘: dies ist eine Konstante, die von PHP immer mit dem absoluten Pfad zur aktuellen Datei gefüllt wird.
Ein weitere Vorteil der zweiten Methode – im Gegensatz zur weit verbreiteten Methode, den Pfad zum PHP-Skript direkt im Crontab einzutragen: das PHP-Skript muss nicht ausführbar gemacht werden. Das PHP-Binary selbst wird durch Cron aufgerufen und erhält lediglich den Pfad zum PHP-Skript als Parameter übergeben.