Dies ist eine kanonische Frage zur Verwendung von cron & crontab.
Sie wurden hierher geleitet, weil die Community ziemlich sicher ist, dass die Antwort auf Ihre Frage unten zu finden ist. Wenn Ihre Frage im Folgenden nicht beantwortet wird, helfen Ihnen die Antworten dabei, Informationen zu sammeln, die der Community helfen, Ihnen zu helfen. Diese Informationen sollten in Ihre ursprüngliche Frage eingearbeitet werden.
Die Antwort für ' Warum funktioniert meine Crontab nicht und wie kann ich Fehler beheben? 'kann unten gesehen werden. Dies adressiert das cron
System mit der hervorgehobenen Crontab.
Antworten:
So beheben Sie all Ihre Probleme mit Crontab (Linux)
Erstens grundlegende Terminologie:
Als nächstes Aufklärung über Cron:
Jeder Benutzer auf einem System verfügt möglicherweise über eine eigene crontab-Datei. Der Speicherort der Root- und Benutzer-Crontab-Dateien ist systemabhängig, liegt jedoch in der Regel darunter
/var/spool/cron
.Es gibt eine systemweite
/etc/crontab
Datei, das/etc/cron.d
Verzeichnis kann Crontab-Fragmente enthalten, die auch von Cron gelesen und bearbeitet werden. Einige Linux-Distributionen (z. B. Red Hat) haben/etc/cron.{hourly,daily,weekly,monthly}
auch Verzeichnisse, Skripte, die jede Stunde / Tag / Woche / Monat mit Root-Rechten ausgeführt werden.root kann immer den Befehl crontab verwenden. regulären Benutzern kann der Zugriff gewährt werden oder nicht. Wenn Sie die crontab-Datei mit dem Befehl bearbeiten
crontab -e
und speichern, überprüft crond sie auf ihre grundlegende Gültigkeit, garantiert jedoch nicht, dass Ihre crontab-Datei korrekt erstellt wurde. Es gibt eine Datei mit dem Namen,cron.deny
die angibt, welche Benutzer Cron nicht verwenden können. Dercron.deny
Dateispeicherort ist systemabhängig und kann gelöscht werden, sodass alle Benutzer cron verwenden können.Wenn der Computer nicht eingeschaltet ist oder der crond-Daemon nicht ausgeführt wird und das Datum und die Uhrzeit für die Ausführung eines Befehls abgelaufen sind, kann crond vergangene Abfragen nicht abrufen und ausführen.
crontab Angaben, wie man einen Befehl formuliert:
Ein crontab-Befehl wird durch eine einzelne Zeile dargestellt. Sie können
\
einen Befehl nicht über mehrere Zeilen erweitern. Das hash (#
) -Zeichen stellt einen Kommentar dar, was bedeutet, dass alles in dieser Zeile von cron ignoriert wird. Führende Leerzeichen und Leerzeilen werden ignoriert.Seien Sie SEHR vorsichtig, wenn Sie das Prozentzeichen (
%
) in Ihrem Befehl verwenden. Sofern sie nicht\%
maskiert werden , werden sie in Zeilenumbrüche umgewandelt und alles, was nach dem ersten nicht maskierten Zeilenumbruch%
passiert, wird auf stdin an Ihren Befehl übergeben.Es gibt zwei Formate für Crontab-Dateien:
Benutzer crontabs
Systemweit
/etc/crontab
und/etc/cron.d
FragmenteBeachten Sie, dass letzteres einen Benutzernamen erfordert. Der Befehl wird als benannter Benutzer ausgeführt.
Die ersten 5 Felder der Zeile geben die Zeiten an, zu denen der Befehl ausgeführt werden soll. In der Zeitangabe können Sie Zahlen oder ggf. Tag- / Monatsnamen verwenden.
,
) wird verwendet, um eine Liste anzugeben, z. B. 1,4,6,8, was 1,4,6,8 bedeutet.-
) angegeben und können mit Listen kombiniert werden, z. B. 1-3,9-12, dh zwischen 1 und 3, dann zwischen 9 und 12./
Zeichen kann verwendet werden, um einen Schritt einzuführen, z. B. 2/5, was bedeutet, dass bei 2 alle 5 begonnen wird (2,7,12,17,22 ...). Sie wickeln sich nicht über das Ende hinaus.*
) in einem Feld kennzeichnet den gesamten Bereich für dieses Feld (z. B.0-59
für das Minutenfeld).*/2
bedeutet beginnend mit dem Minimum für das betreffende Feld alle 2, z. B. 0 für Minuten (0,2 ... 58), 1 für Monate (1,3 ... 11) usw.Debuggen von Cron-Befehlen
Schauen Sie sich ihre E-Mails an!
Standardmäßig sendet cron alle Ausgaben des Befehls per E-Mail an den Benutzer, unter dem der Befehl ausgeführt wird. Wenn es keine Ausgabe gibt, gibt es keine Post. Wenn Sie möchten, dass cron E-Mails an ein anderes Konto sendet, können Sie die Umgebungsvariable MAILTO in der crontab-Datei festlegen, z
Erfassen Sie die Ausgabe selbst
Sie können stdout und stderr in eine Datei umleiten. Die genaue Syntax zum Erfassen der Ausgabe kann je nach verwendetem Shell-Cron variieren. Hier sind zwei Beispiele, die alle Ausgaben in einer Datei speichern
/tmp/mycommand.log
:Schauen Sie sich die Protokolle an
Cron protokolliert seine Aktionen über Syslog, das (abhängig von Ihrem Setup) häufig auf
/var/log/cron
oder zugreift/var/log/syslog
.Bei Bedarf können Sie die cron-Anweisungen mit zB filtern
Nachdem wir uns nun mit den Grundlagen von Cron befasst haben, wo sich die Dateien befinden und wie sie verwendet werden, wollen wir uns einige häufige Probleme ansehen.
Überprüfen Sie, ob cron läuft
Wenn cron nicht läuft, werden Ihre Befehle nicht eingeplant ...
sollte dir sowas besorgen
oder
Wenn nicht, starten Sie es neu
oder
Es kann andere Methoden geben; Verwenden Sie, was Ihre Distribution bietet.
cron führt Ihren Befehl in einer eingeschränkten Umgebung aus.
Welche Umgebungsvariablen verfügbar sind, ist wahrscheinlich sehr begrenzt. Normalerweise werden Sie nur wenige Variablen definiert, wie erhalten
$LOGNAME
,$HOME
und$PATH
.Besonders hervorzuheben ist die
PATH
Beschränkung auf/bin:/usr/bin
. Die überwiegende Mehrheit der Probleme mit "Mein Cron-Skript funktioniert nicht" wird durch diesen restriktiven Pfad verursacht . Wenn sich Ihr Befehl an einem anderen Ort befindet, können Sie dies auf verschiedene Arten lösen:Geben Sie den vollständigen Pfad zu Ihrem Befehl an.
Geben Sie einen geeigneten PFAD in die crontab-Datei ein
Wenn Ihr Befehl andere Umgebungsvariablen erfordert, können Sie diese auch in der crontab-Datei definieren.
cron führt Ihren Befehl mit cwd == $ HOME aus
Unabhängig davon, wo sich das von Ihnen ausgeführte Programm im Dateisystem befindet, ist das aktuelle Arbeitsverzeichnis des Programms, wenn es von cron ausgeführt wird, das Ausgangsverzeichnis des Benutzers . Wenn Sie auf Dateien in Ihrem Programm zugreifen, müssen Sie dies berücksichtigen, wenn Sie relative Pfade verwenden, oder (vorzugsweise) überall nur vollqualifizierte Pfade verwenden, und allen eine Menge Verwirrung ersparen.
Der letzte Befehl in meiner Crontab wird nicht ausgeführt
Cron verlangt im Allgemeinen, dass Befehle mit einer neuen Zeile abgeschlossen werden. Bearbeiten Sie Ihre Crontab; Gehen Sie zum Ende der Zeile, die den letzten Befehl enthält, und fügen Sie eine neue Zeile ein (drücken Sie die Eingabetaste).
Überprüfen Sie das Crontab-Format
Sie können keine benutzer-crontab-formatierte crontab für / etc / crontab oder die Fragmente in /etc/cron.d und umgekehrt verwenden. Eine vom Benutzer formatierte crontab enthält keinen Benutzernamen an der sechsten Position einer Zeile, während eine vom System formatierte crontab den Benutzernamen enthält und den Befehl als dieser Benutzer ausführt.
Ich habe eine Datei in /etc/cron.{hourly,daily,weekly,monthly} abgelegt und sie wird nicht ausgeführt
#!/bin/sh
oben setzen)Cron date bezogene Bugs
Wenn Ihr Datum kürzlich von einem Benutzer- oder Systemupdate, einer Zeitzone oder einem anderen geändert wurde, verhält sich crontab fehlerhaft und weist bizarre Fehler auf, die manchmal funktionieren, manchmal aber nicht. Dies ist der Versuch von crontab, zu versuchen, "zu tun, was Sie wollen", wenn sich die Zeit darunter ändert. Das Feld "Minute" wird unwirksam, nachdem die Stunde geändert wurde. In diesem Szenario werden nur Sternchen akzeptiert. Starten Sie cron neu und versuchen Sie es erneut, ohne eine Verbindung zum Internet herzustellen (damit das Datum nicht auf einen der Zeitserver zurückgesetzt werden kann).
Wieder Prozentzeichen
Um den Rat zu Prozentzeichen hervorzuheben, hier ein Beispiel, was cron mit ihnen macht:
erstellt die ~ / cron.out-Datei mit den 3 Zeilen
Dies ist besonders aufdringlich bei der Verwendung des
date
Befehls. Achten Sie darauf, den Prozentzeichen zu entkommenquelle
... /path/to/your/command >/tmp/mycommand.log 2>&1
sudo apt-get install postfix
Debian Linux und sein Derivat (Ubuntu, Mint usw.) weisen einige Besonderheiten auf, die möglicherweise die Ausführung Ihrer Cron-Jobs verhindern. insbesondere die Dateien in
/etc/cron.d
,/etc/cron.{hourly,daily,weekly,monthly}
müssen:Der letzte verletzt regelmäßig ahnungslose Benutzer; insbesondere jedes Skript in einem dieser Ordner genannt
whatever.sh
,mycron.py
,testfile.pl
etc. wird nicht immer ausgeführt werden.Nach meiner Erfahrung war dieser spezielle Punkt bei weitem der häufigste Grund für einen nicht ausgeführten Cronjob auf Debian und Derivaten.
Sehen Sie
man cron
für weitere Informationen, falls erforderlich.quelle
Wenn Ihre Cronjobs nicht mehr funktionieren, stellen Sie sicher, dass Ihr Kennwort nicht abgelaufen ist. Sobald dies der Fall ist, werden alle Cronjobs gestoppt.
Es werden Meldungen
/var/log/messages
ähnlich der folgenden angezeigt, die Probleme bei der Benutzerauthentifizierung aufzeigen:quelle
sudo -u root passwd
Gelegentlich und unregelmäßig
Alles in allem ist Cron ein sehr grundlegender Scheduler, und die Syntax ermöglicht es einem Administrator nicht leicht, etwas ungewöhnlichere Zeitpläne zu formulieren.
Betrachten Sie den folgenden Job, der normalerweise als "
command
alle 5 Minuten ausgeführt" bezeichnet wird :gegen:
was nicht immer
command
alle 7 Minuten läuft .Denken Sie daran , dass das /können Zeichen verwendet werden , um einen Schritt einzuführen , sondern dass Schritte wickeln nicht über das Ende einer Serie zB
*/7
die jede 7. Minute aus dem Protokoll übereinstimmt ,0-59
dh 0,7,14,21,28,35,42,49, 56 aber zwischen einer Stunde und den nächsten wird es nur 4 Minuten zwischen den Chargen , nachdem00:56
eine neue Serie startet bei01:00
,01:07
usw. (und Chargen werden nicht ausgeführt auf01:03
,01:10
,01:17
etc.).Was ist stattdessen zu tun?
Erstellen Sie mehrere Stapel
Erstellen Sie anstelle eines einzelnen Cron-Jobs mehrere Stapel, die zusammen den gewünschten Zeitplan ergeben.
Um beispielsweise alle 40 Minuten einen Stapel auszuführen (00:00, 00:40, 01:20, 02:00 usw.), erstellen Sie zwei Stapel, von denen einer zweimal zu geraden und der andere nur zu ungeraden Stunden ausgeführt wird:
Führen Sie Ihre Stapel weniger häufig aus
Anstatt Ihren Stapel alle 7 Minuten auszuführen, was ein schwieriger Zeitplan für die Aufteilung in mehrere Stapel ist, führen Sie ihn stattdessen einfach alle 10 Minuten aus.
Starten Sie Ihre Stapel häufiger (aber verhindern Sie, dass mehrere Stapel gleichzeitig ausgeführt werden)
Viele ungewöhnliche Zeitpläne entwickeln sich, weil die Stapellaufzeiten zunehmen / schwanken und die Stapel dann mit einer zusätzlichen Sicherheitsmarge geplant werden, um zu verhindern, dass sich nachfolgende Läufe desselben Stapels überlappen und gleichzeitig ausgeführt werden.
Denken Sie stattdessen anders und erstellen Sie einen Cronjob, der ordnungsgemäß fehlschlägt, wenn ein vorheriger Lauf noch nicht abgeschlossen ist, der jedoch ansonsten ausgeführt wird. Lesen Sie diese Fragen und Antworten :
Damit wird fast sofort ein neuer Lauf gestartet, sobald der vorherige Lauf von / usr / local / bin / frequent_cron_job abgeschlossen ist.
Starten Sie Ihre Stapel häufiger (aber beenden Sie sie ordnungsgemäß, wenn die Bedingungen nicht stimmen).
Da die Cron-Syntax eingeschränkt ist, können Sie entscheiden, komplexere Bedingungen und Logik im Stapeljob selbst (oder in einem Wrapper-Skript um den vorhandenen Stapeljob herum) zu platzieren. Auf diese Weise können Sie die erweiterten Funktionen Ihrer bevorzugten Skriptsprachen nutzen, Ihren Code kommentieren und schwer lesbare Konstrukte im crontab-Eintrag selbst vermeiden.
In bash
seven-minute-job
würde das dann ungefähr so aussehen:Was Sie dann sicher (versuchen) können, jede Minute zu laufen:
Ein anderes, aber ähnliches Problem würde eine Charge planen am ersten Montag eines jeden Monats (oder zweiten Mittwoch) usw. einfach plant den Stapel laufen jeden Montag und Ausgang zu laufen , wenn Datum weder zwischen dem 1 st oder 7 th und der Wochentag ist nicht Montag.
Was Sie dann sicher (versuchen) können, jeden Montag auszuführen:
Verwenden Sie kein Cron
Wenn Ihre Anforderungen komplex sind, sollten Sie ein fortschrittlicheres Produkt verwenden, das für die Ausführung komplexer Zeitpläne (verteilt auf mehrere Server) ausgelegt ist und Trigger, Jobabhängigkeiten, Fehlerbehandlung, Wiederholungsversuche und Wiederholungsüberwachung usw. unterstützt. Die Fachsprache lautet "Unternehmen" " Job Scheduling und / oder" Workload Automation ".
quelle
PHP-spezifisch
Wenn du einen Cron Job hast wie:
Und im Falle von Fehlern erwarten Sie, dass sie an Sie gesendet werden, aber sie nicht - überprüfen Sie dies.
PHP sendet standardmäßig keine Fehler an STDOUT. @siehe https://bugs.php.net/bug.php?id=22839
Um dies zu beheben, fügen Sie in cli`s php.ini oder in Ihrer Zeile (oder in Ihrem Bash-Wrapper für PHP) Folgendes hinzu:
Mit der ersten Einstellung können Sie Fatals wie 'Memory oops' und mit der zweiten Einstellung alle nach STDERR umleiten. Erst wenn Sie gut schlafen können, werden alle an die Mail Ihres Roots gesendet, anstatt nur angemeldet zu sein.
quelle
Hinzufügen meine Antwort von hier der Vollständigkeit halber, und das Hinzufügen eines weiteren potenziell hilfreiche Ressource:
Der
cron
Benutzer hat eine andere$PATH
als Sie:Ein häufiges Problem, das Benutzer bei
crontab
Eingaben machen, besteht darin, dass sie vergessen, dasscron
eine andereenvironment
als die als angemeldete Benutzer ausgeführt wird. Ein Benutzer erstellt beispielsweise ein Programm oder ein Skript in seinem$HOME
Verzeichnis und gibt den folgenden Befehl ein, um es auszuführen:Der Befehl läuft perfekt von seiner Kommandozeile aus. Der Benutzer fügt dann diesen Befehl zu seinem hinzu
crontab
, stellt jedoch fest, dass dies nicht funktioniert:In diesem Fall liegt der Grund für den Fehler darin, dass
./
dercron
Benutzer einen anderen Speicherort als der angemeldete Benutzer hat. Das heißt, dasenvironment
ist anders! Der PFAD ist ein Teil vonenvironment
, und er ist normalerweise für dencron
Benutzer unterschiedlich. Dieses Problem wird dadurch erschwert, dass dasenvironment
forcron
nicht für alle * nix- Distributionen gleich ist und es mehrere Versionen von gibtcron
Eine einfache Lösung für dieses spezielle Problem besteht darin, dem
cron
Benutzer imcrontab
Eintrag eine vollständige Pfadangabe zu geben :Was ist der
cron
Benutzerenvironment
?In einigen Fällen müssen wir möglicherweise die vollständigen
environment
Spezifikationen fürcron
unser System kennen (oder wir sind einfach nur neugierig). Was ist dasenvironment
für dencron
Benutzer und wie unterscheidet es sich von unserem? Ferner müssen wir die wissen ,environment
für einen anderencron
Benutzer -root
zum Beispiel ... was das ist desroot
Benutzersenvironment
verwendetcron
? Eine Möglichkeit, dies zu lernen, bestehtcron
darin, uns Folgendes mitzuteilen:~/
) wie folgt (oder mit dem Editor Ihrer Wahl):/home/you/envtst.sh.out
. Diese Ausgabe zeigt Ihre aktuelle Umgebung an, als die$USER
Sie angemeldet sind als:crontab
zum Bearbeiten:crontab
:ANTWORT: Die Ausgabedatei
/home/you/envtst.sh.out
enthält eine Auflistung derenvironment
für den "root cron user". Wenn Sie das wissen, passen Sie Ihrecrontab
Eingabe entsprechend an.Ich kann den Zeitplan, den ich benötige, in meinem
crontab
Eintrag nicht angeben :Der Zeitplaneintrag für
crontab
ist natürlich in definiertman crontab
, und Sie sollten dies lesen. Das Lesenman crontab
und Verstehen des Zeitplans sind jedoch zwei verschiedene Dinge. Das Ausprobieren einer Zeitplanspezifikation kann sehr mühsam werden. Glücklicherweise gibt es eine Ressource, die helfen kann: den Crontab-Guru. . Geben Sie Ihre Zeitplanspezifikation ein und es wird der Zeitplan in einfacher englischer Sprache erklärt.Denken Sie nicht, dass Sie sich auf einen einzelnen
crontab
Eintrag beschränken, da Sie nur einen Job zu erledigen haben. Sie können beliebig vielecrontab
Einträge verwenden, um den gewünschten Zeitplan zu erhalten.quelle