Wenn GNU grep
versucht, das Ergebnis zu schreiben, schlägt es mit einem Exit-Status ungleich Null fehl, da die Ausgabe nirgends geschrieben werden kann, da die SSH-Verbindung unterbrochen ist.
Dies bedeutet, dass die if
Anweisung immer den else
Zweig übernimmt .
Um dies zu veranschaulichen (dies ist nicht genau das, was in Ihrem Fall passiert, aber es zeigt, was passiert, wenn GNU grep
seine Ausgabe nicht schreiben kann):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Hier haben wir grep
für den String, der echo
erzeugt, aber wir schließen beide Ausgabestreams für grep
, damit er nirgendwo schreiben kann. Wie Sie sehen können, ist der Exit-Status von GNU grep
2 statt 0.
Dies gilt insbesondere für GNU grep
, da sich grep
BSD-Systeme nicht gleich verhalten:
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
Um dies zu beheben, stellen Sie sicher, dass das Skript keine Ausgabe generiert. Sie können dies mit tun exec >/dev/null 2>&1
. Außerdem sollten wir verwenden sein grep
mit seiner -q
Wahl , da wir in haupt nicht daran interessiert sind zu sehen , die Ausgabe von ihm (dies in der Regel auch die beschleunigen würde , grep
da es nicht die ganze Datei zu analysieren braucht, aber in diesem Fall ist es macht sehr wenig Geschwindigkeitsunterschied, da die Datei so klein ist).
Zusamenfassend:
#!/bin/sh
# redirect all output not redirected elsewhere to /dev/null by default:
exec >/dev/null 2>&1
while true; do
date >sdown.txt
ping -c 1 -W 1 myserver.net >pingop.txt
if ! grep -q "64 bytes" pingop.txt; then
mutt -s "Server Down!" myemail@address.com <sdown.txt
break
fi
sleep 10
done
Sie können einen Test auch ping
direkt für verwenden, um die Notwendigkeit einer der Zwischendateien zu beseitigen (und auch die andere Zwischendatei zu entfernen, die wirklich immer nur einen Datenstempel enthält):
#!/bin/sh
exec >/dev/null 2>&1
while true; do
if ! ping -q -c 1 -W 1 myserver.net; then
date | mutt -s "Server Down!" myemail@address.com
break
fi
sleep 10
done
In beiden Varianten des obigen Skripts entscheide ich mich, die Schleife zu verlassen, wenn der Host nicht erreicht wird, um die Anzahl der gesendeten E-Mails zu minimieren. Sie können stattdessen das break
durch zB sleep 10m
oder etwas ersetzen , wenn Sie erwarten, dass der Server irgendwann wieder hochfährt.
Ich habe auch die verwendeten Optionen leicht angepasst, ping
da -i 1
dies nicht viel Sinn macht -c 1
.
Kürzere (es sei denn, Sie möchten, dass weiterhin E-Mails gesendet werden, wenn der Host nicht erreichbar ist):
#!/bin/sh
exec >/dev/null 2>&1
while ping -q -c 1 -W 1 myserver.net; do
sleep 10
done
date | mutt -s "Server Down!" myemail@address.com
Als Cron-Job, der jede Minute ausgeführt wird (würde weiterhin jede Minute E-Mails senden, wenn der Server weiterhin ausfällt):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )
:
? Es würde für mich Sinn machen, wenn es ein Semikolon wäre;
...