Cron-Jobs - Tipps & Tricks

Nachfolgend erhalten Sie wichtige Hinweise zu Cron-Jobs.


Allgemein

Mittels Cron-Jobs können direkt auf dem Server, der diese ausführt, regelmäßige Aufgaben 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. Cron):

* * * * * auszuführender Befehl
| | | | |
| | | | |
| | | | +---- Wochentag (0-7) (Sonntag =0 oder =7)
| | | +------ Monat (1-12)
| | +-------- Tag (1-31)
| +---------- Stunde (0-23)
+------------ Minute (0-59)

Beispielaufrufe (Cron):

#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.

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.
  • <a href="http://www.example.com/cron.php" data-proofer-ignore>http://www.example.com/cron.php</a>: vollständige URL der Webseite, die abgerufen werden soll.

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 Cron-Job erzeugt somit weder im Fehler-, noch im Erfolgsfall eine E-Mail mit Ausgaben.

Aufruf direkt auf dem 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.

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 Cron-Job 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 Cron-Job 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 weiterer Vorteil der zweiten Methode ist - 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.