Warum funktionieren Crontab-Skripte nicht?

Warum funktionieren Crontab-Skripte nicht?

Häufig crontabwerden Skripte nicht planmäßig 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 häufigsten Gründe dafür zusammenzufassen, dass crontabSkripte nicht wie erwartet ausgeführt werden. Schreiben Sie jeden Grund in eine separate Antwort.

Bitte geben Sie pro Antwort einen Grund an – Einzelheiten, warum es nicht ausgeführt wird – und eine(n) Lösung(en) für diesen einen Grund.

Bitte schreiben Sie nur cron-spezifische Probleme, z. B. Befehle, die von der Shell wie erwartet ausgeführt werden, von cron jedoch fehlerhaft ausgeführt werden.

Antwort1

Andere Umgebung

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

* * * * * umgebung > /tmp/umgebung.output

Warten Sie, bis /tmp/env.outputder Job erstellt wurde, und entfernen Sie ihn dann erneut. Vergleichen Sie nun den Inhalt /tmp/env.outputmit der Ausgabe von env„run“ in Ihrem normalen Terminal.

Ein häufiges Problem hier ist, dass die PATHUmgebungsvariable unterschiedlich ist. Vielleicht verwendet Ihr Cron-Skript den Befehl somecommandaus /opt/someApp/bin, den Sie PATHin hinzugefügt haben /etc/environment? Cron ignoriert PATHdiese Datei, sodass die Ausführung somecommandIhres Skripts fehlschlägt, wenn es mit Cron ausgeführt wird, aber funktioniert, wenn es in einem Terminal ausgeführt wird. Es ist erwähnenswert, dass Variablen aus /etc/environmentan Cron-Jobs weitergegeben werden, nur nicht die Variablen, die Cron selbst speziell festlegt, wie z . B. PATH.

Um das zu umgehen, setzen Sie einfach Ihre eigene PATHVariable oben im Skript. Beispiel:

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

# rest of script follows

Manche bevorzugen es, stattdessen einfach absolute Pfade zu allen Befehlen zu verwenden. Davon rate ich ab. Bedenken Sie, was passiert, wenn Sie Ihr Skript auf einem anderen System ausführen möchten und auf diesem System der Befehl /opt/someAppv2.2/binstattdessen in steht. Sie müssten das gesamte Skript durchgehen und durch ersetzen, /opt/someApp/binanstatt /opt/someAppv2.2/binnur eine kleine Änderung an der ersten Zeile des Skripts vorzunehmen.

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

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

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

Antwort2

Mein größtes Problem: Wenn Sie vergessen, am Ende der crontabDatei eine neue Zeile einzufügen. Mit anderen Worten, die Crontab-Datei sollte mit einer leeren Zeile enden.

Unten finden Sie den relevanten Abschnitt in den Manpages zu diesem Problem ( man crontabspringen Sie dann zum Ende):

   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)

Antwort3

Der Cron-Daemon läuft nicht. Das habe ich vor einigen Monaten wirklich vermasselt.

Typ:

pgrep cron 

Wenn Sie keine Nummer sehen (d. h. die Haupt-PID von cron), wird cron nicht ausgeführt. sudo /etc/init.d/cron startkann zum Starten von cron verwendet werden.

EDIT: Anstatt Init-Skripte über /etc/init.d aufzurufen, verwenden Sie das Service-Dienstprogramm, z. B.

sudo service cron start

EDIT: Sie können auch systemctl in modernem Linux verwenden, zB

sudo systemctl start cron

Antwort4

In vielen Umgebungen führt cron Befehle unter Verwendung aus sh, während viele Leute davon ausgehen, dass es verwenden wird bash.

Vorschläge zum Testen oder Beheben eines fehlgeschlagenen Befehls:

  • Versuchen Sie, den Befehl auszuführen, shum zu sehen, ob er funktioniert:

    sh -c "mycommand"
    
  • Um sicherzustellen, dass der Befehl in der Bash ausgeführt wird, schließen Sie ihn in eine Bash-Subshell ein:

    bash -c "mybashcommand"
    
  • Weisen Sie cron an, alle Befehle in Bash auszuführen, indem Sie die Shell oben in Ihrer Crontab festlegen:

    SHELL=/bin/bash
    
  • Wenn es sich bei dem Befehl um ein Skript handelt, stellen Sie sicher, dass das Skript ein Shebang enthält:

    #!/bin/bash
    

verwandte Informationen