Ich laufe unter Skript:
#!/bin/bash
ps ax | grep -q [v]arnish
if [ $? -eq 0 ];then
echo varnish is running...
exit 0
else
echo "Critical : varnish is not running "
exit 2
fi
Die Ausgabe ist wie ::
[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0
Wenn ich dasselbe in der Befehlszeile ausführe, erhalte ich den Beendigungsstatus 1:
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
Der Fall ist, als wäre kein Lack auf dem Server installiert. Dieses Skript funktioniert gut auf einem Server, auf dem Lack installiert ist.
Warum unterschiedlicher Exit-Status bei Ausführung über Skript und Befehlszeile? Wie kann ich dieses Skript verbessern?
shell-script
process
ps
exit-status
Prado
quelle
quelle
Antworten:
Wenn Sie ein Skript mit dem Namen
check_varnish_pro.sh
test ausführenist erfolgreich, weil ein Skript namens
check_
Lack_pro
ausgeführt wird.quelle
Im Allgemeinen ist es eine schlechte Idee , den einfachen Ansatz mit , um zu versuchen
ps
undgrep
zu versuchen , einen bestimmten Prozess zu bestimmen , ob ausgeführt wird .Sie wären dafür viel besser dran
pgrep
:Siehe das Handbuch für
pgrep
. Auf einigen Systemen (wahrscheinlich nicht unter Linux) erhalten Sie ein-q
Flag, das demselben Flag entspricht, fürgrep
das keine Umleitung mehr erforderlich ist/dev/null
. Es gibt auch ein-f
Flag, das die Übereinstimmung in der vollständigen Befehlszeile und nicht nur im Prozessnamen ausführt. Man kann die Übereinstimmung auch auf Prozesse beschränken, die zu einem bestimmten Benutzer gehören-u
.Durch die Installation erhalten
pgrep
Sie auch Zugriff, mitpkill
dem Sie Prozesse anhand ihrer Namen signalisieren können.Auch wenn dies ein Service - Daemon , und wenn Ihr Unix - System eine Möglichkeit , Abfragen für Informationen (zB ob es sich um und läuft oder nicht) hat, dann ist das die richtige Art und Weise auf sie zu prüfen.
Unter Linux haben Sie
systemctl
(systemctl is-active --quiet varnish
wird 0 zurückgeben, wenn es ausgeführt wird, andernfalls 3), unter OpenBSDrcctl
usw.Nun zu Ihrem Skript:
In Ihrem Skript analysieren Sie die Ausgabe von
ps ax
. Diese Ausgabe enthält den Namen des Skripts selbstcheck_varnish_pro.sh
, das offensichtlich die Zeichenfolge enthältvarnish
. Dies gibt Ihnen ein falsches Positiv. Sie hätten dies entdeckt, wenn Sie es beim Testen ohne-q
Flag ausgeführt hättengrep
.Ausführen:
Ein weiteres Problem ist, dass Sie zwar versuchen, den
grep
Prozessgrep
durch die Verwendung[v]
im Muster vor dem Erkennen durch sich selbst zu "verbergen" . Dieser Ansatz schlägt fehl, wenn Sie das Skript oder die Befehlszeile in einem Verzeichnis ausführen, in dem eine Datei oder ein Verzeichnis benanntvarnish
ist (in diesem Fall erhalten Sie erneut ein falsches Positiv). Dies liegt daran, dass das Muster nicht in Anführungszeichen gesetzt ist und die Shell damit das Dateinamen-Globbing ausführt.Sehen:
Das Vorhandensein der Datei
varnish
führt dazu, dass die Shell durch[v]arnish
den Dateinamen ersetzt wirdvarnish
und Sie einen Treffer auf das Muster in der Prozesstabelle (demgrep
Prozess) erhalten.quelle
check_varnish_pro.sh
ist ebenfalls ein Faktor.@AlexP erklärt sehr prägnant, was tatsächlich passiert, aber @ Kusalanandas Idee ,
pgrep
/pkill
für einen kritischen Prozess zu verwenden, wird dringend abgeraten . Bessere Lösungen umfassen:systemctl status varnishd
sollte sich bei einer modernen * nix-Installation darum kümmern.Wenn Sie unter unglücklichen Umständen keinen Dienst zur Verfügung haben, können Sie einfach das Startskript ändern, um das Problem zu melden, sobald der Prozess beendet wird:
kill -0 "$pid"
.quelle
systemctl
fast nur unter Linux (AFAIK) und nicht auf allen modernen Unix-ähnlichen Systemen verfügbar ist.