Come si può testare una connessione Internet senza eseguire il ping di un sito Web? Voglio dire, cosa succede se c'è una connessione ma il sito è inattivo? C'è un controllo per una connessione con il mondo?
Come si può testare una connessione Internet senza eseguire il ping di un sito Web? Voglio dire, cosa succede se c'è una connessione ma il sito è inattivo? C'è un controllo per una connessione con il mondo?
Risposte:
Senza ping
#!/bin/bash
wget -q --spider http://google.com
if [ $? -eq 0 ]; then
echo "Online"
else
echo "Offline"
fi
-q : modalità silenziosa
--spider : non ottenere, controlla solo la disponibilità della pagina
$? : codice di ritorno della shell
0 : codice shell "All OK"
Senza 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
nc
per assicurarsi che scada . qualcosa comenc google.com 80 -w 10
Eseguire il ping del gateway predefinito:
#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error
function ping_gw() { ... && return 0 || return 1 }
e quindi usata così:ping_gw || (echo "no network, bye" && exit 1)
ifconfig down wlan0
e ho ancora un gateway predefinito ed è eseguibile il ping, anche se in realtà non posso raggiungere il mondo esterno.
Super Grazie all'utente somedrew per il suo post qui: https://bbs.archlinux.org/viewtopic.php?id=55485 su 2008-09-20 02:09:48
Cercare in / sys / class / net dovrebbe essere unidirezionale
Ecco il mio script per testare una connessione di rete diversa dal loopback. Uso quanto segue in un altro script che ho per testare periodicamente se il mio sito web è accessibile. Se NON è accessibile, una finestra popup mi avvisa di un problema.
Lo script seguente mi impedisce di ricevere messaggi popup ogni cinque minuti ogni volta che il mio laptop non è connesso alla rete.
#!/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
Nota per chi non conosce bash: l'istruzione finale "if" verifica se NON [!] Online ed esce se questo è il caso. Vedi man bash e cerca "Le espressioni possono essere combinate" per maggiori dettagli.
PS Penso che il ping non sia la cosa migliore da usare qui perché mira a testare una connessione a un particolare host NON testare se c'è una connessione a una rete di qualsiasi tipo.
PPS Il precedente funziona su Ubuntu 12.04 Il / sys potrebbe non esistere su alcune altre distribuzioni. Vedi sotto:
Le moderne distribuzioni Linux includono una directory / sys come file system virtuale (sysfs, paragonabile a / proc, che è un procfs), che memorizza e consente la modifica dei dispositivi collegati al sistema, mentre molti sistemi operativi tradizionali UNIX e simili a Unix utilizzano / sys come collegamento simbolico all'albero dei sorgenti del kernel. [citazione necessaria]
Da Wikipedia https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
cat /sys/class/net/wwan0/carrier
Non funziona su ubuntu 14.04 LTS.
2>/dev/null
dopo cat /sys/class/net/$interface/carrier
per non avere output di errore nel caso in cui la rete sia disabilitata.
Funziona sia su MacOSX che su Linux:
#!/bin/bash
ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline
ping: invalid option -- w
)
fping google.com
o semplicemente fping 8.8.8.8
fa la magia con un bonus, ottieni il codice di stato senza bisogno di testarlo (" google.com is alive
") ...
In Bash, utilizzando il suo wrapper di rete tramite / dev / { udp , tcp } / host / port :
if : >/dev/tcp/8.8.8.8/53; then
echo 'Internet available.'
else
echo 'Offline.'
fi
( :
è il Bash no-op, perché vuoi solo testare la connessione, ma non l'elaborazione.)
Ho già scritto script prima di utilizzare semplicemente telnet per connettersi alla porta 80, quindi trasmettere il testo:
HTTP/1.0 GET /index.html
seguito da due sequenze CR / LF.
A condizione che tu riceva una qualche forma di risposta HTTP, puoi generalmente presumere che il sito funzioni.
La risposta migliore manca del fatto che puoi avere una connessione perfettamente stabile al tuo gateway predefinito, ma ciò non significa automaticamente che puoi effettivamente raggiungere qualcosa su Internet. L'OP chiede come può testare una connessione con il mondo. Quindi suggerisco di modificare la risposta principale cambiando l'IP del gateway in un IP noto (xyzw) che si trova al di fuori della tua LAN.
Quindi la risposta sarebbe:
ping -q -w 1 -c 1 x.y.z.w > /dev/null && echo ok || echo error
Rimuovendo anche i backtick non consigliati per la sostituzione dei comandi [1] .
Se vuoi solo assicurarti di essere connesso al mondo prima di eseguire del codice puoi anche usare:
if ping -q -w 1 -c 1 x.y.z.w > /dev/null; then
# more code
fi
assicurati che la tua rete consenta il traffico TCP in entrata e in uscita, quindi potresti recuperare il tuo IP pubblico con il seguente comando
curl ifconfig.co
Eseguire il comando seguente per verificare se un sito Web è attivo e quale messaggio di stato sta mostrando il server Web:
$ curl -Is http://www.google.com |
head -1 HTTP/1.1 200 OK
Il codice di stato "200 OK" significa che la richiesta è andata a buon fine e che un sito web è raggiungibile.
curl -Is http://www.google.com | head -1 | grep 200; if [[ $? -eq 0 ]]; then; echo "Online"; else; echo "Offline"; fi;
Se il tuo server dei nomi locale è inattivo,
ping 4.2.2.1
è un IP sempre attivo facile da ricordare (in realtà è anche un server dei nomi).
La risposta più votata non funziona per MacOS, quindi per quelli su un Mac, ho testato con successo questo:
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
testato su MacOS High Sierra 10.12.6
route
comando in route -n get default 2> /dev/null | grep gateway
per evitare di scrivere un errore su stderr quando offline.
Questo script bash controlla continuamente la presenza di Internet ed emette un segnale acustico quando Internet è disponibile.
#!/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
modo più breve: fping 4.2.2.1
=> "4.2.2.1 è vivo"
lo preferisco in quanto è un output più veloce e meno dettagliato di ping
, lo svantaggio è che dovrai installarlo.
è possibile utilizzare qualsiasi DNS pubblico anziché un sito Web specifico.
fping -q google.com && echo "do something because you're connected!"
-q
restituisce un codice di uscita, quindi sto solo mostrando un esempio di esecuzione di qualcosa che sei online.
da installare su Mac: brew install fping
; su ubuntu:sudo apt-get install fping
Analogamente alla risposta di @ Jesse , questa opzione potrebbe essere molto più veloce di qualsiasi soluzione che utilizza ping
e forse leggermente più efficiente della risposta di @ Jesse .
find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1' {} \; | grep -q '1'
Questo comando utilizza find
con -exec
per eseguire il comando su tutti i file non nominati *lo*
in/sys/class/net/
. Questi dovrebbero essere collegamenti a directory contenenti informazioni sulle interfacce di rete disponibili sulla macchina.
Il comando in esecuzione è un sh
comando che controlla il contenuto del file carrier
in quelle directory. Il valore di $interface/carrier
ha 3 significati - Citando :
Sembra che ci siano tre stati:
- ./carrier non leggibile (ad esempio quando l'interfaccia è disabilitata in Network Manager).
- ./carrier contiene "1" (quando l'interfaccia è attivata ed è collegata a una rete WiFi)
- ./carrier contiene "0" (quando l'interfaccia è attivata e non è collegata a una rete WiFi)
La prima opzione non è stata presa in considerazione nella risposta di @ Jesse . Il sh
comando con striping è:
# Note: $0 == $interface
cat "$0"/carrier 2>&1
cat
viene utilizzato per controllare il contenuto carrier
e reindirizzare tutto l'output allo standard output anche quando fallisce perché il file non è leggibile. Se grep -q
trova "1"
tra quei file significa che c'è almeno 1 interfaccia collegata. Il codice di uscita di grep -q
sarà il codice di uscita finale.
Ad esempio, usando lo stato di uscita di questo comando, puoi usarlo per avviare uno gnubiff nel tuo ~/.xprofile
solo se hai una connessione 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 &
Se il tuo obiettivo è verificare effettivamente l' accesso a Internet , molte delle risposte esistenti a questa domanda sono errate. Alcune cose di cui dovresti essere a conoscenza:
Con questo in mente, credo che la migliore strategia sia contattare diversi siti tramite una connessione HTTPS e restituire true se uno di questi siti risponde.
Per esempio:
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
}
Uso:
if connected_to_internet; then
echo "Connected to internet"
else
echo "No internet connection"
fi
Alcune note su questo approccio:
if wait $pid;
. Non ho idea del motivo per cui non funziona sul tuo sistema. Sei sicuro di usare bash?
wait
e ora capisco che il codice di ritorno è effettivamente in fase di test. Ho ricopiato il tuo codice e oggi funziona - whoops! Devo aver incasinato qualcosa l'ultima volta anche se non riesco a capire cosa o come. Tuttavia, mea culpa. Scuse.
Questo è notevolmente più veloce di qualsiasi soluzione pubblicata qui e può essere utilizzato anche per testare un host specifico .
Il trucco sta nel risolvere l'IP utilizzando un risolutore DNS meno occupato di quello impiegato da 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
}