如何在不ping网站的情况下测试网络连接?我的意思是,如果网站宕机了,但是有连接怎么办?有没有检查与世界连接的方法?
如何在不ping网站的情况下测试网络连接?我的意思是,如果网站宕机了,但是有连接怎么办?有没有检查与世界连接的方法?
#!/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
如果你的本地域名服务器出现故障,
ping 4.2.2.1
是一个易于记忆且始终可用的IP地址(实际上它就是一个域名服务器)。
ping
的任何解决方案快得多,也许比@Jesse的回答稍微更有效。
find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1' {} \; | grep -q '1'
该命令使用find
和-exec
在/sys/class/net/
中运行命令,针对所有未命名为*lo*
的文件。这些应该是包含有关您机器上可用网络接口信息的目录链接。
正在执行的命令是一个sh
命令,它检查这些目录中carrier
文件的内容。变量$interface/carrier
的值有3个含义- 引用:
看起来有三种状态:
- ./carrier不可读(例如当接口在Network Manager中被禁用时)。
- ./carrier包含“1”(当接口已激活且连接到WiFi网络时)
- ./carrier包含“0”(当接口已激活但未连接到WiFi网络时)
第一个选项在@Jesse's answer中没有处理。要去除的sh
命令如下:
# Note: $0 == $interface
cat "$0"/carrier 2>&1
cat
被用于检查carrier
的内容,并将所有输出重定向到标准输出,即使它因为文件不可读而失败。
如果grep -q
在这些文件中找到"1"
,则表示至少有1个接口已连接。 grep -q
的退出代码将是最终退出代码。
例如,使用此命令的退出状态,您可以在~/.xprofile
中仅在有互联网连接时启动gnubiff。
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 &
最短的方式:fping 4.2.2.1
=> "4.2.2.1 存活着"
我更喜欢这种方法,因为它比ping
更快,输出更少,但不足之处是你需要安装它。
你可以使用任何公共 DNS,而不是特定的网站。
fping -q google.com && echo "做一些事情,因为你已经联网了!"
-q
返回一个退出代码,所以我只是展示了一个在线运行的例子。
在Mac上安装:brew install fping
;在Ubuntu上:sudo apt-get install fping
#!/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
Ping的设计目的就是为了实现您想要的功能。但是,如果该网站阻止了ICMP回显,则可以通过telnet到某个站点的80端口、wget或curl来进行测试。
为了获得最快的结果,ping一下DNS服务器:
ping -c1 "8.8.8.8" &>"/dev/null"
if [[ "${?}" -ne 0 ]]; then
echo "offline"
elif [[ "${#args[@]}" -eq 0 ]]; then
echo "online"
fi
可作为一个独立命令使用:linkStatus
考虑到这些问题,我认为最好的策略是通过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吗? - Ajedi32wait
的资料,现在明白返回代码确实被测试了。我重新复制了你的代码,今天它可以正常工作了——糟糕!上次我一定搞错了什么,虽然我不知道是什么或者怎么出错的。无论如何,我承认错误并道歉。 - cepermanPong并不表示服务器上的Web服务正在运行;它仅表示该服务器正在响应ICMP回显。 我建议使用curl并检查其返回值。
如果你想处理强制门户,你可以使用这个一行代码:
if [[ $(curl -s -D - http://www.gstatic.com/generate_204 2>/dev/null | head -1 | cut -d' ' -f 2) == "204" ]]; then
echo 'online'
else
echo 'offline'
fi
或者,如果您想要更易读的内容,可以区分被困住的门户和信号不足:
function is_online() {
# Test signal
local response
response=$(curl --silent --dump-header - http://www.gstatic.com/generate_204 2> /dev/null)
if (($? != 0)); then return 2; fi
# Test captive portal
local status=$(echo $response | head -1 | cut -d' ' -f 2)
((status == "204"))
}
is_online && echo online || echo offline