Wie teste ich eine Internetverbindung mit bash?

113

Wie kann eine Internetverbindung getestet werden, ohne eine Website anzupingen? Ich meine, was ist, wenn eine Verbindung besteht, die Site jedoch nicht verfügbar ist? Gibt es einen Scheck für eine Verbindung mit der Welt?

lauriys
quelle
2
mehrere verschiedene Websites pingen?
1
aber ich möchte keine Websites anpingen, gibt es keine andere Option?
Lauriys
6
Ich möchte nur sehen, dass es vielleicht einen anderen Weg gibt!
Lauris
2
Es gibt keinen besseren Weg, als ein einzelnes Paket an eine Reihe von Adressen zu senden und zu empfangen, von denen Sie wissen, dass sie nicht alle gleichzeitig offline gehen sollen. Eine andere Möglichkeit besteht darin, Ihr aktuell festgelegtes DNS zu überprüfen, wenn Sie nicht möchten, dass Ihre Anwendung einen öffentlichen Ping-Befehl sendet Domain.
Tamara Wijsman
14
Ich möchte wissen, ob jemand zuhört, ohne ein Geräusch zu machen!
Kaz

Antworten:

130

Ohne Ping

#!/bin/bash

wget -q --spider http://google.com

if [ $? -eq 0 ]; then
    echo "Online"
else
    echo "Offline"
fi

-q : Stummschaltungsmodus

--spider : nicht bekommen, nur Seitenverfügbarkeit prüfen

$? : Shell-Rückkehrcode

0 : Shell-Code "Alles in Ordnung"

Ohne wget

#!/bin/bash

echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1

if [ $? -eq 0 ]; then
    echo "Online"
else
    echo "Offline"
fi
user3439968
quelle
2
sehr schön ... aber natürlich wird davon ausgegangen, dass die box wget hat. eingebettete Geräte und so weiter wahrscheinlich nicht. ;)
Eric Sebasta
5
Versuchen Sie Folgendes: echo -e "GET google.com HTTP / 1.0 \ n \ n" | nc google.com 80> / dev / null 2> & 1
user3439968
1
Auch hier wäre tcping hilfreich. (tcping www.yahoo.com 80) && echo "Site is up"
David Ramirez
Die if / else-Anweisung, die hier mit Erklärung verwendet wird, ist großartig. Danke !
Danijel-James W
1
@ user3439968 Sie müssen eine Zeitüberschreitung hinzufügen nc, um sicherzustellen, dass die Zeitüberschreitung abläuft . so etwas wienc google.com 80 -w 10
kaptan
93

Pingen Sie Ihr Standard-Gateway an:

#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error
mateusza
quelle
14
Gute Technik, es kann geändert werden, um in einer Funktion verwendet zu werden: function ping_gw() { ... && return 0 || return 1 }und dann wie ping_gw || (echo "no network, bye" && exit 1)
folgt
1
Auf Mac OS funktioniert dies nicht per Copy-Paste: "-bash: ip: Befehl nicht gefunden ping: illegale Option - w"
Benedikt S. Vogler
1
Gibt einen Fehlalarm aus, wenn er von einem Virtualisierungsgast ausgeführt wird, während der Host nicht verbunden ist.
Teresa e Junior
1
Gibt mir falsche Negative auf elementarem Betriebssystem (0.4.1, Acer Aspire E 15)
Malcolm
1
Sei vorsichtig damit. Ich habe dies gerade getestet ifconfig down wlan0und habe immer noch ein Standard-Gateway und es ist pingbar, obwohl ich die Außenwelt tatsächlich nicht erreichen kann.
Bruno Bronosky
29

Super Vielen Dank an den Benutzer somedrew für seinen Beitrag hier: https://bbs.archlinux.org/viewtopic.php?id=55485 am 2008-09-20 02:09:48

Ein Blick in / sys / class / net sollte eine Möglichkeit sein

Hier ist mein Skript zum Testen auf eine andere Netzwerkverbindung als die Rückschleife. Ich verwende das Folgende in einem anderen Skript, das ich habe, um regelmäßig zu testen, ob meine Website zugänglich ist. Wenn es NICHT zugänglich ist, weist mich ein Popup-Fenster auf ein Problem hin.

Das folgende Skript verhindert, dass ich alle fünf Minuten Popup-Nachrichten erhalte, wenn mein Laptop nicht mit dem Netzwerk verbunden ist.

#!/usr/bin/bash

# Test for network conection
for interface in $(ls /sys/class/net/ | grep -v lo);
do
  if [[ $(cat /sys/class/net/$interface/carrier) = 1 ]]; then OnLine=1; fi
done
if ! [ $OnLine ]; then echo "Not Online" > /dev/stderr; exit; fi

Hinweis für Neueinsteiger: Die letzte 'if'-Anweisung testet, ob NICHT [!] Online ist, und wird beendet, wenn dies der Fall ist. Weitere Informationen finden Sie unter man bash und suchen Sie nach "Ausdrücke können kombiniert werden".

PS Ich bin der Meinung, dass Ping hier nicht das Beste ist, da es darauf abzielt, eine Verbindung zu einem bestimmten Host zu testen. NICHT zu testen, ob eine Verbindung zu einem Netzwerk jeglicher Art besteht.

PPS The Above funktioniert unter Ubuntu 12.04. Das / sys ist in einigen anderen Distributionen möglicherweise nicht vorhanden. Siehe unten:

Moderne Linux-Distributionen enthalten ein / sys-Verzeichnis als virtuelles Dateisystem (sysfs, vergleichbar mit / proc, einem procfs), in dem die mit dem System verbundenen Geräte gespeichert und geändert werden können, während viele herkömmliche UNIX- und Unix-ähnliche Betriebssysteme verwendet werden / sys als symbolische Verknüpfung zum Kernel-Quellbaum. [Zitieren erforderlich]

Aus Wikipedia https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

Jesse
quelle
1
Vorsicht jetzt! "Funktioniert cat /sys/class/net/wwan0/carriernicht auf Ubuntu 14.04 LTS.
dotnetCarpenter
1
Sie können setzen wollen 2>/dev/nullnach cat /sys/class/net/$interface/carriernicht Fehlerausgang haben , falls Vernetzung deaktiviert ist.
jarno
25

Dies funktioniert sowohl unter MacOSX als auch unter Linux:

#!/bin/bash

ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline
legel
quelle
Außer osx ( ping: invalid option -- w)
avishayp
fping google.comoder macht einfach fping 8.8.8.8die Magie mit einem Bonus Sie erhalten Statuscode, ohne ihn testen zu müssen (" google.com is alive") ...
Roger
9

In Bash wird der Netzwerk-Wrapper über / dev / { udp , tcp } / host / port verwendet :

if : >/dev/tcp/8.8.8.8/53; then
  echo 'Internet available.'
else
  echo 'Offline.'
fi

( :ist das Bash-No-Op, weil Sie nur die Verbindung testen, aber nicht verarbeiten möchten.)

Luchostein
quelle
7

Ich habe zuvor Skripte geschrieben, die einfach Telnet verwenden, um eine Verbindung zu Port 80 herzustellen, und dann den Text übertragen:

HTTP/1.0 GET /index.html

gefolgt von zwei CR / LF-Sequenzen.

Vorausgesetzt, Sie erhalten eine HTTP-Antwort zurück, können Sie im Allgemeinen davon ausgehen, dass die Site funktioniert.

paxdiablo
quelle
3
Warum das Rad neu erfinden? Curl und Wget machen das beide perfekt.
Adam Rosenfield
6
Weil wget und curl nicht immer verfügbar sind (z. B. Einschränkungen in Unternehmensumgebungen). Telnet ist seit dem Zeitpunkt t = 0 ein Standardbestandteil jedes UNIX.
Paxdiablo
Ja, Telnetting ist seit einiger Zeit eine Standardmethode zum Testen von Verbindungen.
PTBNL
2
Guter Punkt, obwohl wget ziemlich häufig ist. Eine weitere Option ist netcat (nc), obwohl dies in diesem Fall keine Verbesserung gegenüber Telnet darstellt.
Adam Rosenfield
7

Bei der Top-Antwort fehlt die Tatsache, dass Sie eine perfekt stabile Verbindung zu Ihrem Standard-Gateway haben können. Dies bedeutet jedoch nicht automatisch, dass Sie tatsächlich etwas im Internet erreichen können. Das OP fragt, wie er / sie eine Verbindung mit der Welt testen kann. Daher schlage ich vor, die Top-Antwort zu ändern, indem Sie die Gateway-IP in eine bekannte IP (xyzw) ändern, die sich außerhalb Ihres LAN befindet.

Die Antwort würde also lauten:

ping -q -w 1 -c 1 x.y.z.w > /dev/null && echo ok || echo error

Entfernen Sie auch die ungünstigen Backticks für die Befehlsersetzung [1] .

Wenn Sie nur sicherstellen möchten, dass Sie mit der Welt verbunden sind, bevor Sie Code ausführen, können Sie auch Folgendes verwenden:

if ping -q -w 1 -c 1 x.y.z.w > /dev/null; then
    # more code
fi
Fuwan
quelle
6

Stellen Sie sicher, dass in Ihrem Netzwerk TCP-Datenverkehr ein- und ausgeht. Anschließend können Sie mit dem folgenden Befehl Ihre öffentlich zugängliche IP-Adresse wiederherstellen

curl ifconfig.co
WaiKit Kung
quelle
5

Führen Sie den folgenden Befehl aus, um zu überprüfen, ob eine Website aktiv ist und welche Statusmeldung der Webserver anzeigt:

$ curl -Is http://www.google.com | head -1 HTTP/1.1 200 OK

Der Statuscode '200 OK' bedeutet, dass die Anfrage erfolgreich war und eine Website erreichbar ist.

Chaminda Bandara
quelle
2
Eine bessere Implementierung könnte seincurl -Is http://www.google.com | head -1 | grep 200; if [[ $? -eq 0 ]]; then; echo "Online"; else; echo "Offline"; fi;
Luca Galasso
4

Wenn Ihr lokaler Nameserver nicht verfügbar ist,

ping 4.2.2.1

ist eine leicht zu merkende Always-Up-IP (eigentlich sogar ein Nameserver).

kurzlebig
quelle
5
ping 8.8.8.8 (Google NS)
user3439968
4

Die Antwort mit der höchsten Bewertung funktioniert nicht für MacOS. Für Benutzer eines Mac habe ich dies erfolgreich getestet:

GATEWAY=`route -n get default | grep gateway`
if [ -z "$GATEWAY" ]
  then
    echo error
else
  ping -q -t 1 -c 1 `echo $GATEWAY | cut -d ':' -f 2` > /dev/null && echo ok || echo error
fi

getestet unter MacOS High Sierra 10.12.6

Francisc0
quelle
2
Ändern Sie den routeBefehl so route -n get default 2> /dev/null | grep gateway, dass im Offline-Modus kein Fehler in stderr geschrieben wird.
Devstuff
4

Dieses Bash-Skript sucht kontinuierlich nach dem Internet und gibt einen Piepton aus, wenn das Internet verfügbar ist.

#!/bin/bash
play -n synth 0.3 sine 800 vol 0.75
while :
do
pingtime=$(ping -w 1 8.8.8.8 | grep ttl)
if [ "$pingtime" = "" ] 
then 
   pingtimetwo=$(ping -w 1 www.google.com | grep ttl) 
   if [ "$pingtimetwo" = "" ] 
   then 
       clear ; echo 'Offline'
   else
       clear ; echo 'Online' ; play -n synth 0.3 sine 800 vol 0.75
   fi 
else
    clear ; echo 'Online' ; play -n synth 0.3 sine 800 vol 0.75
fi
sleep 1
done
Arjun G Perambra
quelle
3

kürzester Weg: fping 4.2.2.1=> "4.2.2.1 lebt"

Ich bevorzuge dies, da es schneller und weniger ausführlich ausgegeben wird als der pingNachteil, dass Sie es installieren müssen.

Sie können eine beliebige öffentliche DNS anstelle einer bestimmten Website verwenden.

fping -q google.com && echo "do something because you're connected!"

-q Gibt einen Exit-Code zurück, daher zeige ich nur ein Beispiel für die Ausführung von etwas, das Sie online sind.

auf dem Mac installieren : brew install fping; auf Ubuntu:sudo apt-get install fping

Alex Moore-Niemi
quelle
2

Ping wurde entwickelt, um genau das zu tun, was Sie suchen. Wenn die Site jedoch das ICMP-Echo blockiert, können Sie das Telnet jederzeit für Port 80 einer Site, eines Wget oder eines Curls ausführen.

Nikudesu
quelle
2

Das Überprüfen der Google-Indexseite ist eine weitere Möglichkeit:

#!/bin/bash

WGET="/usr/bin/wget"

$WGET -q --tries=20 --timeout=10 http://www.google.com -O /tmp/google.idx &> /dev/null
if [ ! -s /tmp/google.idx ]
then
    echo "Not Connected..!"
else
    echo "Connected..!"
fi
dm76
quelle
2

Ähnlich wie bei der Antwort von @ Jesse ist diese Option möglicherweise viel schneller als jede Lösung pingund möglicherweise etwas effizienter als die Antwort von @ Jesse .

find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1' {} \; | grep -q '1'

Explenation:

Dieser Befehl verwendet findmit -execBefehl für alle Dateien ausgeführt werden nicht genannt *lo*in /sys/class/net/. Dies sollten Links zu Verzeichnissen sein, die Informationen zu den verfügbaren Netzwerkschnittstellen auf Ihrem Computer enthalten.

Der ausgeführte Befehl ist ein shBefehl, der den Inhalt der Datei carrierin diesen Verzeichnissen überprüft . Der Wert von $interface/carrierhat 3 Bedeutungen - Zitat :

Es scheint drei Staaten zu geben:

  • ./carrier nicht lesbar (z. B. wenn die Schnittstelle in Network Manager deaktiviert ist).
  • ./Träger enthalten "1" (wenn die Schnittstelle aktiviert und mit einem WiFi-Netzwerk verbunden ist)
  • ./Träger enthalten "0" (wenn die Schnittstelle aktiviert ist und keine Verbindung zu einem WiFi-Netzwerk besteht)

Die erste Option wird in der Antwort von @ Jesse nicht berücksichtigt . Der shgestreifte Befehl lautet:

# Note: $0 == $interface
cat "$0"/carrier 2>&1

catwird verwendet, um den Inhalt der carriergesamten Ausgabe zu überprüfen und sie auf die Standardausgabe umzuleiten, auch wenn dies fehlschlägt, da die Datei nicht lesbar ist. Wenn grep -qFunde "1"unter diesen Dateien bedeutet dies , gibt es mindestens 1 - Schnittstelle verbunden. Der Exit-Code von grep -qist der endgültige Exit-Code.

Verwendung

Wenn Sie beispielsweise den Exit-Status dieses Befehls verwenden, können Sie damit nur dann einen Gnubiff in Ihrem Befehl starten, ~/.xprofilewenn Sie über eine Internetverbindung verfügen.

online() {
    find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1 > /dev/null | grep -q "1" && exit 0' {} \;
}
online && gnubiff --systemtray --noconfigure &

Referenz

Doron Behar
quelle
1

Pong bedeutet nicht, dass der Webdienst auf dem Server ausgeführt wird. Dies bedeutet lediglich, dass der Server auf das ICMP-Echo antwortet. Ich würde empfehlen, Curl zu verwenden und den Rückgabewert zu überprüfen.

Tomoe
quelle
0

Wenn Sie tatsächlich nach einem Internetzugang suchen möchten, sind viele der vorhandenen Antworten auf diese Frage fehlerhaft. Einige Dinge, die Sie beachten sollten:

  1. Es ist möglich, dass Ihr Computer mit einem Netzwerk verbunden ist, ohne dass dieses Netzwerk über einen Internetzugang verfügt
  2. Es ist möglich, dass ein Server ausfällt, ohne dass auf das gesamte Internet zugegriffen werden kann
  3. Ein Captive-Portal kann eine HTTP-Antwort für eine beliebige URL zurückgeben, auch wenn Sie keinen Internetzugang haben

Vor diesem Hintergrund glaube ich, dass die beste Strategie darin besteht, mehrere Sites über eine HTTPS-Verbindung zu kontaktieren und true zurückzugeben, wenn eine dieser Sites antwortet.

Beispielsweise:

connected_to_internet() {
  test_urls="\
  https://www.google.com/ \
  https://www.microsoft.com/ \
  https://www.cloudflare.com/ \
  "

  processes="0"
  pids=""

  for test_url in $test_urls; do
    curl --silent --head "$test_url" > /dev/null &
    pids="$pids $!"
    processes=$(($processes + 1))
  done

  while [ $processes -gt 0 ]; do
    for pid in $pids; do
      if ! ps | grep "^[[:blank:]]*$pid[[:blank:]]" > /dev/null; then
        # Process no longer running
        processes=$(($processes - 1))
        pids=$(echo "$pids" | sed --regexp-extended "s/(^| )$pid($| )/ /g")

        if wait $pid; then
          # Success! We have a connection to at least one public site, so the
          # internet is up. Ignore other exit statuses.
          kill -TERM $pids > /dev/null 2>&1 || true
          wait $pids
          return 0
        fi
      fi
    done
    # wait -n $pids # Better than sleep, but not supported on all systems
    sleep 0.1
  done

  return 1
}

Verwendung:

if connected_to_internet; then
  echo "Connected to internet"
else
  echo "No internet connection"
fi

Einige Anmerkungen zu diesem Ansatz:

  1. Es ist robust gegen alle oben beschriebenen falsch positiven und negativen Ergebnisse
  2. Die Anforderungen erfolgen alle parallel, um die Geschwindigkeit zu maximieren
  3. Es wird false zurückgegeben, wenn Sie technisch über einen Internetzugang verfügen, DNS jedoch nicht funktioniert oder Ihre Netzwerkeinstellungen anderweitig durcheinander sind, was meiner Meinung nach in den meisten Fällen sinnvoll ist
Ajedi32
quelle
Der Rückkehrcode von curl wird nicht getestet. Wenn das Netzwerk auf meinem System nicht verfügbar ist, gibt curl rc = 6 (fehlgeschlagene DNS-Auflösung) an, aber dieser Code meldet weiterhin "Mit dem Internet verbunden".
Ceperman
@ceperman Der Rückkehrcode für Curl wird in der Zeile getestet, in der er steht if wait $pid;. Keine Ahnung, warum das auf Ihrem System nicht funktioniert. Bist du sicher, dass du Bash verwendest?
Ajedi32
@ceperman Eine andere Möglichkeit; Vielleicht bringt eine der URLs in der Liste oben tatsächlich Erfolg für Sie, obwohl die anderen die Namensauflösung nicht erfüllen?
Ajedi32
2
Meine Bash ist ziemlich einfach, also lese ich weiter waitund verstehe jetzt, dass der Rückkehrcode tatsächlich getestet wird. Ich habe Ihren Code erneut kopiert und heute funktioniert es - whoops! Ich muss beim letzten Mal etwas durcheinander gebracht haben, obwohl ich nicht verstehen kann, was oder wie. Trotzdem mea culpa. Entschuldigung.
Ceperman
-1

Dies ist deutlich schneller als jede hier veröffentlichte Lösung und kann auch zum Testen eines bestimmten Hosts verwendet werden.

Der Trick besteht darin, die IP mit einem weniger ausgelasteten DNS-Solver zu lösen als dem von ping:

validateConnection () {
    host="${1}"
    ip=$(getent ahostsv4 "${host}" | awk '{ print $1 }' | head -n1)
    ping -c1 "${ip}" 2>&1 >"/dev/null"

    if [ "${?}" -ne 0 ]; then
        echo "No connection to: ${host}" >&2
        exit 1
    fi
}
Alberto Salvia Novella
quelle
2
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - Aus der Rezension
David Buck
Dies gilt nicht für diese besondere Situation.
Alberto Salvia Novella