Wenn ich ein Skript von einem ( root
) Cronjob aus aufrufe, schlägt es mit der Meldung „IPset nicht gefunden“ fehl. Hier ist die problematische Skriptzeile:
for i in $(cat /etc/cn.zone); do ipset -A china $i; done
Einige Zeilen zuvor wird im Skript dieser Befehl aufgerufen:
ipset -N china hash:net
Daher wurde das betreffende IPset tatsächlich erstellt.
Wenn ich dieses Skript vom Stammverzeichnis des Root-Benutzers aus ausführe, läuft es einwandfrei.
Irgendeine Idee, was die Fehlerursache sein könnte?
Antwort1
Ihr Skript erkennt Ihre Umgebungsvariablen nicht, wenn es als Cron-Job ausgeführt wird.
Ich rufe ein Skript von einem (
root
) Cronjob aus auf und es schlägt mit der Meldung „IPset nicht gefunden“ fehl …
Führen Sie dieses Skript als Bash-Skript aus (was heutzutage bei den meisten Shell-Skripten der Fall ist)?
Wenn ja, ändern Sie die erste Zeile Ihres Skripts von
#!/bin/bash
Hierzu:
#!/bin/bash -l
Durch das Hinzufügen -l
wird Bash so ausgeführt, als wäre es als Login-Shell aufgerufen worden. Und wenn das Bash-Skript in diesem Cron-Job über die Login-Shell ausgeführt wird, stehen alle Umgebungsvariablen – und andere Elemente –, die normalerweise über die Login-Shell festgelegt werden, diesem Bash-Skript zur Verfügung, sodass es ipset
wie erwartet ausgeführt werden kann.
Ein weiterer Trick, den Sie anwenden können, ist die Verwendung which
innerhalb einer Bash-Variable wie dieser; Sie verwenden dies offensichtlich für, $(cat /etc/cn.zone)
daher ist der Mechanismus ähnlich:
$(which ipset)
Und ändern Sie in Ihrem Skript die Zeile wie folgt:
for i in $(cat /etc/cn.zone); do $(which ipset) -A china $i; done
Das bedeutet, dass Sie which
Ihrem Skript mithilfe von den vollständigen Pfad ipset
(etwa /sbin/ipset
) auf dem System, auf dem Sie es ausführen, geben. Wenn Sie diesen Pfad dann über als analysierte Variable festlegen, $()
kann das Skript ihn selbst ausführen.
ipset
Da Sie es aber an anderer Stelle in Ihrem Skript verwenden , würde ich Ihnen – wenn Sie diese which
Methode verwenden – empfehlen, Ihr Skript so umzugestalten, dass es ipset
oben in Ihrem Skript eine Variable wie diese festlegt:
ipset_bin=$(which ipset);
Und rufen Sie dann Ihre Befehle wie folgt auf:
$ipset_bin -N china hash:net
Und das:
for i in $(cat /etc/cn.zone); do $ipset_bin -A china $i; done
Antwort2
Ihre Shell weiß, wo ausführbare Dateien zu finden sind , ipset
indem sie beispielsweise in Ihrem nachschaut PATH
, das von Ihrer Umgebung festgelegt wird, aber cron
nicht dieselbe Umgebung teilt.
Wenn Sie dies oben crontab
(oder in Ihrem Skript) hinzufügen, sollte es wie erwartet wissen, wo die Befehle zu finden sind:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin