web-dev-qa-db-fra.com

Comment tester une connexion Internet avec bash?

Comment tester une connexion Internet sans envoyer de ping sur un site Web? Existe-t-il un chèque pour une connexion avec le monde?

83
lauriys

Sans ping

#!/bin/bash

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

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

-q : Mode silence

--spider : ne pas obtenir, juste vérifier la disponibilité de la page

$? : Code retour 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
97
user3439968

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
87
mateusza

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

Regarder 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 le texte ci-dessous dans un autre script que j'ai pour tester régulièrement si mon site Web est accessible. Si ce n'est PAS accessible, une fenêtre contextuelle m'avertit d'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

Note pour les débutants en bash: La dernière déclaration 'if' teste si NOT [!] En ligne et se ferme si tel 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.

(P.P.S. The Above fonctionne sur Ubuntu 12.04. Le/sys peut ne pas exister sur d'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, similaires aux systèmes UNIX et Unix, utilisent/sys en tant que lien symbolique vers l’arbre source du noyau. [citation requise]

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

24
Jesse

Cela fonctionne à la fois sur MacOSX et Linux:

#!/bin/bash

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

J'ai déjà écrit des scripts qui utilisent simplement telnet pour se connecter au port 80, puis transmettent le texte:

HTTP/1.0 GET /index.html

suivi de deux séquences CR/LF.

Si vous recevez une réponse HTTP, vous pouvez généralement supposer que le site fonctionne.

8
paxdiablo

La réponse la plus pertinente omet le 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 remplaçant l'adresse IP de la passerelle par une adresse IP connue (x.y.z.w) située en dehors de votre réseau local. 

Donc, la réponse deviendrait:

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

Suppression également des backticks défavorisés 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 aussi utiliser:

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

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 abouti et qu’un site Web est accessible.

4
Chaminda Bandara

Si votre serveur de noms local est en panne,

 ping 4.2.2.1 

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

4
ephemient

assurez-vous que votre réseau autorise l'entrée et la sortie du trafic TCP, vous pouvez alors récupérer votre adresse IP publique en utilisant la commande suivante

curl ifconfig.co
4
WaiKit Kung

Le réponse votée en haut ne fonctionne pas pour MacOS, donc pour ceux qui utilisent un mac, j'ai testé ceci avec succès:

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

3
Francisc0

De la même manière que @ réponse de Jesse , cette option pourrait être beaucoup plus rapide que toute solution utilisant ping et peut-être légèrement plus efficace que @ 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 find avec -exec pour 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 ordinateur.

La commande en cours d'exécution est une commande sh qui vérifie le contenu du fichier carrier dans ces répertoires. La valeur de $interface/carrier a 3 significations - Citant :

Il semble qu'il y ait trois états:

  • ./carrier illisible (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 commande sh rayée est:

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

cat est utilisé pour vérifier le contenu de carrier et rediriger toutes les sorties vers la sortie standard, même en cas d'échec car le fichier n'est pas lisible. Si grep -q trouve "1" parmi ces fichiers, cela signifie qu'au moins une interface est connectée. Le code de sortie de grep -q sera le code de sortie final.

Usage

Par exemple, en utilisant le statut de sortie de cette commande, vous pouvez l’utiliser pour démarrer un gnubiff dans votre ~/.xprofile uniquement si vous disposez d’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

2
Doron Behar

Ping a été conçu pour faire exactement ce que vous cherchez à faire. Toutefois, si le site bloque l’écho ICMP, vous pouvez toujours utiliser telnet sur le port 80 de certains sites, wget ou curl.

2
nikudesu

Ce script bash vérifie continuellement 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
2
Arjun G Perambra

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

je préfère ceci car il est plus rapide et moins verbeux que ping;.

vous pouvez utiliser un public dns 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, je montre donc 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

2
Alex Moore-Niemi

Consulter la page d'index de Google est un autre moyen 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
1
dm76

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 à ICMP echo . Je vous recommanderais d'utiliser curl et de vérifier sa valeur de retour.

1
tomoe

Si votre objectif est de vérifier Internet accès, bon nombre des réponses existantes à cette question sont erronées. Quelques points à connaître:

  1. Il est possible que votre ordinateur soit connecté à un réseau sans que ce réseau ait accès à Internet
  2. Il est possible qu'un serveur soit en panne sans que tout l'internet soit inaccessible
  3. Il est possible qu'un portail captif renvoie 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 arrivent toutes en parallèle pour maximiser la vitesse
  3. Il retournera false si techniquement j'ai un accès Internet mais le DNS n'est pas fonctionnel ou si vos paramètres réseau sont altérés, ce qui, à mon avis, est raisonnable dans la plupart des cas
0
Ajedi32

Dans Bash, utiliser son wrapper réseau via / 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