Frage Warum funktioniert meine Crontab nicht, und wie kann ich sie beheben?


Das ist ein Kanonische Frage über die 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 unten nicht beantwortet wird, helfen Ihnen die Antworten dabei, Informationen zu sammeln, die der Community helfen. Diese Informationen sollten in Ihrer ursprünglichen Frage bearbeitet werden.

Die Antwort für 'Warum funktioniert meine Crontab nicht, und wie kann ich sie beheben?'kann unten gesehen werden. Dies adressiert die cron System mit der Crontab hervorgehoben.


193
2017-11-17 04:51


Ursprung


Dies ist eine große Täuschung von Gründe, warum Crontab nicht funktioniert auf AskUbuntu. - Dan Dascalescu


Antworten:


Wie behebe ich alle deine Crontab-Probleme / Probleme (Linux)


Das ist ein Community-WikiWenn Sie mit dieser Antwort etwas falsch finden oder zusätzliche Informationen haben, dann bearbeiten Sie sie bitte.


Zunächst grundlegende Terminologie:

  • Cron (8) ist der Daemon, der geplante Befehle ausführt.
  • Crontab (1) ist das Programm, um Benutzer Crontab (5) Dateien zu ändern.
  • Crontab (5) ist eine Benutzerdatei, die Anweisungen für cron (8) enthält.

Weiter, Bildung über Cron:

Jeder Benutzer eines Systems kann eine eigene Crontab-Datei haben. Der Speicherort der root- und user-crontab-Dateien hängt vom System ab, liegt jedoch im Allgemeinen darunter /var/spool/cron.

Es gibt ein systemweites /etc/crontab Datei, die /etc/cron.d Verzeichnis kann Crontab-Fragmente enthalten, die auch von Cron gelesen und bearbeitet werden. Einige Linux-Distributionen (zB Red Hat) haben auch /etc/cron.{hourly,daily,weekly,monthly} Dies sind Verzeichnisse, in denen Skripte jede Stunde / Tag / Woche / Monat mit root-Rechten ausgeführt werden.

root kann immer den Befehl crontab verwenden; Regelmäßige Benutzer können Zugriff erhalten oder nicht. Wenn Sie die Crontab-Datei mit dem Befehl bearbeiten crontab -e und speichern Sie es, crond prüft es auf Grundgültigkeit, garantiert aber nicht, dass Ihre Crontab-Datei korrekt erstellt wurde. Es gibt eine Datei namens cron.deny welches spezifiziert, welche Benutzer cron nicht benutzen können. Das cron.deny Der Speicherort der Datei 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 / die Uhrzeit für die Ausführung eines Befehls verstrichen ist, wird crond nicht aufholen und vorherige Abfragen ausführen.

crontab Besonderheiten, wie man einen Befehl formuliert:

Ein Crontab-Befehl wird durch eine einzelne Zeile dargestellt. Sie können nicht verwenden \ um einen Befehl über mehrere Zeilen zu erweitern. Der Hash (#) sign stellt einen Kommentar dar, der bedeutet, dass alles in dieser Zeile von cron ignoriert wird. Führende Leerzeichen und Leerzeilen werden ignoriert.

Seien Sie sehr vorsichtig, wenn Sie den Prozentsatz verwenden (%) signiere deinen Befehl. Es sei denn, sie sind entkommen \% Sie werden in Zeilenumbrüche umgewandelt und alles nach dem ersten nicht maskiert % wird an stdin übergeben.

Es gibt zwei Formate für Crontab-Dateien:

  • Benutzer crontabs

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  *   command to be executed
    
  • Systemweit /etc/crontab und /etc/cron.d Fragmente

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  * user-name  command to be executed
    

Beachten Sie, dass für Letzteres ein Benutzername erforderlich ist. Der Befehl wird als benannter Benutzer ausgeführt.

Die ersten 5 Felder der Linie repräsentieren die Zeit (s), wann der Befehl ausgeführt werden sollte. Sie können in der Zeitangabe Nummern oder ggf. Tag- / Monatsnamen verwenden.

  • Die Felder sind durch Leerzeichen oder Tabulatoren getrennt.
  • Ein Komma (,) wird verwendet, um eine Liste zu spezifizieren, z. B. 1,4,6,8, was bedeutet, bei 1,4,6,8 zu laufen.
  • Bereiche sind mit einem Bindestrich angegeben (-) und kann mit Listen kombiniert werden, z. 1-3,9-12 was bedeutet zwischen 1 und 3 dann zwischen 9 und 12.
  • Das / Zeichen kann verwendet werden, um einen Schritt z.B. 2/5, also beginnend mit 2, dann alle 5 (2,7,12,17,22 ...). Sie wickeln sich nicht über das Ende hinaus.
  • Ein Sternchen (*) in einem Feld bedeutet den gesamten Bereich für dieses Feld (z.B. 0-59 für das Minutenfeld).
  • Bereiche und Schritte können z.B. */2 bedeutet, beginnend mit dem Minimum für das relevante Feld dann alle 2, z. 0 für Minuten (0,2 ... 58), 1 für Monate (1,3 ... 11) usw.

Cron-Befehle debuggen

Schauen Sie sich ihre E-Mails an! Standardmäßig sendet cron eine Ausgabe des Befehls an den Benutzer, bei dem der Befehl ausgeführt wird. Wenn es keine Ausgabe gibt, wird es keine Mail geben. Wenn Sie möchten, dass cron E-Mails an ein anderes Konto sendet, können Sie die Umgebungsvariable MAILTO in der Crontab-Datei z.

MAILTO=user@somehost.tld
1 2 * * * /path/to/your/command

Erfassen Sie die Ausgabe selbst

1 2 * * *  /path/to/your/command &>/tmp/mycommand.log

die stdout und stderr in /tmp/mycommand.log erfasst

Sieh dir die Protokolle an. cron protokolliert seine Aktionen über syslog, die (abhängig von Ihrer Einrichtung) oft zu gehen /var/log/cron oder /var/log/syslog.

Bei Bedarf können Sie die Cron-Anweisungen mit z.

grep CRON /var/log/syslog 

Jetzt, wo wir die Grundlagen von cron besprochen haben, wo die Dateien sind und wie sie verwendet werden, schauen wir uns einige allgemeine Probleme an.

Überprüfen Sie, ob Cron ausgeführt wird

Wenn cron nicht läuft, werden Ihre Befehle nicht geplant ...

ps -ef | grep cron | grep -v grep

sollte dich etwas wie bekommen

root    1224   1  0 Nov16 ?    00:00:03 cron

oder

root    2018   1  0 Nov14 ?    00:00:06 crond

Wenn es nicht neu gestartet wird

/sbin/service cron start

oder

/sbin/service crond start

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. In der Regel werden nur einige Variablen definiert, z $LOGNAME, $HOME, und $PATH.

Besonders hervorzuheben ist die PATH ist beschränkt auf /bin:/usr/bin. Die überwiegende Mehrheit der Probleme "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:

  1. Geben Sie den vollständigen Pfad zu Ihrem Befehl an.

    1 2 * * * /path/to/your/command
    
  2. Geben Sie einen geeigneten PATH in der Crontab-Datei an

    PATH=/usr:/usr/bin:/path/to/something/else
    1 2 * * * command 
    

Wenn Ihr Befehl andere Umgebungsvariablen benötigt, können Sie diese auch in der Crontab-Datei definieren.

cron führt deinen Befehl mit cwd == $ HOME aus

Unabhängig davon, wo sich das Programm, das Sie ausführen, auf dem Dateisystem befindet, ist das aktuelle Arbeitsverzeichnis des Programms, wenn Cron es ausführt das Home-Verzeichnis des Benutzers. Wenn Sie auf Dateien in Ihrem Programm zugreifen, müssen Sie dies berücksichtigen, wenn Sie relative Pfade verwenden oder (vorzugsweise) einfach vollqualifizierte Pfade überall verwenden und allen eine Menge Verwirrung ersparen.

Der letzte Befehl in meiner Crontab läuft nicht

Cron erfordert normalerweise, dass Befehle mit einer neuen Zeile beendet werden. Editiere deine Crontab; gehe an das Ende der Zeile, die den letzten Befehl enthält, und füge eine neue Zeile ein (Enter drücken).

Überprüfen Sie das Crontab-Format

Sie können keine Crontab-formatierte Crontab-Benutzerdatei für / etc / crontab oder die Fragmente in /etc/cron.d verwenden und umgekehrt. Eine vom Benutzer formatierte Crontab enthält keinen Benutzernamen an der sechsten Position einer Zeile, während eine systemdefinierte Crontab den Benutzernamen enthält und den Befehl als diesen Benutzer ausführt.

Ich lege eine Datei in /etc/cron.{hourly,daily,weekly,monthly} und es läuft nicht

  • Überprüfen Sie, ob der Dateiname keine Erweiterung hat Laufteile
  • Stellen Sie sicher, dass die Datei über Ausführungsberechtigungen verfügt.
  • Teilen Sie dem System mit, was Sie bei der Ausführung Ihres Skripts verwenden sollen (z. B. put #!/bin/sh an der Spitze)

Cron-Datum bezogene Fehler

Wenn Ihr Datum kürzlich durch einen Benutzer oder ein Systemupdate, eine Zeitzone oder anderes geändert wurde, wird sich crontab unberechenbar verhalten und seltsame Fehler aufweisen, die manchmal funktionieren, manchmal nicht. Dies ist der Versuch von crontab, "zu tun, was Sie wollen", wenn die Zeit darunter verschwindet. Das Feld "Minute" wird nach dem Ändern der Stunde unwirksam. In diesem Szenario werden nur Sternchen akzeptiert. Starten Sie Cron neu und versuchen Sie es erneut, ohne eine Verbindung zum Internet herzustellen (das Datum hat also keine Chance, auf einen der Zeitserver zurückzusetzen).

Prozentzeichen wieder

Um den Hinweis auf Prozentzeichen zu betonen, hier ist ein Beispiel dafür, was Cron mit ihnen macht:

# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz

erstellt die ~ / cron.out-Datei mit den drei Zeilen

foo
bar
baz

Dies ist besonders aufdringlich bei der Verwendung der date Befehl. Achten Sie darauf, den Prozentzeichen zu entgehen

* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"

273
2017-10-09 15:29



Möglicherweise möchten Sie auch im Abschnitt 'eingeschränkte Umgebung' erwähnen, dass LD_LIBRARY_PATH möglicherweise zusätzliche Verzeichnisse für den Fall, dass Ihre Cron-Task fehlschlägt, benötigt, da keine gemeinsam genutzten Bibliotheken gefunden werden können. - DavidJ
Beachten Sie, dass Sie sogar so etwas schreiben können: 35 1,5-23 / 2 * * * do_something statt 35,1,5,7,9, .. * * * Zusätzlich dazu crontab.guru übersetzt die von Ihnen gemachten Eingaben in die menschliche Sprache. - Dennis Nolte
Die Ausgabeerfassung funktioniert bei mir nicht, möglicherweise wegen der sh-Shell. Ich denke, das ist tragbarer: ... /path/to/your/command >/tmp/mycommand.log 2>&1 - chus
das hat bei mir funktioniert: sudo apt-get install postfix - jmunsch
hängt der Cron-Job auch davon ab, wie schwer die Datei ist? Weil ich einfach Hallo Welt in Python mit Cron lief, hat es funktioniert. Aber mein zweiter Code war ein bisschen schwer und läuft normalerweise, aber mit Cron gibt es keine Ausgabe in die Datei. - Devendra Bhat


Wenn Ihre Cronjobs nicht mehr funktionieren, vergewissern Sie sich, dass Ihr Passwort nicht abgelaufen ist. Seit diesem Zeitpunkt stoppen alle Cronjobs.
Es wird Nachrichten geben /var/log/messages ähnlich wie die folgende, die Probleme mit der Authentifizierung des Benutzers zeigen:

(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)


18
2018-02-04 20:29



Ich habe es auch bekommen (Fehlermeldung Datei / var / log / syslog für mich). In meinem Fall eine DigitalOcean-Box, die zum Zeitpunkt der Erstellung das root-Passwort (optional) auf ein anderes zurücksetzt, und anscheinend, bis Sie dort hineingehen und es ändern, werden alle Cron-Jobs nicht ausgeführt. Bummel. Fix ist so etwas wie sudo -u root passwd - rogerdpack


Debian Linux und seine Derivate (Ubuntu, Mint usw.) haben einige Besonderheiten, die die Ausführung Ihrer Cron-Jobs verhindern können; insbesondere die Dateien in /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly} Muss :

  • im Besitz von root sein
  • nur von root beschreibbar sein
  • nicht für Gruppen oder andere Benutzer schreibbar sein
  • habe einen Namen ohne Punkte '.' oder irgendein anderes Sonderzeichen außer '-' und '_'.

Der letzte schmerzt regelmäßig ahnungslose Benutzer; insbesondere jedes Skript in einem dieser Ordner namens whatever.sh, mycron.py, testfile.plusw. wird nicht jemals ausgeführt werden.

Meiner Erfahrung nach war dieser spezielle Punkt bei weitem der häufigste Grund für einen nicht-ausführenden Cronjob auf Debian und Derivaten.

Sehen man cron für weitere Details, falls erforderlich.


15
2017-11-17 14:37





Gelegentliche und unregelmäßige Zeitpläne

Cron wird alles als ein sehr einfacher Scheduler angesehen und die Syntax erlaubt einem Administrator nicht leicht, etwas ungewöhnlichere Zeitpläne zu formulieren.

Betrachten Sie die folgende Aufgabe, die allgemein erklärt werden würde "Lauf command alle 5 Minuten ":

*/5 * * * * /path/to/your/command

gegen:

*/7 * * * * /path/to/your/command

welche nicht immer Lauf command alle 7 Minuten.

Denken Sie daran, dass die / Zeichen können verwendet werden, um einen Schritt einzuführen, aber die Schritte werden nicht über das Ende einer Reihe, z. */7 was entspricht jeder 7. Minute aus den Minuten 0-59  d.h. 0,7,14,21,28,35,42,49,56 aber zwischen einer Stunde und der nächsten es wird____geben nur 4 Minuten zwischen den Chargen, nach dem 00:56 eine neue Serie beginnt um 01:00, 01:07 usw. (und Chargen laufen nicht weiter 01:03 , 01:10 , 01:17 usw.).


Was ist stattdessen zu tun?

Erstellen Sie mehrere Stapel

Erstellen Sie anstelle eines einzelnen Cron-Jobs mehrere Batches, die zusammen den gewünschten Zeitplan ergeben.

Wenn Sie beispielsweise alle 40 Minuten eine Charge laufen lassen (00:00, 00:40, 01:20, 02:00 usw.), erstellen Sie zwei Chargen, eine, die zweimal in den geraden Stunden läuft, und eine zweite, die nur die ungeraden Stunden ausführt:

# The following lines create a batch that runs every 40 minutes i.e.

# runs on   0:00, 0:40,        02:00, 02:40         04:00 etc to 22:40
0,40 */2 * * * /path/to/your/command

# runs on               01:20,               03:20,       etc to 23:20
20 1/2 * * * /path/to/your/command

# Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.

Führen Sie Ihre Chargen seltener aus 

Anstatt den Batch alle 7 Minuten auszuführen, was ein schwieriger Zeitplan für mehrere Batches ist, führen Sie ihn stattdessen alle 10 Minuten aus.

Führen Sie Ihre Chargen häufiger aus 

Viele ungerade Zeitpläne entstehen, weil die Laufzeiten des Stapels steigen / schwanken und die Batches dann mit einem zusätzlichen Sicherheitsabstand geplant werden, um zu verhindern, dass sich nachfolgende Läufe desselben Stapels überschneiden und gleichzeitig laufen.

Denken Sie anders darüber nach und erstellen Sie einen Cronjob, der ordnungsgemäß fehlschlägt, wenn ein vorheriger Lauf noch nicht beendet ist, aber ansonsten ausgeführt wird. Sieh dir das an Fragen und Antworten:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job --minutely

In ähnlicher Weise können Sie den Zeitstempel des letzten erfolgreichen Laufs stapelweise aufzeichnen und zu Beginn der Stapelprüfung überprüfen, ob das gewünschte Intervall zwischen den Stapeln bereits verstrichen ist und ausgeführt wird und andernfalls ordnungsgemäß beendet wird.

In der Bash die seven-minute-job würde ungefähr so ​​aussehen:

#!/bin/bash
# seven-minute-job
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
    echo "The minimum interval of 7 minutes between successive batches hasn't passed yet."
    exit
fi

echo "Start running your batch"

date > /tmp/lastrun

Welche Sie dann sicher (versuchen) können, um jede Minute zu laufen:

* * * * * /path/to/your/seven-minute-job

Verwenden Sie nicht Cron

Wenn Ihre Anforderungen komplex sind, sollten Sie ein fortschrittlicheres Produkt verwenden, das komplexe Zeitpläne erstellt (verteilt auf mehrere Server) und Trigger, Jobabhängigkeiten, Fehlerbehandlung, Überwachungsversuche usw. unterstützt. Der Fachjargon lautet "Enterprise". Arbeit planen und / oder "Workload Automation".


10
2017-10-23 04:45





PHP-spezifisch

Wenn Sie einen Cron-Job haben wie:

php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log

Und im Falle von Fehlern erwarten, dass sie an Sie gesendet werden, aber sie nicht - überprüfen Sie dies.

PHP sendet standardmäßig keine Fehler an STDOUT. @sehen https://bugs.php.net/bug.php?id=22839

Um das zu beheben, fügen Sie in der php.ini oder in Ihrer Zeile (oder in Ihrem bash Wrapper für PHP) diese hinzu:

  • --define display_startup_errors = 1
  • --define display_errors = 'stderr'

Die erste Einstellung ermöglicht es Ihnen, Fatals wie "Memory oops" und "2nd" zu haben, um alle auf STDERR umzuleiten. Nur nachdem Sie gut schlafen können, werden alle an die E-Mail-Adresse Ihres Roots gesendet und nicht nur protokolliert.


8



Dieser Fehlerbericht wurde 2007 mit dem Status geschlossen, dass der Patch den PHP 5.2 + -Zweigen hinzugefügt wurde. Bist du sicher, dass das nötig ist? Ich habe gerade PHP 5.4 getestet und es scheint gut zu funktionieren. (Es wird jedoch immer noch für PHP 4 benötigt). - Xeoncross
@Xeoncross siehe Datum der Antwort :) - gaRex
Ja, das hat mich verwirrt, seit du 2013 geantwortet hast und das Ticket war 2007 zurück. - Xeoncross