it-swarm.com.de

Warum funktionieren Crontab-Skripte nicht?

Häufig werden crontab Skripte nicht termingerecht oder wie erwartet ausgeführt. 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 nicht erwartungsgemäße Ausführung von crontab 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, z. Befehle, die erwartungsgemäß von der Shell ausgeführt werden, jedoch von cron fehlerhaft ausgeführt werden.

520
Adam Matan

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, bis /tmp/env.output erstellt wurde, und entfernen Sie dann den Job erneut. Vergleichen Sie nun den Inhalt von /tmp/env.output mit der Ausgabe von env, die in Ihrem regulären Terminal ausgeführt wird.

Ein häufiges "gotcha" ist hier, dass die Umgebungsvariable PATH unterschiedlich ist. Möglicherweise verwendet Ihr Cron-Skript den Befehl somecommand, der in /opt/someApp/bin enthalten ist und den Sie in /etc/environment zu PATH hinzugefügt haben. cron ignoriert PATH aus dieser Datei, daher schlägt das Ausführen von somecommand aus 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 aus /etc/environment an Cron-Jobs weitergegeben werden, nur nicht die Variablen, die Cron selbst festlegt, wie z. B. PATH.

Um das zu umgehen, setzen Sie einfach Ihre eigene Variable PATH 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. Auf diesem System befindet sich der Befehl stattdessen in /opt/someAppv2.2/bin. Sie müssten das gesamte Skript durchgehen und /opt/someApp/bin durch /opt/someAppv2.2/bin ersetzen, anstatt nur eine kleine Bearbeitung in der ersten Zeile des Skripts vorzunehmen.

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
493
geirha

Meine Top-Nachricht: Wenn Sie vergessen haben, am Ende der Datei crontab eine neue Zeile einzufügen. Mit anderen Worten sollte die crontab-Datei mit einer leeren Zeile enden.

Unten finden Sie den relevanten Abschnitt in den Manpages 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)
332
user4124

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 start kann verwendet werden, um cron zu starten.

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

Sudo service cron start
138
aneeshep

Die Skriptdateinamen in cron.d/, cron.daily/, cron.hourly/ usw. sollten keinen Punkt (.) enthalten, da sie sonst von den ausführenden Teilen übersprungen werden.

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_-]+$).

Wenn Sie ein Cron-Skript backup.sh, analyze-logs.pl im Verzeichnis cron.daily/ haben, sollten Sie die Erweiterungsnamen entfernen.

91
Xiè Jìléi

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

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

  • Versuchen Sie, den Befehl in sh auszuführen, um festzustellen, 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
    
67
Ian Mackinnon

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
39
luissquall

Für Skripte sollte der absolute Pfad verwendet werden:

Zum Beispiel sollte /bin/grep anstelle von grep verwendet werden:

# 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 von Shell ausgeführt wird. Der Grund ist, dass cron nicht dieselbe Umgebungsvariable PATH wie der Benutzer hat.

36
Adam Matan

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

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

32
JMS

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

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

25
jet

Es ist auch möglich, dass das Passwort des Benutzers abgelaufen ist. Sogar das Passwort von root kann verfallen. Du kannst tail -f /var/log/cron.log und du wirst sehen, dass cron mit abgelaufenem Passwort fehlschlägt. Sie können das Kennwort so festlegen, 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.

24
Daniel Tet

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

Beispiel: Firefox-Start mit cron.

Ihr Skript sollte irgendwo export DISPLAY=:0 enthalten.

18
andrew

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.

15
user9521

Unsichere Berechtigung für Cron-Tabelle

Eine Cron-Tabelle ist 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
14
John Peterson

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 cd in ein bestimmtes Verzeichnis, bevor er ausgeführt werden kann, z. 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/production/current[.____.owntown/usr/bin/rake db: session_purge Rails_ENV = production 
12
pjmorse

In der Vergangenheit verwendete 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 Cron-Tab-Dateien der Benutzer (/ var/spool/cron/benutzername oder/var/spool/cron/crontabs/benutzername) und den System-Cron-Tabs (/etc/crontab und 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 wie george; command not found, wenn Sie einen Befehl aus /etc/crontab oder eine Datei in /etc/cron.d in die Crontab-Datei eines Benutzers verschieben.

Umgekehrt liefert cron Fehler wie /usr/bin/restartxyz is not a valid username oder ähnliches, wenn der umgekehrte Fall eintritt.

11
pbr

Der häufigste Grund, warum ich gesehen habe, dass cron in einem falsch angegebenen Zeitplan versagt. Es ist üblich, einen für 23:15 Uhr geplanten Job als 15 23 * * * anstelle von * * 11 15 * oder 11 15 * * * anzugeben. Wochentag für Jobs nach Mitternacht wird auch verwirrt M-F ist 2-6 nach Mitternacht, nicht 1-5. Bestimmte Daten sind normalerweise ein Problem, da wir sie selten verwenden. * * 3 1 * ist nicht der 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 wie 2/3 in Zeitangaben verwenden, 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-5 oder 1,3,5 gestoßen.

Die Verwendung nicht qualifizierter Pfade hat ebenfalls Probleme verursacht. Der Standardpfad ist normalerweise /bin:/usr/bin, sodass 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 mithilfe von crontab -l aus der vorhandenen Crontab wiederhergestellt werden, wenn sie verstopft ist. 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 
 # Laden Sie diese crontab 
 # 
 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) als Dateinamen. 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 (das einzige Mal, dass ich crontab -e verwende) 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.

10
BillThor

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 bei der Ausführung über Shell einwandfrei, schlug jedoch bei der Ausführung über crontab fehl, da die ausführliche Ausgabe bei der Ausführung über Shell auf stdout gesetzt wird, bei der Ausführung über 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
10
Aaron Peart

Wenn Sie über SSH-Schlüssel auf ein Konto zugreifen, ist es möglich, sich beim 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. Oktober 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. Oktober 07:52:00 mybox cron [29063]: [ID 731128 auth.notice] pam_unix_account: cron versucht, den gesperrten Account mybox cron 
 24. Oktober 07:53:00 mybox cron [29098]: [ID 731128 auth.notice] pam_unix_account : cron versucht, 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, 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.

7
JohnGH

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.

7
Philluminati

Ich habe ein Shell-Installationsskript geschrieben, das ein weiteres Skript zum Löschen alter Transaktionsdaten aus einer Datenbank erstellt. Als Teil der Aufgabe musste der tägliche cron Job konfiguriert werden, um zu einem beliebigen Zeitpunkt ausgeführt zu werden, wenn die Datenbanklast niedrig war.

Ich habe eine Datei mycronjob mit cron schedule, username & the command erstellt und in das Verzeichnis /etc/cron.d kopiert. Meine zwei Fallstricke:

  1. Die Datei mycronjob 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 /var/log/syslog wie 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 die Datei /etc/crontab und die spätere auf eine Datei, die ich unter /etc/cront.d platziert habe.

3
allaptr

=== 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 -f zusammen 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

3
AlonL

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

Sudo /etc/init.d/cron restart
2
Phil Dodd

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}
2
Alexandre

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 ' hat dazu geführt, dass ein Skript, das ich geschrieben habe, hängen blieb und nie beendet wurde, weil es eine neue Zeile gefolgt von einer Fortschrittszeile ausspuckte. 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.

2
Mange

In 16.04, wenn Sie diesen Fehler in Syslog haben

(CRON) error (can't fork)

versuchen:

systemctl status cron.service

Im Ergebnis:

Tasks: num_task (limit: 512)

Wenn num_task nahe am Grenzwert liegt, verwenden Sie:

systemctl set-property cron.service TasksMax=new_max

Ersetzen Sie new_max durch einen geeigneten Wert.

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

2
Kangarooo

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

2
Dennis Parslow

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. Indem ich Berechtigungen auf --x------ setze, 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, als auch das oben erwähnte Problem mit den Ablageperioden in/etc/crontab (was, witzigerweise, keinen Fehler beim Durchlaufen von crontab -e verursacht) unterbrochen. ).

Als Beispiel habe ich Instanzen von Sudo crontab -e gesehen, die verwendet wurden, um ein Skript mit Root-Berechtigungen mit einem entsprechenden chown username file_output im Shell-Skript auszuführen. Schlampig, aber es funktioniert. IMHO, die elegantere Option ist, es in /etc/crontab mit dem angegebenen Benutzernamen und den richtigen Berechtigungen einzutragen, damit file_output an die richtige Stelle und den richtigen Besitzer geht.

2
Mange

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 goaccess zum Analysieren von Webserver-Protokolldateien. Dies funktioniert NICHT in Cron:

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

und goaccess zeigt 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

Die Korrektur für goaccess besteht 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
2

In meinem Fall hatten cron und crontab unterschiedliche Besitzer.

NICHT funktionierend hatte ich das:

[email protected] ~ $ 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:

[email protected] ~ $ 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.


[email protected] ~ $ 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

[email protected] ~ $
2
KiloOne

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
2
Doug

Die standardmäßigen .bashrc-Dateien auf UBuntu 16.04 (und vielen anderen Versionen) haben einen eingebauten Mechanismus, um nichts zu tun wenn sie keine interaktive Shell sind.

Dies kann dazu führen, dass die Datei in einem von cron ausgeführten Skript nicht korrekt bezogen wird! Um dies zu verhindern, kommentieren Sie die folgenden Zeilen am Anfang Ihrer .bashrc-Datei aus:

Ubuntu 16.04

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Ubuntu 12.04 und einige andere Versionen

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Solange diese in verbleiben, wenn cron ein Skript ausführt, das Ihre .bashrc-Datei erstellt, erhalten Sie tatsächlich keine der Umgebungsvariablen, die Sie in Ihrem Terminal gewohnt sind!

2
GrayedFox

Noch eine Gotcha:

Wenn Sie crontab -e eingeben und im Editor speichern, hat dies keine Auswirkungen. Sie müssen den Editor beenden, damit er entsprechend Ihren Änderungen hinzugefügt oder aktualisiert wird (verwenden Sie beispielsweise :x in Vim).

(crontab -e führt effektiv "Cron-Datei bearbeiten; Von Cron-Datei aktualisieren" aus, sodass der Editor blockiert wird, bis Sie ihn schließen.)

1
mahemoff

Ich hatte ein Problem mit einem Skript namens grep mit einem regulären Ausdruck. Einige reguläre Ausdrücke funktionierten, wenn das Skript von crontab aufgerufen wurde, während andere dies nicht taten, z. [[: print:]] hat nicht funktioniert. Es stellt sich heraus, dass die Umgebungsvariable LANG sich auf Zeichensätze wie [a-z] oder [[: print:]] auswirkt. Als ich meine LANG-Umgebungsvariable oben in meine crontab eingefügt habe, d.h. HTH.

1
user166286

Protokollierungsberechtigungen

Eine sehr einfache crontab, wird nicht ausgeführt, da /var/log/ von luser Konto nicht beschreibbar ist!

* * * * * /usr/local/bin/teamviewer_check >> /var/log/teamviewer.log 2>&1

LÖSUNG: Erstellen Sie die Datei als root und chmod bis 777

Dank des vorherigen Vorschlags, die Cron-Protokollierung in /etc/rsyslog.d/50-default.conf zu aktivieren, wird der Syslog-Eintrag (No MTA installed, discarding output) erstellt, und dann dank "(CRON) info (Kein MTA installiert, Ausgabe wird verworfen ) "Fehler im Syslog Installation von Postfix im lokalen Modus, tail/var/mail/luser, /bin/sh: 1: cannot create /var/log/teamviewer.log: Permission denied

1
kevinf

Noch eine Einschränkung:

Versuchen Sie, Ihre Cron-Skripte nicht im Home-Verzeichnis eines Benutzers abzulegen.

Ich hatte gerade ein Problem, bei dem alles gut schien, aber nach einer Weile - wahrscheinlich ein paar Stunden, nachdem ich mich abgemeldet habe, funktionieren die Cron-Jobs nicht mehr und diese Meldungen erscheinen im Protokoll:

Signature not found in user keyring
Perhaps try the interactive 'ecryptfs-mount-private'

Mein Home-Verzeichnis ist, soweit ich weiß, nicht verschlüsselt. Dennoch konnte das Problem behoben werden, indem diese Skripte aus dem Ausgangsverzeichnis verschoben wurden.

1
AlonL

Meine Crontab funktionierte nur, wenn ich als Benutzer angemeldet war.

Ich fand die hier vorgeschlagene Lösung für Unix & Linux SE

Was war das Problem ist, dass die Skripte in meinem Home-Verzeichnis waren, das verschlüsselt wurde. Es wird also nicht eingehängt und nicht verfügbar sein, wenn ich angemeldet war. Mit dem Befehl mount können Sie feststellen, ob Ihr Basisverzeichnis für die Verschlüsselung bereitgestellt ist.

Ich habe das Problem behoben, indem ich meine Skripte in den Ordner /usr/local/bin gestellt habe.

1
Paul

Nachdem Stunden herausgefunden hatten, wo das Problem lag, bearbeitete ich das Shell-Skript von Windows ( notepad ++ ), wo sich die Datei ursprünglich in a befand Linux Server und ich habe das neue Zeilenzeichen verpasst.

Da ich Notepad ++ zum Bearbeiten der Datei verwendete, musste ich die EOL-Konvertierung zu Unix , um das neue Zeilenzeichen zu erhalten, und es hat einwandfrei funktioniert.

Ich hoffe es hilft!

1
Kulasangar

Wenn crontab etwas wie run-parts /etc/cron.daily erwähnt, lehnt run-parts möglicherweise die Ausführung Ihres Skripts ab. In meinem Fall hat das Skript in cron.daily nicht mit #!/Bin/sh begonnen.

Ich habe dies entdeckt, indem ich mein Skript in ein eigenes Verzeichnis gestellt und run-parts für dieses Verzeichnis ausgeführt habe.

1
Michael Mather

Das ist mir kürzlich passiert: Ich hatte zwei Zeilen, die PATH so geändert haben:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/ernesto/bin

Dann später in der Datei:

PATH=$PATH:/some/other/path

wie man es normalerweise in einem Shell-interpretierten Kontext tun würde. $ PATH scheint jedoch nicht erweitert worden zu sein, sodass alle meine Jobs fehlschlagen. Die Lösung besteht darin, alles in eine einzige Zeile zu setzen.

Bearbeiten:

Da ich nicht bis zur nächsten normalen Iteration von anacron warten wollte, um zu überprüfen, ob meine Jobs ordnungsgemäß funktionierten, führte ich Folgendes aus:

anacron -fnd "jobname"

Dabei ist "Jobname" die in einer Registerkarte angegebene Job-ID. Dadurch werden Jobs gezwungen, nacheinander und ohne Verzögerung vom gleichen Anacron-Prozess ausgeführt zu werden.

1
erjoalgo

Cron-Jobs werden nicht ausgeführt, wenn das Kennwort Ihres Benutzers abgelaufen ist.

Ein Hinweis darauf ist, dass Ihr Cron-Protokoll (normalerweise /var/log/syslog unter Ubuntu, glaube ich) Nachrichten wie "Authentifizierungstoken ist nicht mehr gültig; neues erforderlich" enthält.

Sie können dieses Problem überprüfen, indem Sie Sudo chage -l the_username ausführen.

Hier ist ein Beispiel für ein abgelaufenes Passwort:

$ Sudo chage -l root
Last password change                    : password must be changed
Password expires                    : password must be changed
Password inactive                   : password must be changed
Account expires                     : never
Minimum number of days between password change      : 0
Maximum number of days between password change      : 14600
Number of days of warning before password expires   : 14

Das Update besteht darin, das Passwort zu ändern. Zum Beispiel:

Sudo -u root passwd

Befolgen Sie dann die Anweisungen und geben Sie ein neues Kennwort ein, wenn Sie dazu aufgefordert werden.

Vielen Dank an https://serverfault.com/questions/449651/why-is-my-crontab-not-working-and-how-can-i-troubleshoot-it#comment966708_544905 für den Hinweis die richtige Richtung hier. In meinem Fall war es genau wie für diesen Kommentator der Root-Benutzer einer DigitalOcean-Box.

1
Henrik N

Du hast benutzt:

*  *  * * * DISPLAY=:0 /path/to/your/app

aber es ist fehlgeschlagen, weil Ihr ~/.dbus -Verzeichnis nicht Ihnen gehört, sondern root. Prüfen Sie:

ls -l ~/.dbus
0
loxaxs

Ich habe einmal an einem gemeinsamen Server mit vielen Einschränkungen gearbeitet .

Alle Antworten hier (PATH, Shell, bash -c, ...) konnten mein Skript nicht zum Laufen bringen.

Es hat perfekt funktioniert, als ich den Befehl in ein kleines Skriptdatei mit PATH, Shell und Shebang und nicht in die Crontab selbst geschrieben habe. Ich musste die Berechtigungen auf 700 ändern.

0
don.joey

Manchmal funktioniert cron einwandfrei, aber das Skript oder der Befehl, den Sie ausführen möchten, schlägt unbemerkt fehl und Sie bellen den falschen Baum an.

In solchen Fällen finde ich es nützlich, das Ziel in ein anderes kurzes Skript zu packen, das einen sichtbaren Debug-Code ausgibt (einschließlich der Ausgabe von date), und die Umleitung zu verwenden, um sicherzustellen, dass ich Beweise für die Überprüfung erhalte. Wenn das Ziel ein Skript ist, kann das Umschließen eines sh -x weiter helfen.

Der crontab-Eintrag (immer mit crontab -e editieren) könnte so aussehen:

00 14 * * * (sh -x /tmp/my_wrapper_script) >> /tmp/debug.log 2>&1

Überprüfen Sie /tmp/debug.log und seinen Zeitstempel. Wenn es leer oder nicht vorhanden ist oder die Uhrzeit nicht kurz nach 14:00 Uhr (in diesem Beispiel) ist, liegt möglicherweise ein Cron-Problem vor. Andernfalls müssen Sie die eigentliche Zielaktion debuggen, und Cron funktioniert einwandfrei.

0
sxc731

Ich hatte einige Probleme mit der Verwendung von Sudo in einem Cron.

Grundsätzlich wollte ich einen Befehl als bestimmter Benutzer ausführen und habe zuerst an der Befehlszeile su getestet, was den Fehler This account is not available zurückgab. Mit Sudo wurde der Befehl fehlerfrei ausgeführt.

Bei der Ausführung von cron gab der Befehl Sudo jedoch den folgenden Fehler zurück: Sudo: sorry, you must have a tty to run Sudo.

Ich habe später festgestellt, dass die Verwendung von runuser und die Angabe einer Shell für den auszuführenden Befehl funktioniert.

0
marius-nyxpoint

Wenn Sie Skripte in /etc/cron.* Verzeichnissen ausführen, stellen Sie sicher, dass Ihre Skripte:

  • ausführbar sind,
  • stimmen mit dem Ubuntu/Debian-Cron-Skript-Namespace (^[a-zA-Z0-9_-]+$) überein.

Wenn Sie beispielsweise ein Skript mit einer Erweiterung (wie .sh) haben, funktioniert dies nicht.

Versuchen Sie Folgendes, um die Namen der Skripte zu drucken, die stündlich ausgeführt werden sollen:

Sudo run-parts --report --test /etc/cron.hourly
0
kenorb