Warum funktionieren Crontab-Skripte nicht?

525

Oft crontabwerden Skripte nicht termingerecht ausgeführt oder wie erwartet. Dafür gibt es zahlreiche Gründe:

  1. falsche crontab Notation
  2. Berechtigungsproblem
  3. Umgebungsvariablen

In diesem Community-Wiki werden die Hauptgründe für die crontabnicht erwartungsgemäße Ausführung von Skripten zusammengefasst. Schreiben Sie jeden Grund in eine separate Antwort.

Bitte geben Sie einen Grund pro Antwort an - Einzelheiten dazu, warum es nicht ausgeführt wird - und beheben Sie den / die Grund (e) für diesen einen Grund.

Bitte schreiben Sie nur Cron-spezifische Probleme, zB Befehle, die erwartungsgemäß von der Shell ausgeführt werden, aber von Cron fehlerhaft ausgeführt werden.

Adam Matan
quelle
12
Sie müssen schließen, crontab -edamit der Cron wirksam wird. Zum Beispiel mit vim bearbeite ich die Datei und verwende sie :wzum Schreiben, aber der Job wird erst dann zu cron hinzugefügt, wenn ich ihn auch beende. Also werde ich den Job erst sehen, nachdem ich ihn :qauch habe.
DutGRIFF
Ich denke, der beste Weg, um Cron zu debuggen, ist, Syslog zu überprüfen und die Probleme zu finden.
Suneel Kumar
In meinem Fall - die E - Mail zu meinen Spam - Ordnern vorging, so ..... das überprüfen , bevor Sie Stunden auf Debuggen verbringen: D
almaruf
Stromausfälle
Josef Klimuk

Antworten:

501

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 Sie, /tmp/env.outputbis der Auftrag erstellt wurde, und entfernen Sie ihn dann erneut. Vergleichen Sie nun den Inhalt von /tmp/env.outputmit der Ausgabe von envrun in Ihrem regulären Terminal.

Ein allgemeines "gotcha" hier ist die PATHUmgebungsvariable, die unterschiedlich ist. Vielleicht ist Ihr Cron - Skript verwendet den Befehl somecommandgefunden /opt/someApp/bin, die Sie hinzugefügt haben PATHin /etc/environment? cron ignoriert PATHdiese Datei, daher schlägt das Ausführen somecommandvon Ihrem Skript fehl, wenn es mit cron ausgeführt wird, funktioniert jedoch, wenn es in einem Terminal ausgeführt wird. Es ist erwähnenswert, dass Variablen von /etc/environmentan Cron-Jobs weitergegeben werden, nur nicht die Variablen, die Cron selbst festlegt, wie z PATH.

Um das zu umgehen, setzen Sie einfach Ihre eigene PATHVariable oben im Skript. Z.B

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

# rest of script follows

Einige bevorzugen es, stattdessen nur absolute Pfade zu allen Befehlen zu verwenden. Ich empfehle dagegen. Überlegen Sie, was passiert, wenn Sie Ihr Skript auf einem anderen System ausführen möchten und auf diesem System /opt/someAppv2.2/binstattdessen der Befehl ausgeführt wird . Sie müßten durch das gesamte Skript gehen ersetzt /opt/someApp/binmit , /opt/someAppv2.2/binanstatt nur einen kleinen bearbeiten auf der ersten Zeile des Skripts zu tun.

Sie können auch die Variable PATH 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
geirha
quelle
5
Ich glaube, ich bin einfach darauf hereingefallen, und Newline am Ende ... doppelt so schnell.
WernerCD
6
+1, denn envich hatte diesen Befehl völlig vergessen und dachte, PATH würde funktionieren. In meinem Fall war es tatsächlich ein bisschen anders.
Izkata
8
@pbr Wenn solche Verzeichnisse für andere schreibgeschützt bleiben, ist das System bereits gefährdet.
Geirha
6
@pbr Ein Systemadministrator kann das Root-Dateisystem unbeabsichtigt löschen. Sie können sich nicht davor hüten, dass Sysadmins alberne Fehler machen. Wenn Sie eine neuere Version eines Interpreters installieren, der nicht abwärtskompatibel ist, würde ich trotzdem einen Bruch erwarten. Die vernünftige Vorgehensweise besteht darin, es als einen anderen Befehl zu installieren. Wenn Sie beispielsweise Python Version 2.x haben und Python 3 installieren, installieren Sie es als Python3, nicht als Python. Und was / opt / someApp / bin anbelangt, warum in aller Welt hätte es keine vernünftigen Berechtigungen / Eigentumsrechte? Jeder vernünftige Administrator würde vernünftige Berechtigungen / Besitzrechte für Systemdateien sicherstellen.
Geirha
2
@pbr Es scheint, wir könnten für immer weitermachen, ja. Ich verstehe immer noch nicht, warum es eine schlechte Idee ist, PATH zu verwenden. Wenn Sie dies in einem Medium weiter diskutieren möchten, das für Diskussionen besser geeignet ist, finden Sie mich unter anderem in #ubuntu und #bash auf irc.freenode.net
geirha
336

Meine Top-Nachricht: Wenn Sie vergessen haben, 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 entsprechenden Abschnitt in den Manpages für dieses Problem (fahren Sie man crontabdann mit dem Ende fort):

   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)
user4124
quelle
91
Das ist so ein Showstopper, warum wurde es in so vielen Jahren von Cron nicht behoben?
Capi Etheriel
2
Scheint in Vixie cron behoben zu sein: In man crontabUbuntu 10.10 heißt es "cron erfordert, dass jeder Eintrag in einer Crontab mit einem Zeilenumbruch endet. Wenn der letzte Eintrag in einer Crontab den Zeilenumbruch nicht enthält, betrachtet cron die Crontab als (zumindest teilweise) fehlerhaft und weigern, es zu installieren. " (Und das Datum am Ende ist der 19. April 2010.)
Marius Gedminas
19
@barraponto Dies ist eigentlich ein Fehler in neuen Texteditoren. Das "Newline" -Zeichen soll ein Zeilenendezeichen sein , daher soll die letzte Zeile in einer Textdatei mit einem Newline-Zeichen enden, das im Editor nicht angezeigt wird. Vi und vim verwenden den Charakter korrekt, und cron wurde erstellt, bevor die neuen Editoren ihr merkwürdiges Verhalten begannen ... Daher wird es sicher abgespielt und eine Leerzeile eingefügt.
Izkata,
6
Wenn Sie crontab mit bearbeiten, crontab -ewird die Syntax der Datei überprüft, bevor das Speichern zugelassen wird, einschließlich der Prüfung auf Zeilenumbruch.
Tom Harrison Jr.
2
@ Chan-HoSuh, laut Manpage "verlangt cron, dass jeder Eintrag in einer Crontab mit einem Zeilenumbruch endet. Wenn dem letzten Eintrag in einer Crontab der Zeilenumbruch fehlt, betrachtet cron die Crontab als (zumindest teilweise) defekt und lehnt ab es installieren." Dieses Verhalten wird beim Bearbeiten und Speichern der Crontab mithilfe der -eOption ausgelöst und ist vom Editor unabhängig.
Tom Harrison Jr
139

Cron-Daemon läuft nicht. Ich habe es vor einigen Monaten wirklich vermasselt.

Art:

pgrep cron 

Wenn Sie keine Nummer sehen, läuft cron nicht. sudo /etc/init.d/cron startkann verwendet werden, um cron zu starten.

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

sudo service cron start

EDIT: Auch Sie könnten systemctl in modernen Linux verwenden, z

sudo systemctl start cron
user6019
quelle
47
Danke, dass du mir pgrep gezeigt hast. Ich habe ps -ef | weiter gemacht grep foo
ripper234
4
Sie können auch verwenden pidof cron, dass Ergebnisse für andere Anwendungen weggelassen werden, die ebenfalls das Wort "cron" enthalten, z. B. crontab.
Pithikos
Seltsam, all das gibt mir nichts zu zeigen, dass Cron läuft, aber wenn ich renne, sudo service cron startbekomme ichstart: Job is already running: cron
Colleen
1
service crond startif its centos / RHEL
Srihari Karanth
91

Das Skript Dateinamen in cron.d/, cron.daily/, cron.hourly/usw. sollten nicht enthalten Punkt ( .), sonst laufen Teile sie überspringen wird.

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 einen cron - Skript backup.sh, analyze-logs.plin cron.daily/Verzeichnis, würden Sie am besten die Erweiterung Namen zu entfernen.

Xiè Jìléi
quelle
10
Es ist eine Funktion, kein Fehler - sie verhindert, dass Dinge wie myscript.backup oder myscript.original oder myscript.rpm-new direkt neben myscript ausgeführt werden.
pbr
@pbr: macht Sinn. Zumindest wäre es für das Debuggen hilfreich gewesen, wenn run-parts --test(oder eine andere imaginäre Option wie --debugdie Ausgabe der Dateien, die
übersprungen werden,
8
Wenn dies ein Feature ist, ist es kein nettes :( Viele Leute verwenden Punkt im Dateinamen (backup.sh ist das am häufigsten verwendete). Wenn Sie möchten, dass ein Skript nicht mehr ausgeführt wird, ist dies die logischste Methode entfernen Sie es aus dem Verzeichnis "cron.d"
MatuDuke
7
Dies ist ein so schlechtes Feature, dass es praktisch ein Fehler ist. Es ist gängige Praxis, eine bestimmte Endung (wie ".list" oder ".cron" oder so etwas) zu fordern, wenn die Leute sicherstellen möchten, dass die Dinge nur dann ausgeführt werden, wenn sie beabsichtigt sind. Das willkürliche Auswählen eines Punkts als wahrscheinliches Trennzeichen für ".bak" oder ".temp" oder was auch immer, ist völlig unvorhersehbar, außer in der Weise, dass es Menschen vorhersehbar verwirren wird. Legitime Endungen wie ".sh" und ".pl" sind seit Jahrzehnten weit verbreitet. Viele Leute verwenden jedoch "_bak" oder "_temp" oder "-bak" anstelle eines Punkts. Dies ist eine schreckliche Wahl für das Design. es ist bestenfalls ein Designfehler.
Teekin
68

In vielen Umgebungen führt cron Befehle mit aus sh, während viele davon ausgehen, dass sie verwendet werden bash.

Vorschläge zum Testen oder Beheben dieses Problems bei einem fehlerhaften Befehl:

  • Führen Sie den Befehl aus, um shzu überprüfen, ob er funktioniert:

    sh -c "mycommand"
    
  • Schließen Sie den Befehl in eine Bash-Subshell ein, um sicherzustellen, dass er in Bash ausgeführt wird:

    bash -c "mybashcommand"
    
  • Weisen Sie cron an, alle Befehle in bash auszuführen, indem Sie die Shell oben auf Ihrer crontab setzen:

    SHELL=/bin/bash
    
  • Wenn der Befehl ein Skript ist, stellen Sie sicher, dass das Skript einen Shebang enthält:

    #!/bin/bash
    
Olorin
quelle
Bash-Vorschlag ist sehr hilfreich, behobenes Problem mit meinem Cron.
Maxim Galushka
Das hat mich nur eine Stunde lang beschäftigt. Noch verblüffender ist, dass das Skript manuell ausgeführt wird, wenn Sie eine typische Shell haben bash, aber nicht mit cron. Vielen Dank!
Hendy
Vor langer Zeit bin ich auf etwas Ähnliches gestoßen: Der Befehl sourceist in der Bash, aber nicht in der Sh. Verwenden Sie in cron / sh einen Punkt: . envfileanstatt source envfile.
Kungphu
@Clockwork sh "mycommand"teilt shmit, mycommand als Skriptdatei auszuführen. Meinten Sie sh -c "mycommand"? In jedem Fall scheint es bei dieser Antwort darum zu gehen, dass der Befehl speziell in bash ausgeführt wird. Warum haben Sie den Befehl shhier hinzugefügt ?
Olorin
@Olorin Meines Wissens war es das Ziel des ersten Punktes, zu versuchen, es mit sh auszuführen, um zu sehen, ob das Problem wirklich von der Tatsache herrührt, dass cron es mit sh anstelle von bash ausführt. Andererseits habe ich wenig Wissen über die Angelegenheit, also könnte ich mich irren.
Uhrwerk
40

Ich hatte einige Probleme mit den Zeitzonen. Cron lief mit der Zeitzone für die Neuinstallation. Die Lösung war, cron neu zu starten:

sudo service cron restart
luissquall
quelle
6
Ja, nach dem Ändern der Zeitzone auf einem System muss entweder jeder Dienst neu gestartet werden, für den es wichtig ist, wie spät es ist, oder es muss ein Neustart durchgeführt werden. Ich bevorzuge den Neustart, um sicherzugehen, dass ich alles erwischt habe.
pbr
Oh, um Himmels willen, das hat Stunden gekostet. Versuchte Dienst Neustart nach * * * * * touch /tmp/cronworksnichts getan, noch gibt es RELOADbei Cronlog.
НЛО
36

Für Skripte sollte der absolute Pfad verwendet werden:

Beispielsweise /bin/grepsollte anstelle von grep:

# m h  dom mon dow   command
0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

Anstatt von:

# m h  dom mon dow   command
0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

Dies ist besonders schwierig, da derselbe Befehl funktioniert, wenn er über die Shell ausgeführt wird. Der Grund dafür ist, dass cronnicht dieselbe PATHUmgebungsvariable wie der Benutzer vorhanden ist.

Adam Matan
quelle
3
siehe geirha antwort, du kannst (musst)
crons
9
Bzzt. Sie müssen den PFAD NICHT definieren - die Verwendung absoluter Pfade ist hier die beste Vorgehensweise. "Weil sich eine ausführbare Datei möglicherweise auf einem anderen Computer befindet" trumpft nicht "Ich möchte, dass sie genau dieses Programm
ausführt
1
yep das war es für mich, außerhalb des Cron konnte ich den Befehl direkt ausführen, innerhalb des Cron brauchte es vollen /usr/bin/whateverPfad
Anentropic
32

Wenn Ihr crontab-Befehl ein %Symbol enthält, versucht cron, es zu interpretieren. Wenn Sie also einen Befehl mit einem %darin enthaltenen Wert verwenden (z. B. eine Formatangabe für den Datumsbefehl), müssen Sie ihn maskieren.

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

JMS
quelle
Dies hat dazu geführt, dass mein Cron-Job in der letzten Woche fehlgeschlagen ist. Endlich herausgefunden, dass mein Date keinen Escape-Charakter hat (Backslash für alle anderen Leute, die nach dem Escape-Charakter suchen). Yay!
Valien
25

Cron ruft ein Skript auf, das nicht ausführbar ist.

Durch das Ausführen wird chmod +x /path/to/scripdas Skript ausführbar und sollte dieses Problem beheben.

Jet
quelle
5
Dies ist kein Einzelfall cronund einfach nachzuvollziehen, indem Sie versuchen, es /path/to/scriptüber die Befehlszeile auszuführen .
Adam Matan
4
Wenn Sie es gewohnt sind, Skripte mit . scriptnameoder sh scriptnameoder auszuführen bash scriptname, wird dies zu einem cronspezifischen Problem.
Eliah Kagan,
24

Es ist auch möglich, dass das Passwort des Benutzers abgelaufen ist. Sogar das Passwort von root kann verfallen. Sie können tail -f /var/log/cron.logund Sie werden sehen, dass cron mit abgelaufenem Passwort fehlschlägt. Sie können das Passwort so einstellen, dass es niemals abläuft:passwd -x -1 <username>

In einigen Systemen (Debian, Ubuntu) ist die Protokollierung für cron standardmäßig nicht aktiviert. In /etc/rsyslog.conf oder /etc/rsyslog.d/50-default.conf die Zeile:

# cron.*                          /var/log/cron.log

sollte bearbeitet werden ( sudo nano /etc/rsyslog.conf) unkommentiert zu:

cron.*                          /var/log/cron.log

Danach müssen Sie rsyslog über neu starten

/etc/init.d/rsyslog restart

oder

service rsyslog restart 

Quelle: Aktivieren Sie die Crontab-Protokollierung in Debian Linux

In einigen Systemen (Ubuntu) ist eine separate Protokolldatei für Cron nicht standardmäßig aktiviert, aber Cron-bezogene Protokolle werden in der Syslog-Datei angezeigt. Man darf verwenden

cat /var/log/syslog | grep cron -i

um cron-bezogene Nachrichten anzuzeigen.

unbekannt
quelle
Ich habe Debian (wheezy), aber es gibt kein /etc/init.d/rsyslog, nur inetutils-syslogd und sysklogd. Muss ich etwas installieren oder einfach einen der beiden neu starten?
Hgoebl
18

Wenn Ihr Cronjob GUI-Apps aufruft, müssen Sie ihnen mitteilen, welches DISPLAY sie verwenden sollen.

Beispiel: Firefox-Start mit cron.

Ihr Skript sollte export DISPLAY=:0irgendwo enthalten .

andrew
quelle
aplay brauchte diesen aus irgendeinem Grund. danke
IljaBek
* * * * * export DISPLAY=:0 && <command>
LoMaPh
15

Berechtigungsprobleme sind leider recht häufig.

Beachten Sie, dass eine häufige Problemumgehung darin besteht, alles mit der crontab von root auszuführen, was manchmal eine sehr schlechte Idee ist. Das Festlegen der richtigen Berechtigungen wird auf jeden Fall weitgehend übersehen.

user9521
quelle
Beachten Sie, dass die Zeile nicht ausgeführt wird, wenn Sie über eine Crontab-Zeile verfügen, die die Ausgabe an eine noch nicht vorhandene Datei weiterleitet, und das Verzeichnis für die Datei ein Verzeichnis ist, auf das der Cron-Benutzer keinen Zugriff hat.
Evan Donovan
14

Unsichere Berechtigung für Cron-Tabelle

Eine Cron-Tabelle wird abgelehnt, wenn ihre Berechtigung unsicher ist

sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)

Das Problem ist mit gelöst

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs
John Peterson
quelle
Zuerst habe ich es selbst herausgefunden und dann habe ich deine Antwort gefunden! Trotzdem vielen Dank! In meinem Fall hatte ich einige crontabs in / var / spool / cron / crontabs über SVN wiederhergestellt, wodurch die Berechtigungen geändert wurden!
Alfonx
12

Das Skript ist ortsabhängig. Dies hängt damit zusammen, dass in einem Skript immer absolute Pfade verwendet werden, ist aber nicht ganz dasselbe. Ihr Cron-Job muss möglicherweise cdvor der Ausführung in ein bestimmtes Verzeichnis, z. B. eine Rake-Aufgabe in einer Rails-Anwendung muss sich möglicherweise im Anwendungsstamm befinden, damit Rake die richtige Aufgabe findet, ganz zu schweigen von der entsprechenden Datenbankkonfiguration usw.

Also ein crontab Eintrag von

23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

wäre besser als

23 3 * * * cd / var / www / production / current && / usr / bin / rake db: session_purge RAILS_ENV = production

Oder um den Crontab-Eintrag einfacher und weniger spröde zu halten:

23 3 * * * /home/<user>/scripts/session-purge.sh

mit dem folgenden Code in /home/<user>/scripts/session-purge.sh:

cd / var / www / produktion / aktuell
/ usr / bin / rake db: session_purge RAILS_ENV = Produktion
pjmorse
quelle
1
Wenn das von cron aufgerufene Skript in einer interpretierten Sprache wie PHP geschrieben ist, müssen Sie möglicherweise das Arbeitsverzeichnis im Skript selbst festlegen. Zum Beispiel in PHP: chdir(dirname(__FILE__));
Evan Donovan
Ich habe mich mit diesem erwischt: Das Skript befand sich früher im Stammverzeichnis meines Ausgangsverzeichnisses, aber dann habe ich es verschoben (und die Crontab aktualisiert) und konnte nicht herausfinden, warum es nicht funktionierte. Es stellte sich heraus, dass das Skript einen relativen Pfad verwendet hat, vorausgesetzt, dass er relativ zum Speicherort des Skripts war, aber tatsächlich relativ zum Stammverzeichnis meines Ausgangsverzeichnisses, da dies das von cron verwendete Arbeitsverzeichnis war, weshalb das Skript funktionierte, als es sich im Stammverzeichnis meines Ausgangsverzeichnisses befand (weil das erwartete Arbeitsverzeichnis des Skripts und dessen tatsächliche Arbeitsweise zufällig zusammenfiel).
Micheal Johnson
11

In der Vergangenheit funktionierende Crontab-Spezifikationen können beim Verschieben von einer Crontab-Datei in eine andere beschädigt werden . Manchmal liegt der Grund darin, dass Sie die Spezifikation von einer System-Crontab-Datei in eine Benutzer-Crontab-Datei verschoben haben oder umgekehrt.

Das Format der Cron-Jobspezifikation unterscheidet sich zwischen den Crontab-Dateien der Benutzer (/ var / spool / cron / benutzername oder / var / spool / cron / crontabs / benutzername) und den Crontabs des Systems ( /etc/crontabund den Dateien in /etc/cron.d).

Die System-Crontabs haben direkt vor dem auszuführenden Befehl ein zusätzliches Feld "Benutzer".

Dies führt zu Fehlern, beispielsweise george; command not foundbeim Verschieben eines Befehls aus /etc/crontabeiner Datei in /etc/cron.ddie Crontab-Datei eines Benutzers.

Umgekehrt liefert cron im umgekehrten Fall ähnliche /usr/bin/restartxyz is not a valid usernameoder ähnliche Fehler .

pbr
quelle
10

cron script ruft einen Befehl mit der Option --verbose auf

Bei mir ist ein Cron-Skript fehlgeschlagen, weil ich beim Schreiben des Skripts im Autopiloten war und die Option --verbose eingefügt habe:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

Das Skript lief einwandfrei, wenn es von der Shell aus ausgeführt wurde, schlug jedoch fehl, wenn es von crontab aus ausgeführt wurde, da die ausführliche Ausgabe von der Shell aus auf stdout gesetzt wird, von crontab jedoch nirgendwo. Einfache Lösung zum Entfernen des 'v':

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands
Aaron Peart
quelle
5
Warum verursacht dies einen Fehler? Pufferprobleme?
Adam Matan
Jegliche Ausgabe oder Fehler über Cronjobs trriggred ist gooing auf Ihre mailbox.So zu richten sollten wir nie über diese Fehler zu kümmern vergessen / output.We sie auf jede Datei umleiten oder / dev / null
Nischay
10

Der häufigste Grund, warum ich gesehen habe, dass cron in einem falsch angegebenen Zeitplan versagt. Es ist üblich, 15 23 * * *anstelle von * * 11 15 *oder einen Job anzugeben, der für 23:15 Uhr geplant ist 11 15 * * *. Wochentag für Jobs nach Mitternacht wird auch verwirrt MF ist 2-6nach Mitternacht nicht 1-5. Bestimmte Daten sind in der Regel ein Problem, da wir sie nur selten verwenden und * * 3 1 *nicht am 3. März. Wenn Sie sich nicht sicher sind, überprüfen Sie Ihre Cron-Zeitpläne online unter https://crontab.guru/ .

Wenn Sie mit verschiedenen Plattformen arbeiten und nicht unterstützte Optionen verwenden, z. B. 2/3Zeitangaben, kann dies ebenfalls zu Fehlern führen. Dies ist eine sehr nützliche Option, die jedoch nicht allgemein verfügbar ist. Ich bin auch auf Probleme mit Listen wie 1-5oder gestoßen 1,3,5.

Die Verwendung nicht qualifizierter Pfade hat ebenfalls Probleme verursacht. Der Standardpfad ist normalerweise /bin:/usr/binso, dass nur Standardbefehle ausgeführt werden. Diese Verzeichnisse haben normalerweise nicht den gewünschten Befehl. Dies betrifft auch Skripte, die nicht standardmäßige Befehle verwenden. Andere Umgebungsvariablen können ebenfalls fehlen.

Das Klopfen einer vorhandenen Crontab hat mir Probleme bereitet. Ich lade jetzt von einer Dateikopie. Dies kann aus der vorhandenen Crontab mit wiederhergestellt werden, crontab -lwenn es verstopft wird. Ich behalte die Kopie von crontab in ~ / bin. Es ist durchgehend kommentiert und endet mit der Zeile # EOF. Dies wird täglich von einem Crontab-Eintrag wie folgt nachgeladen:

#! / usr / bin / crontab
# Crontab neu laden
#
54 12 * * * $ {HOME} / bin / crontab

Der obige Befehl reload basiert auf einer ausführbaren crontab mit einem Bang-Pfad, auf dem crontab ausgeführt wird. Einige Systeme erfordern die Ausführung von crontab im Befehl und die Angabe der Datei. Wenn das Verzeichnis über ein Netzwerk freigegeben ist, verwende ich häufig crontab.$(hostname)den Namen der Datei. Dies korrigiert schließlich Fälle, in denen die falsche Crontab auf dem falschen Server geladen ist.

Durch die Verwendung der Datei wird eine Sicherungskopie der Crontab erstellt, und temporäre Änderungen (die einzige Zeit, die ich verwende crontab -e) können automatisch zurückgesetzt werden. Es stehen Header zur Verfügung, mit deren Hilfe die Planungsparameter richtig eingestellt werden können. Ich habe sie hinzugefügt, wenn unerfahrene Benutzer eine Crontab bearbeiten würden.

In seltenen Fällen stoße ich auf Befehle, die Benutzereingaben erfordern. Diese schlagen unter crontab fehl, obwohl einige mit der Eingabeumleitung funktionieren.

BillThor
quelle
3
Dies deckt drei verschiedene Probleme ab. Können sie in getrennte Antworten aufgeteilt werden?
Eliah Kagan,
9
Können Sie erklären, wie sich die 30 23 * * * Übersetzung auf 23:15 Uhr auswirkt?
JYelton
@JYelton Das war offensichtlich falsch, sollte es sein 15 23 * * *. Korrigiert jetzt.
Melebius
7

Wenn Sie über SSH-Schlüssel auf ein Konto zugreifen, ist es möglich, sich bei dem Konto anzumelden, ohne jedoch zu bemerken, dass das Kennwort für das Konto gesperrt ist (z. B. aufgrund abgelaufener oder ungültiger Kennwortversuche).

Wenn das System PAM verwendet und das Konto gesperrt ist, kann dies dazu führen, dass der Cronjob nicht mehr ausgeführt wird. (Ich habe dies unter Solaris getestet, aber nicht unter Ubuntu)

Sie können Nachrichten wie diese in / var / adm / messages finden:

24.10.07: 51:00 mybox cron [29024]: [ID 731128 auth.notice] pam_unix_account: cron versucht, den gesperrten Account myuser vom lokalen Host zu validieren
24.10.07: 52:00 mybox cron [29063]: [ID 731128 auth.notice] pam_unix_account: cron versucht, den gesperrten Account myuser vom lokalen Host zu validieren
24.10.07: 53:00 mybox cron [29098]: [ID 731128 auth.notice] pam_unix_account: cron versucht, den gesperrten Account myuser vom lokalen Host zu validieren
24.10.07: 54:00 mybox cron [29527]: [ID 731128 auth.notice] pam_unix_account: cron versucht, den gesperrten Account myuser vom lokalen Host zu validieren

Alles, was Sie tun müssen, ist auszuführen:

# passwd -u <BENUTZERNAME>

als root zum entsperren des kontos und die crontab sollte wieder funktionieren.

JohnGH
quelle
7

Wenn Sie einen Befehl wie diesen haben:

* * * * * /path/to/script >> /tmp/output

und es funktioniert nicht und Sie können keine Ausgabe sehen, es muss nicht unbedingt bedeuten, dass cron nicht funktioniert. Das Skript könnte kaputt sein und die Ausgabe nach stderr gehen, was nicht an / tmp / output übergeben wird. Überprüfen Sie, ob dies nicht der Fall ist, indem Sie auch diese Ausgabe erfassen:

* * * * * /path/to/script >> /tmp/output 2>&1

um zu sehen, ob dies Ihnen hilft, Ihr Problem zu erkennen.

Philluminati
quelle
3

=== Docker-Warnung ===

Wenn Sie Docker verwenden,

Ich denke, es ist richtig hinzuzufügen, dass ich es nicht geschafft habe, cron im Hintergrund laufen zu lassen.

Um einen Cron-Job innerhalb des Containers auszuführen, habe ich Supervisor verwendet und cron -fzusammen mit dem anderen Prozess ausgeführt.

Bearbeiten: Ein weiteres Problem - Ich habe es auch nicht geschafft, es zum Laufen zu bringen, wenn der Container mit HOST-Netzwerk ausgeführt wurde. Siehe dieses Problem auch hier: https://github.com/phusion/baseimage-docker/issues/144

AlonL
quelle
3

Ich habe ein Installationsshell-Skript geschrieben, das ein weiteres Skript zum Löschen alter Transaktionsdaten aus einer Datenbank erstellt. Als Teil der Aufgabe musste der tägliche cronJob so konfiguriert werden , dass er zu einer beliebigen Zeit ausgeführt wurde, wenn die Datenbanklast niedrig war.

Ich habe eine Datei mycronjobmit dem Cron-Zeitplan, dem Benutzernamen und dem Befehl erstellt und in das /etc/cron.dVerzeichnis kopiert . Meine zwei Fallstricke:

  1. mycronjob Die Datei musste root gehören, um ausgeführt zu werden
  2. Ich musste Berechtigungen für die Datei auf 644 setzen - 664 würde nicht ausgeführt.

Ein Berechtigungsproblem wird in etwa /var/log/syslogwie folgt angezeigt :

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)

Die erste Zeile bezieht sich auf eine /etc/crontabDatei und die spätere auf eine Datei, unter die ich gestellt habe /etc/cront.d.

Izik Golan
quelle
2

Zeile in einer Weise geschrieben crontab versteht nicht. Es muss richtig geschrieben sein. Hier ist CrontabHowTo .

Kangarooo
quelle
1
Wie kann dies behoben werden?
Adam Matan
Das Überprüfen des Fehlerprotokolls von cron ist die häufigste Methode. IIRC 'crontab -e' führt eine Syntaxanalyse durch, nachdem Sie die Datei ebenfalls bearbeitet haben - dies ist jedoch möglicherweise nicht universell.
pbr
2

Cron-Daemon läuft möglicherweise, funktioniert aber nicht. Versuche cron neu zu starten:

sudo /etc/init.d/cron restart
Phil Dodd
quelle
3
Ich habe diesen Fall NIE in der Produktion gesehen. Das heißt nicht, dass es nicht passiert ist - nur, dass ich es in den 30 Jahren, in denen ich UNIX und Linux verwendet habe, nicht gesehen habe. Cron ist wahnsinnig robust.
pbr
1
Ich bin mir nicht sicher, aber ich denke, das ist mir tatsächlich gerade passiert. Ich habe pidofcron ausprobiert und nichts bekommen. Versucht mit serviceDienstprogramm und es sagte, dass Cron bereits ausgeführt wurde. Führen Sie einfach diesen Befehl aus und führen Sie ihn pidoferneut aus, und ich erhalte ein Ergebnis.
Colleen
2

Schreiben an cron über "crontab -e" mit dem username-Argument in einer Zeile. Ich habe Beispiele von Benutzern (oder Sysadmins) gesehen, die ihre Shell-Skripte geschrieben haben und nicht verstanden haben, warum sie nicht automatisieren. Das Argument "user" befindet sich in / etc / crontab, nicht jedoch in den benutzerdefinierten Dateien. Ihre persönliche Datei würde zum Beispiel so aussehen:

# m h dom mon dow command

* * */2  *   *  /some/shell/script

während / etc / crontab wäre:

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

Warum sollten Sie letzteres tun? Nun, je nachdem, wie Sie Ihre Berechtigungen festlegen möchten, kann dies sehr verworren sein. Ich habe Skripte geschrieben, um Aufgaben für Benutzer zu automatisieren, die die Feinheiten nicht verstehen oder sich nicht um die Plackerei kümmern möchten. Durch Setzen von Berechtigungen auf --x------kann ich das Skript ausführbar machen, ohne dass sie es lesen (und möglicherweise versehentlich ändern) können. Möglicherweise möchte ich diesen Befehl jedoch mit mehreren anderen aus einer Datei ausführen (um die Wartung zu vereinfachen), aber sicherstellen, dass der Dateiausgabe der richtige Eigentümer zugewiesen ist. Wenn Sie dies tun (zumindest in Ubuntu 10.10), wird sowohl die Unfähigkeit, die Datei zu lesen als auch auszuführen, sowie das oben erwähnte Problem mit den Ablageperioden in / etc / crontab beeinträchtigt (was witzigerweise keinen Fehler beim Durchlaufen verursacht crontab -e). .

Als Beispiel habe ich Instanzen von gesehen, sudo crontab -edie zum Ausführen eines Skripts mit Root-Berechtigungen verwendet wurden, mit einem entsprechenden chown username file_outputSkript im Shell-Skript. Schlampig, aber es funktioniert. IMHO, die anmutigere Option ist es, sie /etc/crontabmit dem angegebenen Benutzernamen und den entsprechenden Berechtigungen file_outputeinzugeben.

Mange
quelle
"Wenn Sie dies tun (zumindest in Ubuntu 10.10) , können Sie weder die Datei lesen noch ausführen." Ich sollte klarstellen: / etc / crontab (standardmäßig) erfordert Berechtigungen zum Lesen und Ausführen, während Sie dies KÖNNTEN Führen Sie "sudo crontab -e" aus, um einen Cronjob zu erstellen, der sowohl die Notwendigkeit der Berechtigung "w" als auch das Problem mit Erweiterungen wie ".sh" außer Kraft setzt. Ich hatte keine Zeit, den Cron-Code auseinander zu ziehen und zu überprüfen, warum dies funktioniert, nur ein Detail, das mir aufgefallen ist.
Mange
2

Aufbauend auf dem, was Aaron Peart über den ausführlichen Modus erwähnt hat, werden Skripts, die sich nicht im ausführlichen Modus befinden, manchmal initialisiert, aber nicht beendet, wenn das Standardverhalten eines eingeschlossenen Befehls darin besteht, eine Zeile oder mehr auf dem Bildschirm auszugeben, sobald der Prozess gestartet wird. Zum Beispiel habe ich ein Backup-Skript für unser Intranet geschrieben, das curl verwendet, ein Dienstprogramm, das Dateien auf Remote-Server herunterlädt oder hochlädt. Es ist sehr praktisch, wenn Sie nur über HTTP auf diese Remote-Dateien zugreifen können. Die Verwendung von "curl http://something.com/somefile.xls " führte dazu, dass ein Skript, das ich geschrieben habe, hängen blieb und nie abgeschlossen wurde, weil eine neue Zeile gefolgt von einer Fortschrittszeile ausgegeben wurde. Ich musste das stille Flag (-s) verwenden, um es anzuweisen, keine Informationen auszugeben, und in meinen eigenen Code schreiben, um damit umzugehen, wenn die Datei nicht heruntergeladen werden konnte.

Räude
quelle
1
Für Programme, die keinen stillen Modus haben, können Sie ihre Ausgabe an umleiten /dev/null. Beispiel: some-command > /dev/nullDies leitet nur die Standardausgabe und nicht die Fehlerausgabe um (was normalerweise gewünscht wird, da Sie über Fehler informiert werden möchten). Um auch die Fehlerausgabe umzuleiten, verwenden Sie some-command &> /dev/null.
Eliah Kagan,
Ja, das war mein erster Gedanke, als ich das oben erwähnte Skript schrieb. Ich vergesse, warum ich das nicht benutzt habe, möglicherweise ein ungewöhnliches Verhalten, das diese Lösung umgangen hat. Ich weiß, dass der ausführliche / interaktive Modus bei einigen Befehlen die Standardeinstellung ist (ich schaue auf YOU, scp!), Was bedeutet, dass Sie die Ausgabe für den reibungslosen Betrieb von Shell-Skripten zwischenspeichern müssen.
Mange
2

Obwohl Sie Umgebungsvariablen in Ihrer crontable definieren können, befinden Sie sich nicht in einem Shell-Skript. Konstruktionen wie die folgenden funktionieren also nicht:

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

Dies ist darauf zurückzuführen, dass Variablen in der crontable nicht interpretiert werden: Alle Werte werden wörtlich genommen. Und das ist auch so, wenn Sie die Klammern weglassen. Ihre Befehle werden also nicht ausgeführt und Ihre Protokolldateien werden nicht geschrieben ...

Stattdessen müssen Sie alle Umgebungsvariablen direkt definieren:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}
Alexandre
quelle
2

Wenn eine Aufgabe innerhalb von cron ausgeführt wird, wird stdin geschlossen. Programme, die je nach Verfügbarkeit von stdin unterschiedlich arbeiten, verhalten sich in der Shell-Sitzung und in cron unterschiedlich.

Ein Beispiel ist das Programm goaccesszum Analysieren von Webserver-Protokolldateien. Dies funktioniert NICHT in Cron:

goaccess -a -f /var/log/nginx/access.log > output.html

und goaccesszeigt die Hilfeseite an, anstatt den Bericht zu erstellen. In der Shell kann dies mit reproduziert werden

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

Das Update für goaccessbesteht darin, das Protokoll von stdin zu lesen, anstatt aus der Datei zu lesen. Die Lösung besteht darin, den Eintrag crontab in zu ändern

cat /var/log/nginx/access.log | goaccess -a > output.html
Martijn de Milliano
quelle
2

In meinem Fall hatten cron und crontab unterschiedliche Besitzer.

NICHT funktionierend hatte ich das:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

Grundsätzlich musste ich cron-config ausführen und die Fragen richtig beantworten. Es gab einen Punkt, an dem ich mein Win7-Benutzerkennwort für mein Benutzerkonto eingeben musste. Nach meiner Lektüre scheint dies ein potenzielles Sicherheitsproblem zu sein, aber ich bin der einzige Administrator in einem einzelnen Heimnetzwerk und habe mich daher für OK entschieden.

Hier ist die Befehlssequenz, die mich zum Laufen gebracht hat:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to [email protected].
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $
KiloOne
quelle
1
Obwohl dies gut dokumentiert ist, sieht es wie ein Cygwin-spezifischer Punkt aus. gehört es wirklich in askubuntu?
sxc731
2

Auf meinen RHEL7-Servern würden Root-Cron-Jobs ausgeführt, Benutzerjobs jedoch nicht. Ich habe festgestellt, dass die Jobs ohne Basisverzeichnis nicht ausgeführt werden können (es werden jedoch gute Fehler in / var / log / cron angezeigt). Als ich das Home-Verzeichnis erstellt habe, wurde das Problem behoben.

Dennis Parslow
quelle
2

Wenn Sie Ihre crontab-Datei mit einem Windows-Editor (über Samba oder etwas anderes) bearbeitet haben und die Zeilenumbrüche durch \ n \ r oder nur \ r ersetzt wurden, wird cron nicht ausgeführt.

Wenn Sie /etc/cron.d/* verwenden und eine dieser Dateien ein \ r enthält, durchläuft cron die Dateien und stoppt, wenn eine fehlerhafte Datei gefunden wird. Nicht sicher, ob das das Problem ist?

Verwenden:

od -c /etc/cron.d/* | grep \r
Doug
quelle