Как можно проверить подключение к Интернету без проверки связи с веб-сайтом? Я имею в виду, что если соединение есть, но сайт не работает? Есть ли проверка на связь с миром?
Как можно проверить подключение к Интернету без проверки связи с веб-сайтом? Я имею в виду, что если соединение есть, но сайт не работает? Есть ли проверка на связь с миром?
Ответы:
Без пинга
#!/bin/bash
wget -q --spider http://google.com
if [ $? -eq 0 ]; then
echo "Online"
else
echo "Offline"
fi
-q : режим без звука
--spider : не получайте, просто проверьте доступность страницы
$? : код возврата оболочки
0 : код оболочки "Все ОК"
Без 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
чтобы убедиться, что он истек . что-то вродеnc google.com 80 -w 10
Пингуйте свой шлюз по умолчанию:
#!/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 }
а затем использовать так:ping_gw || (echo "no network, bye" && exit 1)
ifconfig down wlan0
и у меня все еще есть шлюз по умолчанию, и он доступен для проверки связи, хотя я фактически не могу связаться с внешним миром.
Супер Спасибо пользователю somedrew за их сообщение здесь: https://bbs.archlinux.org/viewtopic.php?id=55485 от 20.09.2008 02:09:48
Взгляд в / sys / class / net должен быть односторонним
Вот мой сценарий для проверки сетевого подключения, кроме петли. Я использую приведенный ниже сценарий в другом сценарии, который у меня есть для периодического тестирования доступности моего веб-сайта. Если он НЕ доступен, всплывающее окно предупреждает меня о проблеме.
Приведенный ниже сценарий не позволяет мне получать всплывающие сообщения каждые пять минут, если мой ноутбук не подключен к сети.
#!/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: последний оператор if проверяет НЕ [!] Онлайн и завершает работу, если это так. См. Man bash и поиск по запросу «Выражения могут быть объединены» для получения более подробной информации.
PS Я считаю, что пинг - не лучшее, что можно здесь использовать, потому что он направлен на проверку соединения с конкретным хостом, а НЕ на проверку наличия соединения с какой- либо сетью .
PPS. Вышеупомянутое работает в Ubuntu 12.04. / Sys может не существовать в некоторых других дистрибутивах. Увидеть ниже:
Современные дистрибутивы Linux включают каталог / sys в качестве виртуальной файловой системы (sysfs, сопоставимой с / proc, которая является procfs), которая хранит и позволяет изменять устройства, подключенные к системе, тогда как многие традиционные UNIX и Unix-подобные операционные системы используют / sys в качестве символической ссылки на дерево исходных текстов ядра. [необходима ссылка]
Из Википедии https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
cat /sys/class/net/wwan0/carrier
Не работает на ubuntu 14.04 LTS.
2>/dev/null
после, cat /sys/class/net/$interface/carrier
чтобы не выводить ошибку в случае, если сеть отключена.
Это работает как на MacOSX, так и на Linux:
#!/bin/bash
ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline
ping: invalid option -- w
)
fping google.com
или просто fping 8.8.8.8
творит чудеса с бонусом, вы получаете код статуса без необходимости его проверять (" google.com is alive
") ...
В Bash, используя сетевую оболочку через / dev / { udp , tcp } / host / port :
if : >/dev/tcp/8.8.8.8/53; then
echo 'Internet available.'
else
echo 'Offline.'
fi
( :
это запрет на Bash, потому что вы просто хотите проверить соединение, но не обработку.)
Раньше я писал сценарии, которые просто используют telnet для подключения к порту 80, а затем передают текст:
HTTP/1.0 GET /index.html
за которыми следуют две последовательности CR / LF.
Если вы получили ответ HTTP в той или иной форме, вы можете предположить, что сайт работает.
Главный ответ упускает из виду тот факт, что у вас может быть совершенно стабильное соединение со своим шлюзом по умолчанию, но это не означает, что вы автоматически можете получить доступ к чему-то в Интернете. ОП спрашивает, как он / она может проверить связь с миром. Поэтому я предлагаю изменить главный ответ, изменив IP-адрес шлюза на известный IP-адрес (xyzw), который находится за пределами вашей локальной сети.
Итак, ответ будет таким:
ping -q -w 1 -c 1 x.y.z.w > /dev/null && echo ok || echo error
Также удаление нежелательных обратных кавычек для подстановки команд [1] .
Если вы просто хотите убедиться, что вы подключены к миру, прежде чем выполнять какой-то код, вы также можете использовать:
if ping -q -w 1 -c 1 x.y.z.w > /dev/null; then
# more code
fi
убедитесь, что ваша сеть разрешает входящий и исходящий трафик TCP, тогда вы можете вернуть свой общедоступный IP-адрес с помощью следующей команды
curl ifconfig.co
Выполните следующую команду, чтобы проверить, работает ли веб-сайт и какое сообщение о состоянии показывает веб-сервер:
$ curl -Is http://www.google.com |
head -1 HTTP/1.1 200 OK
Код состояния «200 OK» означает, что запрос выполнен и веб-сайт доступен.
curl -Is http://www.google.com | head -1 | grep 200; if [[ $? -eq 0 ]]; then; echo "Online"; else; echo "Offline"; fi;
Если ваш локальный сервер имен не работает,
пинг 4.2.2.1
- это легко запоминающийся всегда активный IP (на самом деле это даже сервер имен).
Топ проголосовали ответ не работает для MacOS так и для тех , кто на макинтош, я успешно проверил это:
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
route
команду на, route -n get default 2> /dev/null | grep gateway
чтобы избежать записи ошибки в stderr в автономном режиме.
Этот сценарий bash постоянно проверяет наличие Интернета и издает звуковой сигнал, когда Интернет доступен.
#!/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
кратчайший путь: fping 4.2.2.1
=> «4.2.2.1 жив»
Я предпочитаю это, так как это более быстрый и менее подробный вывод, чем ping
недостаток в том, что вам придется его установить.
вы можете использовать любые общедоступные DNS, а не конкретный веб-сайт.
fping -q google.com && echo "do something because you're connected!"
-q
возвращает код выхода, поэтому я просто показываю пример запуска того, что вы в сети.
установить на макинтош: brew install fping
; в Ubuntu:sudo apt-get install fping
Подобно ответу @ Jesse , этот вариант может быть намного быстрее, чем любое ping
другое решение, и, возможно, немного более эффективным, чем ответ @ Jesse .
find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1' {} \; | grep -q '1'
Эта команда использует find
with -exec
для запуска команды для всех файлов, не названных *lo*
в /sys/class/net/
. Это должны быть ссылки на каталоги, содержащие информацию о доступных сетевых интерфейсах на вашем компьютере.
Выполняемая команда - это sh
команда, которая проверяет содержимое файла carrier
в этих каталогах. Значение $interface/carrier
имеет 3 значения - Цитата :
Кажется, есть три состояния:
- ./carrier не читается (например, когда интерфейс отключен в Network Manager).
- ./carrier содержат "1" (когда интерфейс активирован и он подключен к сети Wi-Fi)
- ./carrier содержат "0" (когда интерфейс активирован и он не подключен к сети Wi-Fi)
Первый вариант не рассматривается в ответе @Jesse . sh
Команда полосатая из вне:
# Note: $0 == $interface
cat "$0"/carrier 2>&1
cat
используется для проверки содержимого carrier
и перенаправления всего вывода на стандартный вывод, даже если он терпит неудачу из-за того, что файл не читается. Если среди этих файлов grep -q
обнаруживается "1"
, это означает, что подключен как минимум 1 интерфейс. Код выхода grep -q
будет последним кодом выхода.
Например, используя статус выхода этой команды, вы можете использовать ее для запуска gnubiff в вашем ~/.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 &
Если ваша цель действительно проверить доступ к Интернету , многие из существующих ответов на этот вопрос ошибочны. Вам следует знать несколько вещей:
Имея это в виду, я считаю, что лучшая стратегия - связаться с несколькими сайтами через HTTPS-соединение и вернуть true, если какой-либо из этих сайтов отвечает.
Например:
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
}
Использование:
if connected_to_internet; then
echo "Connected to internet"
else
echo "No internet connection"
fi
Некоторые примечания об этом подходе:
if wait $pid;
. Понятия не имею, почему это не работает в вашей системе. Вы уверены, что используете bash?
wait
и понял, что код возврата действительно тестируется. Я повторно скопировал ваш код, и сегодня он работает - упс! Должно быть, я что-то напортачил в прошлый раз, хотя не могу понять, что и как. Тем не менее, я виноват. Извинения.
Это заметно быстрее, чем любое решение, размещенное здесь, и его также можно использовать для тестирования конкретного хоста .
Уловка состоит в том, чтобы определить IP-адрес с помощью менее загруженного DNS-решателя, чем тот, который используется 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
}