Comment tester une connexion Internet avec bash?

113

Comment tester une connexion Internet sans envoyer de requête ping à un site Web? Je veux dire, que se passe-t-il s'il y a une connexion mais que le site est en panne? Y a-t-il un contrôle pour une connexion avec le monde?

lauriys
la source
2
ping plusieurs sites différents?
1
mais je ne veux pas cingler des sites Web, il n'y a pas d'autre option?
lauriys
6
Je veux juste voir qu'il y a peut-être un autre moyen!
lauriys
2
Il n'y a pas de meilleur moyen que d'envoyer et de recevoir un seul paquet à un ensemble d'adresses que vous savez ne pas mettre hors ligne en même temps, une autre façon est de vérifier votre DNS actuel si vous ne voulez pas que votre application ping un plus public domaine.
Tamara Wijsman
14
Je veux savoir si quelqu'un écoute, sans faire de son!
Kaz

Réponses:

131

Sans ping

#!/bin/bash

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

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

-q : mode silence

--spider : n'obtenez pas, vérifiez simplement la disponibilité de la page

$?: code retour du shell

0 : code shell "Tout est OK"

Sans 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
la source
2
très agréable ... mais suppose bien sûr que la boîte a wget. les périphériques embarqués et ce ne sera probablement pas le cas. ;)
Eric Sebasta
5
Essayez ceci: echo -e "GET google.com HTTP / 1.0 \ n \ n" | nc google.com 80> / dev / null 2> & 1
user3439968
1
tcping serait également utile ici. (tcping www.yahoo.com 80) && echo "Site is up"
David Ramirez
L'instruction if / else utilisée ici avec l'explication est excellente. Je vous remercie !
Danijel-James W
1
@ user3439968 Vous devez ajouter un délai d'attente à ncpour vous assurer qu'il expire . quelque chose commenc google.com 80 -w 10
kaptan
93

Ping votre passerelle par défaut:

#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error
mateusza
la source
14
bonne technique, il peut être modifié pour être utilisé dans une fonction: function ping_gw() { ... && return 0 || return 1 }puis utilisé comme ceci:ping_gw || (echo "no network, bye" && exit 1)
memnoch_proxy
1
sur mac os cela ne fonctionne pas par copier-coller: "-bash: ip: commande non trouvée ping: option illégale - w"
Benedikt S. Vogler
1
Donne une fausse alarme s'il est exécuté à partir d'un invité de virtualisation alors que l'hôte n'est pas connecté.
Teresa e Junior
1
Me donne de faux négatifs sur les
Malcolm
1
Soyez prudent avec cela. Je viens de tester cela en faisant ifconfig down wlan0et j'ai toujours une passerelle par défaut et elle est pingable, même si je ne peux en fait pas atteindre le monde extérieur.
Bruno Bronosky
29

Super merci à l'utilisateur somedrew pour son message ici: https://bbs.archlinux.org/viewtopic.php?id=55485 le 20/09/2008 02:09:48

La recherche dans / sys / class / net devrait être à sens unique

Voici mon script pour tester une connexion réseau autre que la boucle de retour. J'utilise ce qui suit dans un autre script que j'ai pour tester périodiquement si mon site Web est accessible. Si ce n'est PAS accessible, une fenêtre contextuelle me signale un problème.

Le script ci-dessous m'empêche de recevoir des messages contextuels toutes les cinq minutes lorsque mon ordinateur portable n'est pas connecté au réseau.

#!/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

Remarque pour les nouveaux utilisateurs de bash: la dernière instruction «if» teste si NON [!] En ligne et se termine si c'est le cas. Voir man bash et recherchez «Les expressions peuvent être combinées» pour plus de détails.

PS Je pense que le ping n'est pas la meilleure chose à utiliser ici car il vise à tester une connexion à un hôte particulier PAS à tester s'il existe une connexion à un réseau de quelque sorte que ce soit.

PPS The Above fonctionne sur Ubuntu 12.04 Le / sys peut ne pas exister sur certaines autres distributions. Voir ci-dessous:

Les distributions Linux modernes incluent un répertoire / sys en tant que système de fichiers virtuel (sysfs, comparable à / proc, qui est un procfs), qui stocke et permet la modification des périphériques connectés au système, alors que de nombreux systèmes d'exploitation traditionnels de type UNIX et Unix utilisent / sys comme lien symbolique vers l'arborescence des sources du noyau. [citation nécessaire]

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

Jesse
la source
1
Attention maintenant! " cat /sys/class/net/wwan0/carrierNe fonctionne pas sur ubuntu 14.04 LTS.
dotnetCarpenter
1
Vous voudrez peut-être mettre 2>/dev/nullaprès cat /sys/class/net/$interface/carrierpour ne pas avoir de sortie d'erreur au cas où le réseau est désactivé.
jarno
25

Cela fonctionne à la fois sur MacOSX et Linux:

#!/bin/bash

ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline
Legel
la source
Sauf pour osx ( ping: invalid option -- w)
avishayp
fping google.comou tout simplement fping 8.8.8.8faire la magie avec un bonus vous obtenez le code de statut sans avoir besoin de le tester (" google.com is alive") ...
Roger
9

Dans Bash, en utilisant son wrapper réseau via / dev / { udp , tcp } / host / port :

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

( :est le Bash no-op, car vous voulez juste tester la connexion, mais pas le traitement.)

Luchostein
la source
7

J'ai écrit des scripts avant cela, utilisez simplement telnet pour vous connecter au port 80, puis transmettez le texte:

HTTP/1.0 GET /index.html

suivi de deux séquences CR / LF.

À condition de récupérer une forme de réponse HTTP, vous pouvez généralement supposer que le site fonctionne.

paxdiablo
la source
3
Pourquoi réinventer la roue? curl et wget le font parfaitement.
Adam Rosenfield
6
Parce que wget et curl ne sont pas toujours disponibles (par exemple, les restrictions dans les environnements d'entreprise). Telnet fait partie intégrante de tous les UNIX depuis le temps t = 0.
paxdiablo
Ouais, le telnetting est un moyen assez standard de tester les connexions depuis un certain temps.
PTBNL
2
Bon point, bien que wget soit assez courant. Une autre option est netcat (nc), bien que dans ce cas il n'y ait aucune amélioration par rapport à telnet.
Adam Rosenfield
7

La réponse principale ne tient pas compte du fait que vous pouvez avoir une connexion parfaitement stable à votre passerelle par défaut, mais cela ne signifie pas automatiquement que vous pouvez réellement atteindre quelque chose sur Internet. Le PO demande comment il / elle peut tester une connexion avec le monde. Je suggère donc de modifier la réponse principale en changeant l'adresse IP de la passerelle en une adresse IP connue (xyzw) qui se trouve en dehors de votre LAN.

La réponse deviendrait donc:

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

Suppression également des backticks défavorables pour la substitution de commande [1] .

Si vous voulez juste vous assurer que vous êtes connecté au monde avant d'exécuter du code, vous pouvez également utiliser:

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

assurez-vous que votre réseau autorise le trafic TCP entrant et sortant, vous pourrez alors récupérer votre adresse IP publique avec la commande suivante

curl ifconfig.co
WaiKit Kung
la source
5

Exécutez la commande suivante pour vérifier si un site Web est actif et quel message d'état le serveur Web affiche:

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

Le code d'état «200 OK» signifie que la demande a réussi et qu'un site Web est accessible.

Chaminda Bandara
la source
2
Une meilleure mise en œuvre pourrait êtrecurl -Is http://www.google.com | head -1 | grep 200; if [[ $? -eq 0 ]]; then; echo "Online"; else; echo "Offline"; fi;
Luca Galasso
4

Si votre serveur de noms local est en panne,

ping 4.2.2.1

est une adresse IP toujours active et facile à retenir (c'est en fait un serveur de noms, même).

éphémère
la source
5
ping 8.8.8.8 (Google NS)
user3439968
4

le réponse la plus votée ne fonctionne pas pour MacOS, donc pour ceux sur Mac, j'ai testé avec succès ceci:

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

testé sur MacOS High Sierra 10.12.6

Francisc0
la source
2
Modifiez la routecommande en route -n get default 2> /dev/null | grep gatewaypour éviter d'écrire une erreur dans stderr en mode hors connexion.
devstuff
4

Ce script bash vérifie en permanence Internet et émet un bip lorsque Internet est disponible.

#!/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
la source
3

chemin le plus court: fping 4.2.2.1 => "4.2.2.1 est vivant"

je préfère cela car c'est une sortie plus rapide et moins verbeuse que ping , l'inconvénient est que vous devrez l'installer.

vous pouvez utiliser n'importe quel DNS public plutôt qu'un site Web spécifique.

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

-q renvoie un code de sortie, donc je montre juste un exemple d'exécution de quelque chose que vous êtes en ligne.

à installer sur mac: brew install fping; sur ubuntu:sudo apt-get install fping

Alex Moore-Niemi
la source
2

Ping a été conçu pour faire exactement ce que vous cherchez à faire. Cependant, si le site bloque l'écho ICMP, vous pouvez toujours faire le telnet sur le port 80 d'un site, wget ou curl.

Nikudesu
la source
2

Vérifier la page d'index de Google est une autre façon de le faire:

#!/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
la source
2

De la même manière que la réponse de @ Jesse , cette option pourrait être beaucoup plus rapide que n'importe quelle solution utilisant pinget peut-être légèrement plus efficace que la réponse de @ Jesse .

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

Explication:

Cette commande utilise findavec -execpour exécuter la commande sur tous les fichiers non nommés *lo*dans/sys/class/net/ . Il doit s'agir de liens vers des répertoires contenant des informations sur les interfaces réseau disponibles sur votre machine.

La commande en cours d' shexécution est une commande qui vérifie le contenu du fichier carrierdans ces répertoires. La valeur de $interface/carriera 3 significations - Citations :

Il semble qu'il y ait trois états:

  • ./carrier non lisible (par exemple lorsque l'interface est désactivée dans Network Manager).
  • ./carrier contient "1" (lorsque l'interface est activée et qu'elle est connectée à un réseau WiFi)
  • ./carrier contient "0" (lorsque l'interface est activée et qu'elle n'est pas connectée à un réseau WiFi)

La première option n'est pas prise en compte dans la réponse de @ Jesse . La shcommande rayée est:

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

catest utilisé pour vérifier le contenu de carrieret rediriger toute la sortie vers la sortie standard même en cas d'échec car le fichier n'est pas lisible. Sigrep -q trouve "1"parmi ces fichiers, cela signifie qu'il y a au moins 1 interface connectée. Le code de sortie de grep -qsera le code de sortie final.

Usage

Par exemple, en utilisant l'état de sortie de cette commande, vous pouvez l'utiliser pour démarrer un gnubiff dans votre ~/.xprofileuniquement si vous avez une connexion Internet.

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 &

Référence

Doron Behar
la source
1

Pong ne signifie pas que le service Web sur le serveur est en cours d'exécution; cela signifie simplement que le serveur répond à l'écho ICMP. Je recommanderais d'utiliser curl et de vérifier sa valeur de retour.

Tomoe
la source
0

Si votre objectif est de vérifier réellement l' accès à Internet , la plupart des réponses existantes à cette question sont erronées. Quelques points à prendre en compte:

  1. Il est possible que votre ordinateur soit connecté à un réseau sans que ce réseau n'ait accès à Internet
  2. Il est possible qu'un serveur soit en panne sans que tout Internet ne soit inaccessible
  3. Il est possible pour un portail captif de renvoyer une réponse HTTP pour une URL arbitraire même si vous n'avez pas accès à Internet

Dans cet esprit, je pense que la meilleure stratégie consiste à contacter plusieurs sites via une connexion HTTPS et à renvoyer true si l'un de ces sites répond.

Par exemple:

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
}

Usage:

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

Quelques notes sur cette approche:

  1. Il est robuste contre tous les faux positifs et négatifs que j'ai décrits ci-dessus
  2. Les demandes se produisent toutes en parallèle pour maximiser la vitesse
  3. Il retournera false si vous avez techniquement un accès Internet mais que le DNS n'est pas fonctionnel ou que vos paramètres réseau sont autrement perturbés, ce qui, à mon avis, est une chose raisonnable à faire dans la plupart des cas.
Ajedi32
la source
Le code retour de curl n'est pas testé. Sur mon système, si le réseau n'est pas disponible, curl donne rc = 6 (échec de la résolution DNS) mais ce code signale toujours "Connecté à Internet".
ceperman
@ceperman Le code de retour de curl est testé sur la ligne où il est indiqué if wait $pid;. Je ne sais pas pourquoi cela ne fonctionne pas sur votre système. Êtes-vous sûr d'utiliser bash?
Ajedi32
@ceperman Une autre possibilité; peut - être l' une des URL dans la liste en haut fait - t succès de retour pour vous, même si les autres ne parviennent pas la résolution de noms?
Ajedi32
2
Mon bash est assez basique donc j'ai lu et je waitcomprends maintenant que le code de retour est en effet en cours de test. J'ai recopié votre code et aujourd'hui ça marche - oups! J'ai dû foirer quelque chose la dernière fois même si je ne comprends pas quoi ni comment. Néanmoins, mea culpa. Toutes mes excuses.
ceperman
-1

C'est nettement plus rapide que n'importe quelle solution publiée ici, et peut être utilisé pour tester un hôte spécifique .

L'astuce consiste à résoudre l'IP en utilisant un solveur DNS moins occupé que celui utilisé par 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
la source
2
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change. - De l'avis
David Buck
Cela ne s'applique pas à cette situation particulière.
Alberto Salvia Novella le