Bash ile İnternet bağlantısı nasıl test edilir?


113

Bazı web sitelerine ping atmadan bir internet bağlantısı nasıl test edilebilir? Demek istediğim, ya bir bağlantı varsa ama site kapalıysa? Dünya ile bir bağlantı kontrolü var mı?


2
birkaç farklı siteye ping atmak mı?

1
ama web sitelerine ping atmak istemiyorum, başka seçenek yok mu?
lauriys

6
Belki başka bir yol olduğunu görmek istiyorum!
lauriys

2
Tek seferde çevrimdışı kalmamayı bildiğiniz bir dizi adrese tek bir paket gönderip almaktan daha iyi bir yol yoktur, başka bir yol da uygulamanızın daha genel bir ping atmasını istemiyorsanız mevcut set DNS'nizi kontrol etmektir. alan adı.
Tamara Wijsman

14
Hiç ses çıkarmadan dinleyen var mı bilmek istiyorum!
Kaz

Yanıtlar:


131

Ping olmadan

#!/bin/bash

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

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

-q : Sessiz mod

--spider : alma, sadece sayfa kullanılabilirliğini kontrol et

, $? : kabuk dönüş kodu

0 : shell "Hepsi Tamam" kodu

Wget olmadan

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

2
çok güzel ... ama elbette kutunun wget'i olduğunu varsayar. gömülü cihazlar ve muhtemelen olmayacak. ;)
Eric Sebasta

5
Şunu deneyin: echo -e " google.com HTTP / 1.0'ı AL \ n \ n" | nc google.com 80> / dev / null 2> & 1
user3439968

1
tcping de burada yardımcı olabilir. (tcping www.yahoo.com 80) && echo "Site hazır"
David Ramirez

İf / else ifadesini burada kullanın wirh açıklaması harika. Teşekkür ederim !
Danijel-James W

1
@ user3439968 Zaman aşımına uğradığından ncemin olmak için zaman aşımı eklemeniz gerekir . gibi bir şeync google.com 80 -w 10
kaptan

93

Varsayılan ağ geçidinize ping atın:

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

14
iyi teknik, bir işlevde kullanılmak üzere değiştirilebilir: function ping_gw() { ... && return 0 || return 1 }ve sonra şu şekilde kullanılabilir:ping_gw || (echo "no network, bye" && exit 1)
memnoch_proxy

1
mac işletim sisteminde bu, kopyala-yapıştır yoluyla çalışmaz: "-bash: ip: komut bulunamadı ping: geçersiz seçenek - w"
Benedikt S. Vogler

1
Ana bilgisayar bağlı değilken bir sanallaştırma misafirinden çalıştırılırsa yanlış alarm verir.
Teresa e Junior

1
Temel işletim sisteminde bana yanlış negatifler veriyor (0.4.1, Acer Aspire E 15)
Malcolm

1
Buna dikkat et. Bunu sadece yaparak test ifconfig down wlan0ettim ve hala varsayılan bir ağ geçidim var ve aslında dış dünyaya ulaşamasam da pinglenebilir.
Bruno Bronosky

29

Super Somedrew kullanıcısına buradaki gönderileri için teşekkürler : https://bbs.archlinux.org/viewtopic.php?id=55485 , 2008-09-20 02:09:48

/ Sys / class / net'e bakmak tek yönlü olmalıdır

Geri döngü dışında bir ağ bağlantısını test etmek için komut dosyam burada. Aşağıdakini, web sitemin erişilebilir olup olmadığını düzenli olarak test etmek için sahip olduğum başka bir komut dosyasında kullanıyorum. Erişilmezse, bir açılır pencere beni bir soruna karşı uyarır.

Aşağıdaki komut dosyası, dizüstü bilgisayarım ağa bağlı olmadığında her beş dakikada bir açılır mesaj almamı engelliyor.

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

Bash'e yeni başlayanlar için not: Son 'if' ifadesi çevrimiçi DEĞİL [!] İse test eder ve durum buysa çıkar. Daha fazla ayrıntı için man bash bakın ve "İfadeler birleştirilebilir" araması yapın.

Not: Ping'in burada kullanılacak en iyi şey olmadığını düşünüyorum çünkü belirli bir ana bilgisayara olan bağlantıyı test etmeyi hedefliyor , herhangi bir türden bir ağa bağlantı olup olmadığını test etmeyin .

PPS The Above, Ubuntu 12.04'te çalışır. / Sys başka dağıtımlarda bulunmayabilir. Aşağıya bakınız:

Modern Linux dağıtımları, sisteme bağlı aygıtları depolayan ve değiştirmeye izin veren sanal bir dosya sistemi (sysfs, / proc ile karşılaştırılabilir) olarak / sys dizinini içerirken, birçok geleneksel UNIX ve Unix benzeri işletim sistemi / sys, çekirdek kaynak ağacına sembolik bir bağlantı olarak. [kaynak belirtilmeli]

Wikipedia'dan https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard


1
Şimdi dikkatli olun! " cat /sys/class/net/wwan0/carrier
Ubuntu 14.04 LTS'de çalışmıyor

1
Ağ bağlantısının devre dışı bırakılması durumunda hata çıktısı almamak için 2>/dev/nullsonrasına koymak isteyebilirsiniz cat /sys/class/net/$interface/carrier.
jarno

25

Bu hem MacOSX hem de Linux'ta çalışır:

#!/bin/bash

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

ping: invalid option -- w
Osx

fping google.comya da sadece fping 8.8.8.8sihri bir bonusla yapar, test etmeye gerek kalmadan durum kodunu alırsınız (" google.com is alive") ...
Roger

9

Bash'de, / dev / { udp , tcp } / host / port aracılığıyla ağ sarmalayıcısını kullanarak :

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

( :Bash işlemsizdir, çünkü yalnızca bağlantıyı test etmek istersiniz, ancak işlem yapmazsınız.)


7

Daha önce komut dosyaları yazdım, bundan önce 80 numaralı bağlantı noktasına bağlanmak için telnet kullanın, ardından metni iletin:

HTTP/1.0 GET /index.html

ardından iki CR / LF dizisi.

Bir tür HTTP yanıtını geri alırsanız, genellikle sitenin çalıştığını varsayabilirsiniz.


3
Neden tekerleği yeniden icat etmelisiniz? curl ve wget bunu mükemmel bir şekilde yapıyor.
Adam Rosenfield

6
Çünkü wget ve curl her zaman mevcut değildir (örneğin, kurumsal ortamlardaki kısıtlamalar). Telnet, t = 0'dan beri her UNIX'in standart bir parçası olmuştur.
paxdiablo

Evet, telnet, bir süredir bağlantıları test etmenin oldukça standart bir yolu olmuştur.
PTBNL

2
İyi bir nokta, wget oldukça yaygın olmasına rağmen. Diğer bir seçenek netcat (nc) 'dir, ancak bu durumda telnet üzerinde herhangi bir gelişme olmaz.
Adam Rosenfield

7

En iyi cevap, varsayılan ağ geçidinize mükemmel bir şekilde sabit bir bağlantıya sahip olabileceğiniz gerçeğini gözden kaçırıyor, ancak bu otomatik olarak internetteki bir şeye gerçekten erişebileceğiniz anlamına gelmiyor. OP, dünya ile bir bağı nasıl test edebileceğini sorar. Bu nedenle, ağ geçidi IP'sini LAN'ınız dışındaki bilinen bir IP'ye (xyzw) değiştirerek en iyi yanıtı değiştirmenizi öneririm.

Böylece cevap şu olur:

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

Ayrıca, komut ikamesi için istenmeyen geri işaretlerinin kaldırılması [1] .

Bir kodu çalıştırmadan önce dünyaya bağlı olduğunuzdan emin olmak istiyorsanız, şunları da kullanabilirsiniz:

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

6

ağınızın TCP trafiğine girip çıkmasına izin verdiğinden emin olun, ardından aşağıdaki komutla halka açık IP'nizi geri alabilirsiniz.

curl ifconfig.co

5

Bir web sitesinin çalışıp çalışmadığını ve web sunucusunun hangi durum mesajını gösterdiğini kontrol etmek için aşağıdaki komutu yürütün:

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

Durum kodu '200 Tamam', isteğin başarılı olduğu ve bir web sitesine erişilebilir olduğu anlamına gelir.


2
Daha iyi bir uygulama olabilircurl -Is http://www.google.com | head -1 | grep 200; if [[ $? -eq 0 ]]; then; echo "Online"; else; echo "Offline"; fi;
Luca Galasso

4

Yerel ad sunucunuz çalışmıyorsa,

ping 4.2.2.1

hatırlanması kolay, her zaman açık bir IP'dir (aslında bir ad sunucusudur).


5
ping 8.8.8.8 (Google NS)
user3439968

4

En çok oylanan cevap MacOS için çalışmaz, bu yüzden bir Mac kullananlar için bunu başarıyla test ettim:

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

MacOS High Sierra 10.12.6'da test edildi


2
Çevrimdışıyken stderr'e hata yazmamak için routekomutu olarak değiştirin route -n get default 2> /dev/null | grep gateway.
devstuff

4

Bu bash betiği, İnternet'i sürekli olarak kontrol eder ve İnternet mevcut olduğunda bir bip sesi çıkarır.

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

3

en kısa yol: fping 4.2.2.1 => "4.2.2.1 yaşıyor"

daha hızlı ve daha az ayrıntılı çıktı olduğu için bunu tercih ederim ping , dezavantajı, yüklemeniz gerekecek olmasıdır.

belirli bir web sitesi yerine herhangi bir genel dns kullanabilirsiniz .

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

-q bir çıkış kodu döndürür, bu yüzden çevrimiçi olduğunuz bir şeyi çalıştırmanın bir örneğini gösteriyorum.

mac'a kurmak için brew install fping:; ubuntu'da:sudo apt-get install fping


2

Ping, tam olarak yapmak istediğiniz şeyi yapmak için tasarlandı. Bununla birlikte, site ICMP yankısını engellerse, telnet'i her zaman bir sitenin 80 numaralı bağlantı noktasına, wget veya curl'ye yapabilirsiniz.


2

Google'ın dizin sayfasını kontrol etmek, bunu yapmanın başka bir yoludur:

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

2

Benzer için Jesse'nin cevap @ bu seçenek kullanılarak herhangi bir çözümün çok daha hızlı olabilir pingve daha belki biraz daha verimli Jesse'nin cevap @ .

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

explenation:

Bu komut, findiçinde -execadlandırılmayan tüm dosyalarda komut çalıştırmak için with kullanır *lo*./sys/class/net/ . Bunlar, makinenizdeki mevcut ağ arayüzleri hakkında bilgi içeren dizinlere bağlantılar olmalıdır.

Çalıştırılan shkomut, carrierbu dizinlerdeki dosyanın içeriğini kontrol eden bir komuttur . Değerinin $interface/carrier3 anlamı vardır - Alıntı :

Görünüşe göre üç durum var:

  • ./carrier okunamaz (örneğin arabirim Ağ Yöneticisi'nde devre dışı bırakıldığında).
  • ./carrier "1" içerir (arayüz etkinleştirildiğinde ve bir WiFi ağına bağlandığında)
  • ./carrier "0" içerir (arayüz etkinleştirildiğinde ve bir WiFi ağına bağlı olmadığında)

@ Jesse'nin cevabında ilk seçenek dikkate alınmaz . shDışarı çizgili komut şöyledir:

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

catcarrierdosya okunabilir olmadığından başarısız olsa bile tüm çıktıların içeriğini kontrol etmek ve standart çıktıya yeniden yönlendirmek için kullanılır . Bu dosyalar arasında bulunursa grep -q, "1"bağlı en az 1 arayüz olduğu anlamına gelir. Çıkış kodu grep -q, son çıkış kodu olacaktır.

kullanım

Örneğin, bu komutun çıkış durumunu kullanarak , yalnızca internet bağlantınız varsa , bir gnubiff başlatmak için kullanabilirsiniz ~/.xprofile.

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 &

Referans


1

Pong, sunucudaki web hizmetinin çalıştığı anlamına gelmez; bu yalnızca sunucunun ICMP yankısına yanıt verdiği anlamına gelir. Curl kullanmanızı ve dönüş değerini kontrol etmenizi öneririm.


0

Amacınız İnternet erişimini gerçekten kontrol etmekse, bu soruya verilen mevcut cevapların çoğu kusurludur. Bilmeniz gereken birkaç şey:

  1. Bilgisayarınızın, o ağın internet erişimi olmadan bir ağa bağlanması mümkündür
  2. İnternetin tamamı erişilemez olmadan bir sunucunun kapalı olması mümkündür
  3. Doğrulama amacıyla yönlendirme yapan bir portalın, İnternet erişiminiz olmasa bile rastgele bir URL için bir HTTP yanıtı döndürmesi mümkündür

Bunu göz önünde bulundurarak, en iyi stratejinin bir HTTPS bağlantısı üzerinden birkaç siteyle iletişim kurmak ve bu sitelerden herhangi biri yanıt verirse doğruyu döndürmek olduğuna inanıyorum .

Örneğin:

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
}

Kullanımı:

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

Bu yaklaşımla ilgili bazı notlar:

  1. Yukarıda özetlediğim tüm yanlış pozitif ve negatiflere karşı sağlamdır
  2. Hızı en üst düzeye çıkarmak için isteklerin tümü paralel olarak gerçekleşir
  3. Teknik olarak internet erişiminiz varsa ancak DNS çalışmıyorsa veya ağ ayarlarınız başka türlü bozulmuşsa yanlış döndürür , ki bu çoğu durumda yapılması makul bir şeydir

Curl'den dönüş kodu test edilmiyor. Sistemimde, ağ mevcut değilse curl, rc = 6 (başarısız DNS çözümlemesi) verir, ancak bu kod yine de "İnternete bağlı" olarak bildirir.
ceperman

@ceperman Curl için dönüş kodu yazdığı satırda test edilir if wait $pid;. Sisteminizde neden çalışmadığı hakkında hiçbir fikrim yok. Bash kullandığınızdan emin misiniz?
Ajedi32

@ceperman Başka bir olasılık; belki üstündeki listedeki URL'lerin biri aslında yok diğerleri ad çözümlemesi başarısız olsa bile, sizin için dönüş başarı?
Ajedi32

2
Benim bash'ım oldukça basit, bu yüzden okudum waitve şimdi dönüş kodunun gerçekten test edildiğini anlıyorum. Kodunuzu yeniden kopyaladım ve bugün işe yarıyor - oops! Ne veya nasıl olduğunu anlayamasam da geçen sefer bir şeyleri mahvetmiş olmalıyım. Yine de, mea culpa. Özür.
ceperman


-1

Bu, burada yayınlanan herhangi bir çözümden çok daha hızlıdır ve belirli bir ana bilgisayarı test etmek için kullanılabilir .

Hile daha az meşgul kullanarak IP çözme DNS çözücüsü tarafından istihdam olandan 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
}

2
Bu bağlantı soruyu cevaplayabilirken, cevabın temel kısımlarını buraya eklemek ve referans için bağlantıyı sağlamak daha iyidir. Bağlantılı sayfa değişirse, yalnızca bağlantı yanıtları geçersiz hale gelebilir. - Şu kaynaktan
David Buck

Bu özel durum için geçerli değildir.
Alberto Salvia Novella
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.