So richten Sie einen Root-Cron-Job richtig ein

So richten Sie einen Root-Cron-Job richtig ein

Ich habe versucht, einen Root-Cron-Job einzurichten, um ein Bash-Skript als Root auszuführen, das zur Minute 7,37, jede Stunde, jeden Tag des Monats, jeden Monat ausgeführt wird. Dieses Skript befindet sich in /usr/binund hat den Namen tunlrupdate.sh. Es aktualisiert den DNS von Tunlr.

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

Dieses Bash-Skript ist verfügbarHier.

Wenn das Skript aufgerufen wird, schreibt es die Geschehnisse in ein Protokoll in/var/log/tunlr.log

Um diesen Root-Cron-Job hinzuzufügen, habe ich den Standard für die Root-Crontab verwendet

sudo crontab -e

Und diese beiden Zeilen am Ende eingefügt. Ich erwarte, dass Cron das Skript als Root ausführt.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Ein späterer Befehl sudo crontab -lbestätigte, dass der Cron-Job eingefügt wurde.

Ich habe Ubuntu neu gestartet und in der Protokolldatei überprüft, ob der Cron-Job ordnungsgemäß gestartet wurde. In der Protokolldatei steht jedoch nichts, /var/log/tunlr.logwas bedeutet, dass der Job nie erfolgreich gestartet wurde.

Ich habe überprüft, dass wenn ich das Skript über die Befehlszeile ausführe

sudo /usr/bin/tunlrupdate.sh

dann wird die Logdatei entsprechend aktualisiert.

Warum wird dieser Cron-Job in meinem System nicht wie geplant ausgeführt?

UPDATE 1: Alle bisher vorgeschlagenen Lösungen funktionieren nicht. Ich danke Olli für eine CLI zum Auflisten des Systemprotokolls sudo grep CRON /var/log/syslog. Allerdings habe ich einen CRON-Fehler erhalten

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

mit der vorgeschlagenen PATH=-Einfügung und Verwendung des absoluten Pfads vom Stamm für Funktionen im Skript oder ohne diese hier vorgeschlagenen Lösungen. Ich erhalte immer noch diesen Fehler.

Nach einiger Suche habe ich den Fehler in der Datei lokalisiert /usr/lib/php5/maxlifetime, wie erklärtHier:Change #!/bin/sh -e --> #!/bin/sh -x

Dann wird das CRON-Fehlerprotokoll in meinem System aufgelistet

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

Ich bekomme das Bash-Skript immer noch nicht ausgeführt. Diesmal wird kein Fehler im Protokoll angezeigt. Um sicherzugehen, dass dies nicht der Inhalt des Skripts war, habe ich das Skript auf die folgenden 3 Zeilen reduziert:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

Ich bekomme den Cron-Job immer noch nicht durch. Nichts wird in die Logdatei geschrieben. Kann es also sein, dass selbst ein leeres Skript nicht in Cron ausgeführt wird? Ich verstehe es nicht. Ich versuche gerade ein Skript, das auf diese beiden Zeilen reduziert ist:

#!/bin/bash
exit 0

Und immer noch das gleiche Fehlerprotokoll. Das Cron-Skript läuft nicht durch ...

Antwort1

Wenn Sie ein Skript ausführen möchten alsnormaler Benutzer:

crontab -e

Und fügen Sie die Zeile hinzu:

07,37 * * * * /usr/bin/tunlrupdate.sh

Wenn Sie Ihr Skript ausführen möchten alsWurzel:

sudo crontab -e

Und fügen Sie dieselbe Zeile hinzu:

07,37 * * * * /usr/bin/tunlrupdate.sh

Antwort2

Endlich eine funktionierende Lösung. Im Syslog sah ich das immer wiederkehrende und faszinierende:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

Das klingt, als ob root nicht als cmd erkannt wurde. Da ich den Cron des root bereits mit verwendet habe $ sudo /usr/bin/tunlrupdate.sh. Dann habe ich mit dem Originalskript (korrigiert für einen Fehler im UNIX-Datums-cmd: %m, was Monat ist, wurde für Minuten verwendet, was %M ist) Folgendes versucht (was den root aus der Cron-Zeile entfernt):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

Dies stellte sich als die endgültige Lösung heraus. [Obwohl ich in Unmengen von Literatur die fehlerhafte Zeile mit root in der Cron-Zeile fand. Das war ein Fehler].

Antwort3

Ein "Problem" mit cron ist das Fehlen von Umgebungsvariablen (füroffensichtlichSicherheitsgründen). Wahrscheinlich fehlen PATH und HOME. Diese können Sie direkt im Skript oder in der Crontab-Datei definieren.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Sie müssen testen, bis alle erforderlichen Variablen wie vom Skript gefordert definiert sind.

Antwort4

Sie können diese Zeile in Ihr Skript einfügen. Nachdem Sie die Cron-Protokolle überprüft und bestätigt haben, dass Ihr Job ausgeführt wurde, können Sie denselben $PATH abrufen, den die Crontabs hatten.

/bin/echo $PATH > /root/path.txt

Und das Beste, was Sie tun können, um Probleme in Cron-Skripten zu diagnostizieren, ist wahrscheinlich, alle Umgebungsvariablen von SO mit dem Befehl env in Ihrem Skript abzurufen. Fügen Sie also einfach diese Zeile zu Ihrem Skript hinzu. Anschließend können Sie die Ausgabe analysierenallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

Ein weiterer Trick besteht darin, die Ausgabe des Skripts an einen anderen Ort zu leiten. Durch Hinzufügen von /root/log.log. Auf diese Weise bleibt die gesamte Ausgabe des Skripts erhalten in/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

Sie können das Skript auch so planen, dass es jede Minute ausgeführt wird, um die Tests und Prüfungen zu erleichtern.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

verwandte Informationen