Ich versuche hier, ein Shell-Skript zu schreiben, das meinen Server ständig testet und mir eine E-Mail sendet, wenn er ausfällt.
Das Problem ist, dass wenn ich mich von einer SSH-Verbindung abmelde, obwohl ich sie &
am Ende des Befehls ausführe ./stest01.sh &
, sie automatisch in else fällt und mich ununterbrochen weiterschickt, bis ich mich erneut anmelde und sie beende.
#!/bin/bash
while true; do
date > sdown.txt ;
cp /dev/null pingop.txt ;
ping -i 1 -c 1 -W 1 myserver.net > pingop.txt &
sleep 1 ;
if
grep "64 bytes" pingop.txt ;
then
:
else
mutt -s "Server Down!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done
linux
shell-script
grep
ping
Vasconcelos1914
quelle
quelle
:
? Es würde für mich Sinn machen, wenn es ein Semikolon wäre;
...:
macht nichts. Dafür ist es konzipiert. Anstatt den Test umzukehren, verwenden sie ihn, um zuvor ein No-Op durchzuführenelse
.Antworten:
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 denelse
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):Hier haben wir
grep
für den String, derecho
erzeugt, aber wir schließen beide Ausgabestreams fürgrep
, damit er nirgendwo schreiben kann. Wie Sie sehen können, ist der Exit-Status von GNUgrep
2 statt 0.Dies gilt insbesondere für GNU
grep
, da sichgrep
BSD-Systeme nicht gleich verhalten: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 seingrep
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:
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):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 zBsleep 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):
Als Cron-Job, der jede Minute ausgeführt wird (würde weiterhin jede Minute E-Mails senden, wenn der Server weiterhin ausfällt):
quelle
>&-
wird das fd geschlossen (wie in, Dateideskriptor 1 ist geschlossen), während das Schließen der SSH-Verbindung einen anderen Effekt hat (ein Dateideskriptor ist immer noch vorhanden, aber mit nichts auf der anderen Seite verbunden). Ich denke, der Punkt steht immer noch, das heißt, dass GNU grep ungleich Null beendet wird, wenn es versucht, eine Ausgabe zu schreiben, und dies fehlschlägt. Ja, die beste Lösung besteht darin, den Exit-Status von Ping direkt zu überprüfen.exec </dev/null >/dev/null 2>&1
am Anfang hinzufügen . Auf diese Weiseping
verursacht es kein Problem , wenn z. B. beschlossen wird, etwas an stderr zu schreiben./dev/null
hier zu ziehen , aber ich habe die Ausgabe aussortiert. Danke für den Vorschlag.