Bagaimana cara menguji koneksi internet dengan bash?


113

Bagaimana koneksi internet dapat diuji tanpa melakukan ping ke beberapa situs web? Maksud saya, bagaimana jika ada koneksi tetapi situsnya sedang down? Apakah ada pemeriksaan untuk koneksi dengan dunia?


2
ping beberapa situs berbeda?

1
tetapi saya tidak ingin melakukan ping ke situs web, tidak ada pilihan lain?
lauriys

6
Saya hanya ingin melihat bahwa mungkin ada cara lain!
lauriys

2
Tidak ada cara yang lebih baik daripada mengirim dan menerima satu paket ke satu set alamat yang Anda tahu untuk tidak offline sekaligus, cara lain adalah dengan memeriksa set DNS Anda saat ini jika Anda tidak ingin aplikasi Anda melakukan ping ke lebih publik domain.
Tamara Wijsman

14
Saya ingin tahu apakah ada yang mendengarkan, tanpa bersuara!
Kaz

Jawaban:


131

Tanpa ping

#!/bin/bash

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

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

-q : Mode diam

--spider : jangan sampai, cukup periksa ketersediaan halaman

$? : kode pengembalian shell

0 : kode shell "Semua OK"

Tanpa 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

2
sangat bagus ... tapi tentu saja menganggap kotak itu telah rusak. perangkat tertanam dan yang lainnya mungkin tidak. ;)
Eric Sebasta

5
Coba ini: echo -e "DAPATKAN google.com HTTP / 1.0 \ n \ n" | nc google.com 80> / dev / null 2> & 1
user3439968

1
tcping juga akan membantu di sini. (tcping www.yahoo.com 80) && echo "Situs sudah habis"
David Ramirez

Pernyataan if / else yang digunakan di sini dengan penjelasan bagus. Terima kasih !
Danijel-James W

1
@ user3439968 Anda perlu menambahkan waktu tunggu untuk ncmemastikannya waktu habis. sesuatu sepertinc google.com 80 -w 10
kaptan

93

Ping gateway default Anda:

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

14
teknik yang baik, dapat dimodifikasi untuk digunakan dalam suatu fungsi: function ping_gw() { ... && return 0 || return 1 }dan kemudian digunakan seperti ini:ping_gw || (echo "no network, bye" && exit 1)
memnoch_proxy

1
pada mac os ini tidak bekerja melalui salin-tempel: "-bash: ip: perintah tidak ditemukan ping: opsi ilegal - w"
Benedikt S. Vogler

1
Memberikan alarm palsu jika dijalankan dari tamu virtualisasi saat tuan rumah tidak terhubung.
Teresa e Junior

1
Memberi saya negatif palsu pada OS dasar (0.4.1, Acer Aspire E 15)
Malcolm

1
Hati-hati dengan ini. Saya baru saja menguji ini dengan melakukan ifconfig down wlan0dan saya masih memiliki gateway default dan itu dapat di-ping, meskipun saya sebenarnya tidak dapat menjangkau dunia luar.
Bruno Bronosky

29

Super Terima kasih kepada pengguna somedrew untuk posting mereka di sini: https://bbs.archlinux.org/viewtopic.php?id=55485 pada 2008-09-20 02:09:48

Mencari di / sys / class / net harus menjadi salah satu cara

Berikut skrip saya untuk menguji koneksi jaringan selain loop belakang. Saya menggunakan di bawah ini dalam skrip lain yang saya miliki untuk menguji secara berkala apakah situs web saya dapat diakses. Jika TIDAK dapat diakses, jendela popup memberi tahu saya akan adanya masalah.

Skrip di bawah ini mencegah saya menerima pesan popup setiap lima menit setiap kali laptop saya tidak terhubung ke jaringan.

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

Catatan bagi mereka yang baru mengenal bash: Pernyataan 'jika' terakhir menguji jika TIDAK [!] Online dan keluar jika ini masalahnya. Lihat man bash dan cari "Ekspresi dapat digabungkan" untuk detail selengkapnya.

PS Saya merasa ping bukanlah hal terbaik untuk digunakan di sini karena bertujuan untuk menguji koneksi ke host tertentu BUKAN menguji apakah ada koneksi ke jaringan apa pun.

PPS Di atas berfungsi di Ubuntu 12.04 / sys mungkin tidak ada di beberapa distro lain. Lihat di bawah:

Distribusi Linux modern menyertakan direktori / sys sebagai sistem file virtual (sysfs, sebanding dengan / proc, yang merupakan procfs), yang menyimpan dan memungkinkan modifikasi perangkat yang terhubung ke sistem, sedangkan banyak sistem operasi UNIX tradisional dan mirip Unix menggunakan / sys sebagai tautan simbolis ke pohon sumber kernel. [butuh rujukan]

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


1
Hati-hati sekarang! " cat /sys/class/net/wwan0/carrierTidak berfungsi di ubuntu 14.04 LTS.
dotnetCarpenter

1
Anda mungkin ingin meletakkan 2>/dev/nullsetelah cat /sys/class/net/$interface/carriertidak memiliki output kesalahan jika jaringan dinonaktifkan.
jarno

25

Ini berfungsi di MacOSX dan Linux:

#!/bin/bash

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

Kecuali untuk osx ( ping: invalid option -- w)
avishayp

fping google.comatau hanya fping 8.8.8.8melakukan keajaiban dengan bonus Anda mendapatkan kode status tanpa perlu mengujinya (" google.com is alive") ...
Roger

9

Di Bash, menggunakan pembungkus jaringannya melalui / dev / { udp , tcp } / host / port :

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

( :adalah Bash no-op, karena Anda hanya ingin menguji koneksi, tetapi tidak memproses.)


7

Saya telah menulis skrip sebelumnya yang cukup menggunakan telnet untuk terhubung ke port 80, lalu mengirimkan teks:

HTTP/1.0 GET /index.html

diikuti oleh dua urutan CR / LF.

Asalkan Anda mendapatkan kembali beberapa bentuk respons HTTP, Anda biasanya dapat menganggap situs tersebut berfungsi.


3
Mengapa menemukan kembali roda? curl dan wget keduanya melakukan ini dengan sempurna.
Adam Rosenfield

6
Karena wget dan curl tidak selalu tersedia (misalnya, pembatasan di lingkungan perusahaan). Telnet telah menjadi bagian standar dari setiap UNIX sejak waktu t = 0.
paxdiablo

Ya, telnetting telah menjadi cara yang cukup standar untuk menguji koneksi cukup lama.
PTBNL

2
Poin bagus, meskipun wget cukup umum. Pilihan lainnya adalah netcat (nc), meskipun dalam hal ini tidak ada peningkatan apapun dari telnet.
Adam Rosenfield

7

Jawaban teratas melewatkan fakta bahwa Anda dapat memiliki koneksi yang sangat stabil ke gateway default Anda, tetapi itu tidak secara otomatis berarti Anda benar-benar dapat menjangkau sesuatu di internet. OP bertanya bagaimana dia bisa menguji koneksi dengan dunia. Jadi saya sarankan untuk mengubah jawaban teratas dengan mengubah IP gateway ke IP yang dikenal (xyzw) yang ada di luar LAN Anda.

Jadi jawabannya adalah:

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

Juga menghapus backticks yang tidak disukai untuk substitusi perintah [1] .

Jika Anda hanya ingin memastikan Anda terhubung ke dunia sebelum menjalankan beberapa kode, Anda juga dapat menggunakan:

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

6

pastikan jaringan Anda mengizinkan lalu lintas TCP masuk dan keluar, lalu Anda bisa mendapatkan kembali IP yang menghadap publik dengan perintah berikut

curl ifconfig.co

5

Jalankan perintah berikut untuk memeriksa apakah situs web sudah aktif, dan pesan status apa yang ditampilkan server web:

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

Kode status '200 OK' berarti permintaan berhasil dan situs web dapat dijangkau.


2
Implementasi yang lebih baik bisa jadicurl -Is http://www.google.com | head -1 | grep 200; if [[ $? -eq 0 ]]; then; echo "Online"; else; echo "Offline"; fi;
Luca Galasso

4

Jika server nama lokal Anda tidak aktif,

ping 4.2.2.1

adalah IP selalu up yang mudah diingat (bahkan sebenarnya server nama).


5
ping 8.8.8.8 (Google NS)
pengguna3439968

4

Jawaban pilihan teratas tidak berfungsi untuk MacOS, jadi bagi mereka yang menggunakan mac, saya berhasil menguji ini:

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

diuji pada MacOS High Sierra 10.12.6


2
Ubah routeperintah untuk route -n get default 2> /dev/null | grep gatewaymenghindari penulisan kesalahan ke stderr saat offline.
devstuff

4

Skrip bash ini terus menerus memeriksa Internet dan mengeluarkan bunyi bip saat Internet tersedia.

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

cara terpendek: fping 4.2.2.1=> "4.2.2.1 masih hidup"

Saya lebih suka ini karena lebih cepat dan output yang kurang bertele-tele daripada ping, downside adalah Anda harus menginstalnya.

Anda dapat menggunakan dns publik apa pun daripada situs web tertentu.

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

-q mengembalikan kode keluar, jadi saya hanya menunjukkan contoh menjalankan sesuatu yang Anda sedang online.

untuk menginstal di mac: brew install fping; di ubuntu:sudo apt-get install fping


2

Ping dirancang untuk melakukan apa yang ingin Anda lakukan. Namun, jika situs memblokir echo ICMP, maka Anda selalu dapat melakukan telnet ke port 80 dari beberapa situs, wget, atau curl.


2

Memeriksa halaman indeks Google adalah cara lain untuk melakukannya:

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

Mirip dengan jawaban @ Jesse , opsi ini mungkin jauh lebih cepat daripada solusi apa pun yang digunakan pingdan mungkin sedikit lebih efisien daripada jawaban @ Jesse .

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

Penjelasan:

Perintah ini menggunakan finddengan -execuntuk menjalankan perintah pada semua file yang tidak dinamai *lo*dalam /sys/class/net/. Ini harus berupa tautan ke direktori yang berisi informasi tentang antarmuka jaringan yang tersedia di mesin Anda.

Perintah yang sedang dijalankan adalah shperintah yang memeriksa konten file carrierdi direktori tersebut. Nilai $interface/carriermemiliki 3 arti - Mengutip :

Tampaknya ada tiga kondisi:

  • ./carrier tidak dapat dibaca (misalnya ketika antarmuka dinonaktifkan di Manajer Jaringan).
  • ./carrier berisi "1" (ketika antarmuka diaktifkan dan terhubung ke jaringan WiFi)
  • ./carrier mengandung "0" (ketika antarmuka diaktifkan dan tidak terhubung ke jaringan WiFi)

Opsi pertama tidak diperhatikan dalam jawaban @ Jesse . The shperintah bergaris out adalah:

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

catsedang digunakan untuk memeriksa konten carrierdan mengarahkan semua keluaran ke keluaran standar meskipun gagal karena berkas tidak dapat dibaca. Jika grep -qditemukan di "1"antara file-file tersebut, berarti setidaknya ada 1 antarmuka yang terhubung. Kode keluar dari grep -qakan menjadi kode keluar terakhir.

Pemakaian

Misalnya, menggunakan status exit perintah ini, Anda dapat menggunakannya memulai gnubiff di Anda ~/.xprofilehanya jika Anda memiliki koneksi 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 &

Referensi


1

Pong tidak berarti layanan web di server sedang berjalan; itu hanya berarti bahwa server membalas echo ICMP. Saya akan merekomendasikan menggunakan curl dan memeriksa nilai kembaliannya.


0

Jika tujuan Anda adalah untuk benar-benar memeriksa akses Internet , banyak dari jawaban yang ada untuk pertanyaan ini yang cacat. Beberapa hal yang harus Anda perhatikan:

  1. Mungkin saja komputer Anda terhubung ke jaringan tanpa jaringan tersebut memiliki akses internet
  2. Mungkin saja server tidak aktif tanpa seluruh internet tidak dapat diakses
  3. Portal tawanan dapat menampilkan respons HTTP untuk URL arbitrer meskipun Anda tidak memiliki akses internet

Dengan pemikiran tersebut, saya yakin strategi terbaik adalah menghubungi beberapa situs melalui koneksi HTTPS dan mengembalikan true jika salah satu situs tersebut merespons.

Sebagai contoh:

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
}

Pemakaian:

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

Beberapa catatan tentang pendekatan ini:

  1. Ini kuat terhadap semua positif dan negatif palsu yang saya uraikan di atas
  2. Semua permintaan terjadi secara paralel untuk memaksimalkan kecepatan
  3. Ini akan mengembalikan palsu jika Anda secara teknis memiliki akses internet tetapi DNS tidak berfungsi atau pengaturan jaringan Anda kacau, yang menurut saya adalah hal yang wajar untuk dilakukan dalam banyak kasus.

Kode kembali dari curl tidak sedang diuji. Pada sistem saya, jika jaringan tidak tersedia, curl memberikan rc = 6 (resolusi DNS gagal) tetapi kode ini masih melaporkan "Terhubung ke internet".
ceperman

@ceperman Kode pengembalian untuk curl diuji pada baris yang tertulis if wait $pid;. Tidak tahu mengapa itu tidak berfungsi di sistem Anda. Apakah Anda yakin Anda menggunakan bash?
Ajedi32

@ceperman Kemungkinan lain; mungkin salah satu URL dalam daftar di bagian atas benar - benar mengembalikan kesuksesan untuk Anda, meskipun yang lain gagal dalam resolusi nama?
Ajedi32

2
Bash saya cukup mendasar jadi saya terus membaca waitdan sekarang memahami kode pengembalian memang sedang diuji. Saya menyalin ulang kode Anda dan hari ini berhasil - ups! Saya pasti telah mengacaukan sesuatu terakhir kali meskipun saya tidak mengerti apa atau bagaimana. Meski begitu, mea culpa. Permintaan maaf.
ceperman


-1

Ini terutama lebih cepat daripada solusi apa pun yang diposting di sini, dan dapat digunakan untuk menguji host tertentu juga.

Triknya adalah menyelesaikan IP menggunakan pemecah DNS yang tidak terlalu sibuk daripada yang digunakan oleh 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
Meskipun tautan ini mungkin menjawab pertanyaan, lebih baik menyertakan bagian penting dari jawaban di sini dan menyediakan tautan untuk referensi. Jawaban link saja bisa menjadi tidak valid jika halaman tertaut berubah. - Dari Ulasan
David Buck

Itu tidak berlaku untuk situasi khusus ini.
Alberto Salvia Novella
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.