Frage Warum funktionieren Crontab-Skripte nicht?


Häufig, crontab Skripte werden nicht wie geplant oder wie erwartet ausgeführt. Dafür gibt es zahlreiche Gründe:

  1. falsche Crontab-Notation
  2. Berechtigungsproblem
  3. Umgebungsvariablen

Dieses Community - Wiki zielt darauf ab, die wichtigsten Gründe für crontab Skripte werden nicht wie erwartet ausgeführt. Schreibe jeden Grund in eine separate Antwort.

Bitte geben Sie einen Grund pro Antwort an - Details darüber, warum sie nicht ausgeführt wird - und beheben Sie diesen Grund.

Bitte schreibe nur cron-spezifische Probleme, z.B. Befehle, die wie erwartet von der Shell ausgeführt werden, aber fälschlicherweise von Cron ausgeführt werden.


454


Ursprung


Sie müssen schließen crontab -e damit der Cron wirkt. Zum Beispiel mit vim bearbeite ich die Datei und benutze sie :w um es zu schreiben, aber der Job wird nicht zu Cron hinzugefügt, bis ich auch aufhöre. Also werde ich den Job erst nach mir sehen :q ebenfalls. - DutGRIFF
Ich denke, der beste Weg, Cron zu debuggen, ist Syslog zu überprüfen und die Probleme zu finden. - Suneel Kumar
In meinem Fall - die E-Mail ging in meinen SPAM-Ordner, also ..... überprüfe das, bevor du Stunden mit dem Debugging verbringst: D - almaruf
Stromausfälle - Josef Klimuk


Antworten:


Andere Umgebung

Cron übergibt einen minimalen Satz von Umgebungsvariablen an Ihre Jobs. Um den Unterschied zu sehen, fügen Sie einen Dummy-Job wie folgt hinzu:

* * * * * env> /tmp/env.output

Warten auf /tmp/env.output erstellt werden, entfernen Sie den Job erneut. Vergleichen Sie nun den Inhalt von /tmp/env.output mit der Ausgabe von env Lauf in deinem normalen Terminal.

Ein gewöhnlicher "Gotcha" ist hier der PATH Umgebungsvariable ist unterschiedlich. Vielleicht benutzt dein Cron-Skript den Befehl somecommand gefunden in /opt/someApp/bin, dem du hinzugefügt hast PATH im /etc/environment? Cron ignoriert PATH aus dieser Datei, so runnning somecommand von Ihrem Skript wird bei der Ausführung mit Cron fehlschlagen, aber funktionieren, wenn es in einem Terminal ausgeführt wird. Es ist erwähnenswert, dass Variablen von /etc/environment Wird an Cron-Jobs übergeben, nur nicht die Variablen, die Cron sich selbst setzt, wie z PATH.

Um das zu umgehen, stellen Sie einfach Ihre eigenen ein PATH Variable am Anfang des Skripts. Z.B.

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

Manche ziehen es vor, nur absolute Pfade zu allen Befehlen zu verwenden. Ich empfehle das nicht. Überlegen Sie, was passiert, wenn Sie Ihr Skript auf einem anderen System ausführen möchten und der Befehl auf diesem System aktiviert ist /opt/someAppv2.2/bin stattdessen. Sie müssten das gesamte Skript ersetzen /opt/someApp/bin mit /opt/someAppv2.2/bin anstatt nur einen kleinen Schnitt in der ersten Zeile des Skripts zu machen.

Sie können die Variable PATH auch in der Crontab-Datei festlegen, die für alle Cron-Jobs gilt. Z.B.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

431



Ich glaube, ich bin einfach darauf hereingefallen, und Newline am Ende ... Doppel-Whammy. - WernerCD
+1 für envIch hatte diesen Befehl komplett vergessen und dachte, dass PATH funktionierte. In meinem Fall war es tatsächlich ganz anders. - Izkata
@pbr Wenn solche Verzeichnisse für andere schreibbar bleiben, ist das System bereits kompromittiert. - geirha
@ pbr Ein Systemadministrator konnte das Root-Dateisystem unwissentlich löschen. Sie können sich nicht davor schützen, dass Systemadministratoren dumme Fehler machen. Wenn Sie eine neuere Version eines Interpreters installieren, der nicht abwärtskompatibel ist, würde ich trotzdem einen Bruch erwarten. Der vernünftige Weg, dies zu handhaben, ist es, es als einen anderen Befehl zu installieren. Z.B. Sie haben Python-Version 2.x und Python 3 installieren, installieren Sie es als Python3, nicht Python. Und wie für / opt / someApp / bin, warum in aller Welt hätte es nicht vernünftige Berechtigungen / Besitzrechte? Jeder vernünftige Administrator würde vernünftige Berechtigungen / Besitzrechte für Systemdateien gewährleisten. - geirha
@pbr Es scheint, wir könnten ewig weitermachen, ja. Ich verstehe immer noch nicht, warum es eine schlechte Idee ist, PATH zu verwenden. Wenn Sie darüber in einem Medium diskutieren möchten, das besser zur Diskussion geeignet ist, finden Sie mich unter anderem in #ubuntu und #bash auf irc.freenode.net - geirha


Mein Top - Tipp: Wenn Sie vergessen, am Ende der Zeile einen Zeilenumbruch hinzuzufügen crontab Datei. Mit anderen Worten, die Crontab-Datei sollte mit einer leeren Zeile enden.

Unten ist der relevante Abschnitt in den man-Seiten für diese Ausgabe (man crontab dann zum Ende springen):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

291



Das ist solch ein Showstopper, wie kommt es, dass es in so vielen Jahren von Cron nicht repariert wurde? - Capi Etheriel
Scheint in Vixie Cron behoben zu sein: man crontab auf Ubuntu 10.10 sagt "Cron erfordert, dass jeder Eintrag in einer Crontab in einem Newline-Zeichen endet. Wenn der letzte Eintrag in einer Crontab die Newline fehlt, Cron wird die Crontab (zumindest teilweise) gebrochen und weigern, es zu installieren." (Und das Datum am Ende ist der 19. April 2010.) - Marius Gedminas
@barraponto Dies ist ein Fehler in neuen Texteditoren. Der "newline" Charakter soll ein sein Leitungsabschluss Zeichen, so dass die letzte Zeile in einer Textdatei in einem Newline-Zeichen endet, das nicht im Editor angezeigt wird. Vi und vim verwenden das Zeichen korrekt, und Cron wurde erstellt, bevor die neuen Editoren ihr seltsames Verhalten begannen ... Daher spielt es save und enthält eine Leerzeile. - Izkata
Wenn Sie Crontab bearbeiten mit crontab -e Es prüft die Syntax der Datei, bevor ein Speichern möglich ist, einschließlich einer Überprüfung auf Zeilenumbruch. - Tom Harrison Jr
@ Chan-HoSuh, nach man-Seite "cron erfordert, dass jeder Eintrag in einer Crontab in einem Newline-Zeichen endet. Wenn der letzte Eintrag in einer Crontab die Newline fehlt, wird Cron die Crontab (zumindest teilweise) gebrochen und weigere sich zu verweigern es installieren." Dieses Verhalten wird beim Editieren aufgerufen und speichert die Crontab mit dem -e Option, und ist unabhängig vom Editor. - Tom Harrison Jr


Cron-Daemon wird nicht ausgeführt. Ich habe das vor ein paar Monaten wirklich vermasselt.

Art:

pgrep cron 

Wenn Sie keine Nummer sehen, wird Cron nicht ausgeführt. sudo /etc/init.d/cron start kann verwendet werden, um cron zu starten.

BEARBEITEN: Verwenden Sie den Service nicht, um Init-Skripts über /etc/init.d aufzurufen Dienstprogramm, z.B.

sudo service cron start

125



Danke, dass du mich zeigst. Ich machte weiterhin ps -ef | Grep foo - ripper234
Du könntest auch benutzen pidof cron Die Ergebnisse werden für andere Anwendungen, die auch das Wort "cron" enthalten, wie Crontab, weggelassen. - Pithikos
Seltsam, all diese Dinge geben mir nichts zu zeigen, dass Cron rennt, aber wenn ich renne sudo service cron start Ich bekomme start: Job is already running: cron - Colleen
service crond start wenn seine Centos / RHEL - Srihari Karanth


Die Skriptdateinamen in cron.d/, cron.daily/, cron.hourly/usw. sollten keinen Punkt enthalten (.), sonst laufen Teile übersprungen.

Siehe Laufteile (8):

   If neither the --lsbsysinit option nor the --regex option is given then
   the names must consist entirely of upper and lower case  letters,  dig‐
   its, underscores, and hyphens.

   If  the  --lsbsysinit  option  is given, then the names must not end in
   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to
   one  or more of the following namespaces: the LANANA-assigned namespace
   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces
   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace
   (^[a-zA-Z0-9_-]+$).

Also, wenn Sie ein Cron-Skript haben backup.sh, analyze-logs.pl im cron.daily/ Verzeichnis, entfernen Sie am besten die Namen der Erweiterung.


83



Es ist ein Feature, kein Bug - es hält Dinge wie myscript.backup oder myscript.original oder myscript.rpm-new direkt neben myscript laufen. - pbr
@pbr: macht Sinn. Zumindest wäre es beim Debuggen hilfreich gewesen, wenn run-parts --test (oder eine andere imaginäre Option wie --debug würde die übersprungenen Dateien einschließlich des Grundes ausgeben. - Rabarberski
Wenn das eine Funktion ist, ist es nicht nett :( Viele Leute benutzen den Punkt im Dateinamen (backup.sh ist der gebräuchlichste). Wenn Sie möchten, dass ein Skript aufhört auszuführen, ist die logischste Methode entferne es aus dem Verzeichnis "cron.d". - MatuDuke
Das ist so ein schlechtes Feature, dass es effektiv ein Bug ist. Es ist üblich, eine bestimmte Endung (wie ".list" oder ".cron" oder so etwas) zu verlangen, wenn die Leute sicherstellen wollen, dass die Dinge nur dann ausgeführt werden, wenn sie beabsichtigt sind. Das willkürliche Auswählen eines Punktes als wahrscheinliches Trennzeichen für ".bak" oder ".temp" oder was auch immer, ist völlig unvorhersehbar, außer in der Weise, dass es vorhersagbar Menschen verwirren wird. Legitime Endungen wie ".sh" und ".pl" sind seit Jahrzehnten weit verbreitet. Viele Leute benutzen "_bak" oder "_temp" oder "-bak" anstelle von einem Punkt. Dies ist eine schreckliche Design-Wahl; es ist bestenfalls ein Designfehler. - Teekin


In vielen Umgebungen führt Cron Befehle mit sh, während viele Leute annehmen, dass es verwenden wird bash.

Vorschläge, um dies für einen fehlgeschlagenen Befehl zu testen oder zu beheben:

  • Versuchen Sie, den Befehl auszuführen sh um zu sehen, ob es funktioniert
  • Umgehe den Befehl in einer Bash-Subshell, um sicherzustellen, dass er in bash ausgeführt wird:
    bash -c "mybashcommand"
  • Sag Cron, dass alle Befehle in bash ausgeführt werden sollen, indem du die Shell oben in deiner crontab eingibst:
    SHELL=/bin/bash
  • Wenn der Befehl ein Skript ist, vergewissern Sie sich, dass das Skript einen Shebang enthält:
    #!/bin/bash

55



Bash Vorschlag ist sehr hilfreich, behobenes Problem mit meinem Cron. - Maxim Galushka
Das hat mich nur eine Stunde lang zum Fideln gebracht. Noch verwirrender, wenn Sie sich des Problems nicht bewusst sind, wird das Skript manuell gut ausgeführt, wenn Sie typische Shell sind bashaber nicht mit cron. Vielen Dank! - Hendy
Vor langer Zeit bin ich auf etwas Ähnliches gestoßen: Das Kommando source ist in bash aber nicht sh. Verwenden Sie in cron / sh einen Punkt: . envfile eher, als source envfile. - kungphu


Ich hatte einige Probleme mit den Zeitzonen. Cron lief mit der neuen Installationszeitzone. Die Lösung war, Cron neu zu starten:

sudo service cron restart

34



Ja, nach dem Ändern der Zeitzone auf einem System muss entweder jeder Dienst neu gestartet werden, der sich um die Uhrzeit kümmert, oder ein Neustart durchgeführt werden. Ich bevorzuge den Neustart, um sicher zu sein, dass ich alles gefangen habe. - pbr
Oh, um Gottes Willen, habe ich Stunden damit getötet. Versuchte Dienstneustart nach * * * * * touch /tmp/cronworkshat nichts gemacht, aber da ist es RELOAD bei Cronlog. - НЛО


Wenn Ihr crontab-Befehl a hat % Symbol darin versucht Cron, es zu interpretieren. Also, wenn Sie irgendeinen Befehl mit einem benutzen würden % in ihm (wie eine Formatangabe zu dem Datum-Befehl) müssen Sie es entkommen.

Das und andere gute Sachen hier:
http://www.pantz.org/software/cron/croninfo.html


29



Das hat meinen Cron-Job in der letzten Woche zum Scheitern gebracht. Schließlich fand ich heraus, dass mein Date kein Escape-Zeichen hatte (Backslash für andere Leute, die nach dem Escape-Zeichen suchen). Yay! - Valien
Siehe auch Wie kann ich ausführen? date in einem Cron-Tab-Job? - Jared Beck
Das hat mich auch gebissen. Vielen Dank! - stefansundin