Ich führe ein Skript aus, das davon abhängt, dass das Netzwerk aktiv ist und eine Netzwerkfreigabe bereitgestellt wird. Das Skript wird bei der Anmeldung ausgeführt (was automatisch nach dem Start erfolgt). Das Problem ist, dass ich zum Zeitpunkt der Ausführung des Skripts normalerweise noch keine IP-Adresse (DHCP) habe. Im Moment schlafe ich das Skript nur für 15 Sekunden, aber ich mag diesen Ansatz überhaupt nicht, da ich dem Benutzer mitteilen möchte, ob etwas nicht stimmt.
Was ich vorhabe, ist eine Schleife, während ich noch keine IP-Adresse habe, und dann fortzufahren. Entscheidend ist, dass es nach einer Weile eine Auszeit geben muss. Was ich mir if [ ifconfig | grep "192.168.100" ];
ausgedacht habe ist, aber was passiert ist, dass grepconsumes das ];
und es nicht mag. Dann wird Bash auch wütend, weil es nicht findet, ];
welcher Grep gegessen hat. Und dann habe ich das Timeout noch nicht einmal implementiert.
Jemand schlug vor, eine Variable beizubehalten und beispielsweise in jeder Iteration eine Sekunde zu schlafen und diese Variable jedes Mal zu erhöhen. Hier ist mein vollständiges (nicht funktionierendes) Skript (ich bin ziemlich neu im Bash-Scripting):
x=0
while [ ifconfig | grep "192.168.100." > /dev/null ]; do
echo "no nework"
if "$x" -gt 200; then
#Time out here
exit 1
x=$((x+1))
sleep .1
fi
done
#continue with rest of script...
Alle Hinweise in die richtige Richtung wäre sehr dankbar!
quelle
network-online.target
... wartetgrep
Ausgabe muss nicht umgeleitet werden/dev/null
. Verwenden Sie-q
stattdessen die Option. Und ich finde es auch nicht gut, wenn ifconfig eine gute Idee ist. Warum nichtping
stattdessen verwenden?ping
kann je nach Netzwerk fehlschlagen. Es ist besser, nur die laufende Konfiguration des Systems zu überprüfen.Antworten:
Shell-Syntax
Sie scheinen hinsichtlich der Bedingungen in Shell-Skripten verwirrt zu sein. Jeder Shell-Befehl hat einen Exit-Status, der eine Ganzzahl zwischen 0 und 255 ist, wobei 0 Erfolg und jeder andere Wert Fehler bedeutet. Anweisungen wie
if
undwhile
, die boolesche Operanden erwarten, überprüfen den Exit-Status des Befehls und behandeln 0 (Erfolg) als wahr und jeden anderen Wert (Fehler) als falsch.Beispielsweise gibt der
grep
Befehl 0 zurück, wenn das Muster gefunden wird, und 1, wenn das Muster nicht gefunden wird. Damitwiederholt die Schleife, solange das Muster
192.168.100.
in der Ausgabe von gefunden wirdifconfig
. Beachten Sie, dass das Muster192.168.100.
mit Zeichenfolgen wie übereinstimmt192x168 1007
, da.
in einem regulären Ausdruck ein beliebiges Zeichen übereinstimmt. Übergeben Sie die Option-F
an , um nach einer Literalzeichenfolge zu suchengrep
. Um den Zustand umzukehren, stellen Sie ihn!
vor.Weiter im Skript möchten Sie den Wert einer Variablen mit einer Zahl vergleichen. Sie verwenden den
-gt
Operator, der Teil der Syntax der vom Befehl verstandenen bedingten Ausdrücke isttest
. Dertest
Befehl gibt 0 zurück, wenn der bedingte Ausdruck wahr ist, und 1, wenn der bedingte Ausdruck falsch ist.Es ist üblich, den alternativen Namen
[
für dentest
Befehl zu verwenden. Dieser Name erwartet, dass der Befehl mit dem Parameter endet]
. Die beiden Schreibweisen dieses Befehls sind genau gleichwertig.Bash bietet auch eine dritte Möglichkeit, diesen Befehl mit der speziellen Syntax zu schreiben
[[ … ]]
. Diese spezielle Syntax kann einige Operatoren mehr unterstützen als[
, da[
ein gewöhnlicher Befehl den üblichen Parsing-Regeln[[ … ]]
unterliegt und Teil der Shell-Syntax ist.Auch bedenken Sie, dass
[
für ist bedingte Ausdrücke , die eine Syntax mit Operatoren wie ist-n
,-gt
...[
bedeutet nicht „boolean value“: (Exit - Status = 0) jeder Befehl einen Booleschen Wert hat.Erkennen, dass das Netzwerk aktiv ist
Ihre Methode zum Erkennen, dass das Netzwerk aktiv ist, ist nicht robust. Beachten Sie insbesondere, dass Ihr Skript ausgelöst wird, sobald eine Netzwerkschnittstelle eine IP-Adresse innerhalb des angegebenen Bereichs erhält. Insbesondere ist es durchaus möglich, dass DNS zu diesem Zeitpunkt noch nicht aktiv ist, geschweige denn, dass Netzwerkfreigaben bereitgestellt werden.
Müssen Sie diese Befehle wirklich ausführen, wenn sich jemand anmeldet? Es ist einfacher, einen Befehl automatisch auszuführen, wenn das Netzwerk aufgerufen wird. Die Vorgehensweise hängt von Ihrer Distribution ab und davon, ob Sie NetworkManager verwenden.
Wenn Sie diese Befehle als Teil der Anmeldeskripts ausführen müssen, testen Sie die Ressource, die Sie wirklich benötigen, und nicht das Vorhandensein einer IP-Adresse. Wenn Sie beispielsweise testen möchten, ob
/net/somenode/somedir
gemountet ist, verwenden SieWenn Sie Emporkömmling oder System haben ...
dann kannst du es benutzen. Markieren Sie beispielsweise bei Upstart Ihren Job als
start on net-device-up eth0
(eth0
durch den Namen der Schnittstelle ersetzen , die die gewünschte Netzwerkkonnektivität bereitstellt). Siehe Mit Systemd Verursachen, dass ein Skript ausgeführt wird, nachdem das Netzwerk gestartet wurde?quelle
/net/
sollte sein/proc/net
?/net
ein häufiger Speicherort für solche Mount-Punkte ist.Zählen Sie einfach die Ausgabe von
ip add show
Zum Beispiel:Dann können Sie einfach nach der Anzahl der zurückgegebenen Zeilen verzweigen. Sie würden wahrscheinlich nur prüfen, ob es Null ist, und wenn ja, schlafen und die Schleife wiederholen.
Ungetesteter Code zur Veranschaulichung:
quelle
Ping gibt eine 0-Antwort zurück, wenn mindestens ein Versuch erfolgreich war. Sie können den Server, zu dem Sie eine Verbindung herstellen, anpingen, bis er erfolgreich ist.
quelle