引言
在日常活动中,我遇到过一个令人头疼的问题。测试使用的远程终端在第二天继续使用时可能就发生无法与外网通信的情况,往往连上终端后在拉取资源时才能发现。这导致每次使用前都需要手动检查网络状况,增加了不必要的麻烦。为了简化这一过程,我决定编写一个脚本,实现一键网络检测。
本文将介绍这样一个简单的 Shell 脚本,用于检查服务器内外网络的连接状态。该脚本不仅可以检查预设的内部和外部网络节点,还可以接受用户输入的额外 IP 地址进行检测。
脚本代码
bash
#!/bin/bash
# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# 定义要测试的IP地址
INTERNAL_IP="127.0.0.1"
EXTERNAL_IP1="223.5.5.5" # 阿里云公共DNS
EXTERNAL_IP2="8.8.8.8" # 谷歌公共DNS
# 获取当前服务器的主要IP地址
DEFAULT_ROUTE=$(ip route | grep default | awk '{print $3}')
DEFAULT_INTERFACE=$(ip route | grep default | awk '{print $5}')
SERVER_IP=$(ip addr show $DEFAULT_INTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n 1)
# 获取本地网关
GATEWAY_IP1=$DEFAULT_ROUTE
# 提示用户输入额外检测的IP地址
read -p "请输入需要额外检测的IP地址(留空则按回车跳过): " EXTRA_IP
# 用数组存储测试结果
results=()
# 函数:检查网络连接
check_connection() {
local ip=$1
local name=$2
if ! [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo -e "${RED}输入的IP格式有误,不检测${NC}"
results+=("$name: 失败 (IP: $ip)")
return
fi
local ping_output=$(ping -c 4 $ip 2>/dev/null)
local exit_code=$?
local result=$(echo "$ping_output" | tail -1 | awk -F '/' '{print $5}')
if [ $exit_code -ne 0 ] || [ -z "$result" ]; then
echo -e "${RED}无法连接到 ${name} (${ip})${NC}"
results+=("$name: 失败 (IP: $ip)")
else
echo -e "${GREEN}成功连接到 ${name} (${ip}) - 平均响应时间: ${result}ms${NC}"
results+=("$name: 成功 (IP: $ip)")
fi
}
# 打印标题
echo -e "${GREEN}开始网络连接检查...${NC}"
echo -e "${GREEN}当前服务器IP地址: ${SERVER_IP}${NC}"
# 检查额外指定的IP地址
if [ -n "$EXTRA_IP" ]; then
check_connection $EXTRA_IP "额外检测的IP地址"
else
echo -e "${NC}未指定额外的IP地址,不检测${NC}"
fi
# 检查内部网络
check_connection $INTERNAL_IP "内部网络"
# 检查本地网关
check_connection $GATEWAY_IP1 "本地网关"
# 检查外部网络(阿里云公共DNS)
check_connection $EXTERNAL_IP1 "外部网络 (阿里云)"
# 检查外部网络(谷歌公共DNS)
check_connection $EXTERNAL_IP2 "外部网络 (谷歌)"
# 结束语
all_success=true
for result in "${results[@]}"; do
if [[ $result == *"失败"* ]]; then
all_success=false
break
fi
done
if [ "$all_success" = true ]; then
echo -e "\n${GREEN}所有节点网络正常。${NC}"
else
echo -e "\n${RED}以下节点存在网络问题:${NC}"
for result in "${results[@]}"; do
if [[ $result == *"失败"* ]]; then
echo -e "${RED}${result}${NC}"
fi
done
fi
echo -e "\n${GREEN}网络连接检查完成。${NC}"
主要模块详解
-
定义要测试的IP地址:
bashINTERNAL_IP="127.0.0.1" EXTERNAL_IP1="223.5.5.5" # 阿里云公共DNS EXTERNAL_IP2="8.8.8.8" # 谷歌公共DNS
详解 :通过常用的网络地址来检验服务器内外网的连通性。
127.0.0.1
是本地环回地址,用于检查内部网络连接。223.5.5.5
和8.8.8.8
分别是阿里云和谷歌的公共DNS服务器,用于检查外部网络连接。 -
获取当前服务器的主要IP地址:
bashDEFAULT_ROUTE=$(ip route | grep default | awk '{print $3}') DEFAULT_INTERFACE=$(ip route | grep default | awk '{print $5}') SERVER_IP=$(ip addr show $DEFAULT_INTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n 1)
详解:这部分代码通过解析路由表和网络接口信息,获取当前服务器的主要IP地址。
DEFAULT_ROUTE
获取默认网关的IP地址。DEFAULT_INTERFACE
获取默认网关使用的网络接口名称,为下一步获取主机IP提供便利。SERVER_IP
获取主机IP。
-
构建功能函数:检查网络连接:
bashcheck_connection() { local ip=$1 local name=$2 if ! [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then echo -e "${RED}输入的IP格式有误,不检测${NC}" results+=("$name: 失败 (IP: $ip)") return fi local ping_output=$(ping -c 4 $ip 2>/dev/null) local exit_code=$? local result=$(echo "$ping_output" | tail -1 | awk -F '/' '{print $5}') if [ $exit_code -ne 0 ] || [ -z "$result" ]; then echo -e "${RED}无法连接到 ${name} (${ip})${NC}" results+=("$name: 失败 (IP: $ip)") else echo -e "${GREEN}成功连接到 ${name} (${ip}) - 平均响应时间: ${result}ms${NC}" results+=("$name: 成功 (IP: $ip)") fi }
详解 :这个函数负责检查给定IP地址的网络连接状态,并将结果记录到
results
数组中。local ip=$1
和local name=$2
:将传入的参数分别赋值给局部变量ip
和name
。if ! [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
:检查是否为标准IPv4地址格式。如果不正确,输出错误信息并返回。local ping_output=$(ping -c 4 $ip 2>/dev/null)
:使用ping
命令发送4次ICMP请求,并捕获输出。local exit_code=$?
:获取ping
命令的退出状态码。local result=$(echo "$ping_output" | tail -1 | awk -F '/' '{print $5}')
:从ping
输出中提取平均响应时间。if [ $exit_code -ne 0 ] || [ -z "$result" ]; then
:如果 ping 命令执行失败,exit_code
状态码不为0;如果 ping 命令没有返回有效的响应时间,result
提取的平均响应时间将为空字符串;这两种结果都定义为失败,如果失败,输出错误信息并记录结果;否则,输出成功信息并记录结果。
-
整体结果判断:
bashall_success=true for result in "${results[@]}"; do if [[ $result == *"失败"* ]]; then all_success=false break fi done if [ "$all_success" = true ]; then echo -e "\n${GREEN}所有节点网络正常。${NC}" else echo -e "\n${RED}以下节点存在网络问题:${NC}" for result in "${results[@]}"; do if [[ $result == *"失败"* ]]; then echo -e "${RED}${result}${NC}" fi done fi echo -e "\n${GREEN}网络连接检查完成。${NC}"
详解 :根据
results
数组中的内容,输出检查结果和总结信息。all_success=true
:初始化一个布尔变量all_success
,表示所有节点是否都成功连接。for result in "${results[@]}"; do
:遍历results
数组,检查是否有失败的记录。if [ "$all_success" = true ]; then
:如果所有节点都成功连接,输出成功信息;否则,输出失败的节点列表。echo -e "\n${GREEN}网络连接检查完成。${NC}"
:输出检查完成的信息。
使用效果演示
bash
[root@halo ~]# sh check_network.sh # 指定正常检测
请输入需要额外检测的IP地址(留空则按回车跳过): 192.168.1.215
开始网络连接检查...
当前服务器IP地址: 192.168.111.130
成功连接到 额外检测的IP地址 (192.168.1.215) - 平均响应时间: 1.020ms
成功连接到 内部网络 (127.0.0.1) - 平均响应时间: 0.083ms
成功连接到 本地网关 (192.168.111.2) - 平均响应时间: 0.588ms
成功连接到 外部网络 (阿里云) (223.5.5.5) - 平均响应时间: 16.654ms
成功连接到 外部网络 (谷歌) (8.8.8.8) - 平均响应时间: 53.729ms
所有节点网络正常。
网络连接检查完成。
[root@halo ~]# sh check_network.sh # 输入检测IP有误
请输入需要额外检测的IP地址(留空则按回车跳过): hello
开始网络连接检查...
当前服务器IP地址: 192.168.111.130
输入的IP格式有误,不检测
成功连接到 内部网络 (127.0.0.1) - 平均响应时间: 0.073ms
成功连接到 本地网关 (192.168.111.2) - 平均响应时间: 0.406ms
成功连接到 外部网络 (阿里云) (223.5.5.5) - 平均响应时间: 16.665ms
成功连接到 外部网络 (谷歌) (8.8.8.8) - 平均响应时间: 53.524ms
以下节点存在网络问题:
额外检测的IP地址: 失败 (IP: hello)
网络连接检查完成。
[root@halo ~]# sh check_network.sh # 指定检测IP无法通信
请输入需要额外检测的IP地址(留空则按回车跳过): 192.168.1.888
开始网络连接检查...
当前服务器IP地址: 192.168.111.130
无法连接到 额外检测的IP地址 (192.168.1.888)
成功连接到 内部网络 (127.0.0.1) - 平均响应时间: 0.068ms
成功连接到 本地网关 (192.168.111.2) - 平均响应时间: 0.857ms
成功连接到 外部网络 (阿里云) (223.5.5.5) - 平均响应时间: 14.097ms
成功连接到 外部网络 (谷歌) (8.8.8.8) - 平均响应时间: 47.028ms
以下节点存在网络问题:
额外检测的IP地址: 失败 (IP: 192.168.1.888)
网络连接检查完成。
结语
通过这次尝试,我编写了一个简单的 Shell 脚本,用于检查服务器的网络连接状态。这个脚本帮助我在工作前快速检测服务器网络连接情况,及时发现和定位问题。希望这个小工具能为你在日常工作中带来便利。如果你有任何问题或建议,欢迎在评论区留言分享!希望这篇文章对你有所帮助!