it-swarm.com.de

Wie teste ich eine Internetverbindung mit bash?

Wie kann eine Internetverbindung getestet werden, ohne auf eine Website zu pingen? Gibt es einen Check für eine Verbindung zur Welt?

83
lauriys

Ohne Ping

#!/bin/bash

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

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

-q : Stummschaltung

--spider : nicht bekommen, einfach die Seitenverfügbarkeit prüfen

$? : Shell-Rückkehrcode

0 : Shell-Code "All OK"

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
97
user3439968

Pingen Sie Ihr Standardgateway:

#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error
87
mateusza

Super Dank an Benutzer somedrew für ihren 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 einer anderen Netzwerkverbindung als dem Loopback. Ich verwende das Folgende in einem anderen Skript, mit dem ich regelmäßig prüfe, ob meine Website zugänglich ist. Wenn der Zugriff nicht möglich ist, benachrichtigt mich ein Popup-Fenster über ein Problem.

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 Bash-Neulinge: Die letzte 'if'-Anweisung testet, ob NOT [!] Online ist und beendet sich, wenn dies der Fall ist. Weitere Informationen finden Sie unter man bash und suchen Sie nach "Ausdrücke können kombiniert werden".

P.S. Ich denke, Ping ist hier nicht das Beste, weil es darauf abzielt, eine Verbindung zu testen zu einem bestimmten Host ​​NICHT zu testen, ob es eine Verbindung zu einem Netzwerk gibt zu irgendeiner Art.

P.P.S. Das Obige funktioniert unter Ubuntu 12.04 Das/sys existiert möglicherweise nicht in allen anderen Distributionen. 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-Source-Tree.

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

27
Jesse

Dies funktioniert sowohl unter MacOSX als auch unter Linux:

#!/bin/bash

ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline
20
legel

Ich habe bereits zuvor Skripts geschrieben, die einfach über Telnet eine Verbindung zu Port 80 herstellen und dann den Text übertragen:

HTTP/1.0 GET /index.html

gefolgt von zwei CR/LF-Sequenzen.

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

8
paxdiablo

Die erste Antwort vermisst die Tatsache, dass Sie eine absolut stabile Verbindung zu Ihrem Standardgateway haben können. Dies bedeutet jedoch nicht automatisch, dass Sie tatsächlich etwas im Internet erreichen können. Das OP fragt, wie er eine Verbindung mit der Welt testen kann. Ich schlage daher vor, die oberste Antwort zu ändern, indem Sie die Gateway-IP in eine bekannte IP (x.y.z.w) ändern, die sich außerhalb Ihres LANs befindet. 

Die Antwort wäre also:

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
5
Fuwan

Führen Sie den folgenden Befehl aus, um zu prü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

Statuscode „200 OK“ bedeutet, dass die Anforderung erfolgreich war und eine Website erreichbar ist.

4

Wenn Ihr lokaler Nameserver inaktiv ist,

 ping 4.2.2.1 

ist eine einfach zu merkende Always-Up-IP (es handelt sich sogar um einen Nameserver).

4
ephemient

vergewissern Sie sich, dass Ihr Netzwerk TCP - Datenverkehr zulässt, und Sie können Ihre öffentliche IP-Adresse mit dem folgenden Befehl wiederherstellen

curl ifconfig.co
4
WaiKit Kung

Die Top-Voting-Antwort funktioniert nicht für MacOS. Für Mac-Anwender 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 auf MacOS High Sierra 10.12.6

3
Francisc0

Ähnlich wie @ Jesses Antwort ist diese Option möglicherweise viel schneller als jede Lösung, die ping verwendet, und möglicherweise etwas effizienter als @ Jesses Antwort .

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

Erklärung:

Dieser Befehl verwendet find mit -exec, um den Befehl für alle Dateien auszuführen, die nicht *lo* in /sys/class/net/ heißen. Dies sollten Links zu Verzeichnissen sein, die Informationen zu den verfügbaren Netzwerkschnittstellen Ihres Computers enthalten.

Der Befehl, der ausgeführt wird, ist ein sh-Befehl, der den Inhalt der Datei carrier in diesen Verzeichnissen überprüft. Der Wert von $interface/carrier hat 3 Bedeutungen - Zitieren :

Es scheint, dass es drei Zustände gibt:

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

Die erste Option wird in @ Jesses Antwort nicht berücksichtigt. Der sh Befehl wurde gestreift:

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

cat wird verwendet, um den Inhalt von carrier zu überprüfen und alle Ausgaben zur Standardausgabe umzuleiten, auch wenn die Datei nicht lesbar ist ..__ Wenn grep -q"1" zwischen diesen Dateien findet, bedeutet dies, dass mindestens eine Schnittstelle angeschlossen ist. Der Beendigungscode von grep -q ist der endgültige Beendigungscode.

Verwendungszweck

Wenn Sie zum Beispiel den Exit-Status dieses Befehls verwenden, können Sie einen gnubiff in Ihrem ~/.xprofile nur dann starten, wenn Sie eine Internetverbindung haben.

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

2
Doron Behar

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

2
nikudesu

Dieses Bash-Skript sucht ständig nach Internet und gibt einen Signalton 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
2

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

ich ziehe dies vor, da die Ausgabe schneller und weniger ausführlich ist als ping.

sie können beliebige public 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, wenn Sie etwas online ausführen.

installation unter Mac: brew install fping; auf ubuntu: Sudo apt-get install fping

2

Das Überprüfen der Indexseite von Google bietet eine andere 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
1
dm76

Pong bedeutet nicht, dass der Webservice auf dem Server ausgeführt wird. es bedeutet lediglich, dass der Server auf ICMP-Echo antwortet.

1
tomoe

Wenn Sie tatsächlich nach Internet suchen möchten, sind viele der vorhandenen Antworten auf diese Frage fehlerhaft. Ein paar 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 das gesamte Internet zugänglich ist
  3. Es ist möglich, dass ein Captive-Portal eine HTTP-Antwort für eine beliebige URL zurückgibt, auch wenn Sie keinen Internetzugang haben

Aus diesem Grund 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.

Zum Beispiel:

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
}

Verwendungszweck:

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über all den falschen Positiven und Negativen, die ich oben skizziert habe
  2. Die Anforderungen werden alle parallel ausgeführt, um die Geschwindigkeit zu maximieren
  3. Es wird false zurückgegeben, wenn Sie technisch über einen Internetzugang verfügen, DNS jedoch nicht funktionsfähig ist oder Ihre Netzwerkeinstellungen ansonsten durcheinander sind
0
Ajedi32

Verwenden Sie in Bash den Netzwerk-Wrapper über/dev/{ udp , tcp }/Host/port:

if echo -n >/dev/tcp/8.8.8.8/53; then
  echo 'Internet available.'
else
  echo 'Offline.'
fi
0
Luchostein