如何在 Linux 上使用 Bash 脚本检查 Internet 访问?
Posted
技术标签:
【中文标题】如何在 Linux 上使用 Bash 脚本检查 Internet 访问?【英文标题】:How can I check Internet access using a Bash script on Linux? 【发布时间】:2013-06-21 21:21:36 【问题描述】:在我的学校,网络不可用(每天晚上 23:00 之后学校会断网,让我们睡觉>..ping -w1 ...。
也就是说,当我使用:ping -q -w1 -c1 8.8.8.8
来检查 Internet 连接是否启动/关闭时,它将在那里没有任何输出并且不会退出,就像我使用单个 cat
一样。
我不知道为什么会这样,但我认为问题与 school-internet-service 有关。有什么建议吗? (我认为wget
可能是一个不错的选择,但我该如何使用呢?)
【问题讨论】:
这可以帮助***.com/questions/929368/… 【参考方案1】:使用 wget:
#!/bin/bash
wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
echo "Online"
else
echo "Offline"
fi
【讨论】:
效果很好。非常感谢!我的旧版本缺少--tries
,因此无法使用。
就个人而言,我通过创建wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null
来增强此模式。这会丢弃输出,这意味着文件不会被遗弃,写入权限也不会出现任何问题。
你真的应该使用--spider
选项,因为它会发送一个http HEAD
请求,而不是一个http GET
请求。现在,在这种情况下,您正在检查 google.com,这是一个非常轻量级的页面,因此它可能没问题。但作为一般规则,如果您只是想检查某些内容是否可用而不实际下载,则应使用HEAD
请求。我已相应地添加到答案中。【参考方案2】:
如果学校真的关闭了他们的路由器,而不是将所有流量重定向到“你为什么不睡觉”页面,则无需下载整个网页或发送 HTTP 标头。您所要做的就是建立连接并检查是否有人在听。
nc -z 8.8.8.8 53
这将输出“连接到 8.8.8.8 端口 53 [tcp/domain] 成功!”如果有人在听,则返回值 0。
如果你想在 shell 脚本中使用它:
nc -z 8.8.8.8 53 >/dev/null 2>&1
online=$?
if [ $online -eq 0 ]; then
echo "Online"
else
echo "Offline"
fi
【讨论】:
这是最快的方法,它 ping dns 服务器而不是获取 google 的网站数据。竖起大拇指。 在这里使用超时可能会很好 nc -z -w 5 8.8.8.8 53 >/dev/null 2>&1【参考方案3】:用途:
#!/bin/bash
INTERNET_STATUS="UNKNOWN"
TIMESTAMP=`date +%s`
while [ 1 ]
do
ping -c 1 -W 0.7 8.8.4.4 > /dev/null 2>&1
if [ $? -eq 0 ] ; then
if [ "$INTERNET_STATUS" != "UP" ]; then
echo "UP `date +%Y-%m-%dT%H:%M:%S%Z` $((`date +%s`-$TIMESTAMP))";
INTERNET_STATUS="UP"
fi
else
if [ "$INTERNET_STATUS" = "UP" ]; then
echo "DOWN `date +%Y-%m-%dT%H:%M:%S%Z` $((`date +%s`-$TIMESTAMP))";
INTERNET_STATUS="DOWN"
fi
fi
sleep 1
done;
输出将产生如下内容:
./internet_check.sh
UP 2016-05-10T23:23:06BST 4
DOWN 2016-05-10T23:23:25BST 19
UP 2016-05-10T23:23:32BST 7
行尾的数字表示前一个状态的持续时间,即向上 19 秒,向下 7 秒。
【讨论】:
欢迎来到 Stack Overflow!虽然这段代码可能会回答这个问题,但最好包含一些上下文,解释它的如何工作以及何时使用它。从长远来看,纯代码的答案没有用处。 在几分钟内经历了很多起伏。虽然 DropBox 在线并且可以上网...请参阅 unix.stackexchange.com/a/190610/19694,他们提到nc
比使用 ping 更好,因为很多主机商也禁用了 ICMP。
我看不到如何使用上面的代码获得持续时间。我试过了,每行的“持续时间”单调增长。 TIMESTAMP 不是每次循环都要重置吗?【参考方案4】:
使用超时选项-t
:
ping -q -t 5 -w1 -c1 8.8.8.8 t
【讨论】:
这个解决方案的一个问题是,一些网络可能会阻止传出的 ping(我的大学有这样做的著名记录)。不过,OP 似乎并非如此。 @umlaeute,在这种情况下,您可以使用wget http://google.com
甚至(更好更简单)curl
【参考方案5】:
没有 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
享受;)
【讨论】:
【参考方案6】:安装 fping:> 问题比 ping 少。
fping google.com | grep alive
使用,例如,像:
#!/bin/bash
itest=$(fping google.com | grep alive)
while [ "$itest" == "" ]
do
sleep 5
itest=$(fping google.com | grep alive)
done
echo now online
【讨论】:
fping
需要在运行示例之前安装。【参考方案7】:
使用上面的示例。我写了这个脚本来记录你的连接状态: https://gist.github.com/cganterh/ffc2fffa8263857cbece
首先,将以下代码保存到name.sh
文件中。
#!/bin/bash
while true
do
wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null
if [[ $? -eq 0 ]]; then
echo $(date) "1" | tee -a log.csv
else
echo $(date) "0" | tee -a log.csv
fi
sleep 5
done
然后,在终端执行name.sh
文件,然后查看同一文件夹log.csv
的日志状态信息。
【讨论】:
【参考方案8】:我决定将之前的几个答案结合起来,这样我以后就可以创建一个显示起起落落及其持续时间的图:
#!/bin/bash
#
# pinger is a bash shell script that monitors the network
# status every 15 seconds and records if it is up '1' or down '0'
# into the file log.csv from whence it may be plotted.
#
# author: J. W. Wooten, Ph.D.
# since: 11/12/2019
# version: 1.0
#
TIMESTAMP=`date +%s`
while [ 1 ]
do
nc -z -w 5 8.8.8.8 53 >/dev/null 2>&1
online=$?
TIME=`date +%s`
if [ $online -eq 0 ]; then
echo "`date +%Y-%m-%d_%H:%M:%S_%Z` 1 $(($TIME-$TIMESTAMP))" | tee -a log.csv
else
echo "`date +%Y-%m-%d_%H:%M:%S_%Z` 0 $(($TIME-$TIMESTAMP))" | tee -a log.csv
fi
TIMESTAMP=$TIME
sleep 15
done;
这将每 15 秒输出到一个 CSV 文件。使用 Excel 或 Numbers,您可以读取文件并创建一个图表,该图表将显示 Internet 连接何时不可用以及持续时间。如果它从您的睡眠间隔发生变化,那么它正在花费时间尝试连接。我希望添加在下一次检测到网络关闭时向我发送文本的功能。
【讨论】:
【参考方案9】:Majal's solution 的一个变体只是为了测试 ping 的返回代码,如果站点响应,则返回 0,如果没有回复,则返回 1,如果网络不可达,则返回 2。
ping -c 1 -t 5 8.8.8.8 2&>1
rc=$?
[[ $rc -eq 0 ]] && echo "Connected to the Internet" ; exit 0 ; \
|| [[ $rc -eq 1 ]] && echo "No reply from Google DNS" ; exit 1 ; \
|| [[ $rc -eq 2 ]] && echo "Network unreachable" ; exit 2 ;
使用ping的好处是不需要下载任何东西,提高了测试速度。
【讨论】:
【参考方案10】:可靠的旧 ping
在单独的 Bash 脚本中:
#!/bin/bash
ipaddr='8.8.8.8' # Google's public DNS server
[[ -z `ping -c1 $ipaddr |& grep -o 'Network is unreachable'` ]] || exit 1
[[ -z `ping -c3 $ipaddr |& grep -o '100% packet loss'` ]] && exit 0 || exit 1
把它放在一个单独的脚本中。它将处理不同的网络情况,例如 (1) 未连接到网络,(2) 已连接到网络,但无法访问 Internet(或至少 Google),以及 (3) 连接到互联网。
您可以稍后使用脚本的exit code
来检查连接性,例如
~$ script-name && echo online || echo offline
【讨论】:
以上是关于如何在 Linux 上使用 Bash 脚本检查 Internet 访问?的主要内容,如果未能解决你的问题,请参考以下文章
Bash脚本:如何在Linux Shell上输出和格式化文本
我只想检查在Linux bash上的命令输出中列出的服务器上的网络接口状态