网络连通性批量检测脚本
批量检测多个IP/域名的网络连通性,支持ping和端口检测,生成检测报告,超时或丢包时告警
详细内容
#!/bin/bash
# ==========================================
# 网络连通性批量检测脚本
# 用途:批量检测多个IP/域名的连通性和端口状态
# 使用方法:
# 1. 修改 HOSTS 配置
# 2. bash network_check.sh
# ==========================================
# ========== 配置 ==========
# 检测列表:名称|主机|端口(可选,留空只ping)
HOSTS=(
"网关|192.168.1.1|"
"DNS服务器|8.8.8.8|"
"百度|www.baidu.com|443"
"阿里云|223.5.5.5|"
# "数据库|192.168.1.100|3306"
# "Redis|192.168.1.101|6379"
)
PING_COUNT=3 # ping次数
PING_TIMEOUT=2 # ping超时(秒)
PORT_TIMEOUT=3 # 端口检测超时(秒)
LOG_FILE="/var/log/network_check.log"
ALERT_EMAIL=""
WECOM_WEBHOOK=""
# ==========================
mkdir -p "$(dirname "$LOG_FILE")"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
send_alert() {
local title="$1"
local content="$2"
log_msg "【告警】$title: $content"
if [ -n "$ALERT_EMAIL" ]; then
echo -e "$content" | mail -s "【网络告警】$title" "$ALERT_EMAIL" 2>/dev/null
fi
if [ -n "$WECOM_WEBHOOK" ]; then
curl -s "$WECOM_WEBHOOK" -H "Content-Type: application/json" -d "{
"msgtype": "text",
"text": {"content": "【网络告警】$title\n$content"}
}" >/dev/null 2>&1
fi
}
check_ping() {
local host="$1"
local result=$(ping -c "$PING_COUNT" -W "$PING_TIMEOUT" "$host" 2>&1)
if echo "$result" | grep -q "100% packet loss\|100% 丢包\|Destination Host Unreachable"; then
echo "FAIL|丢包率100%|0ms"
return 1
fi
local loss=$(echo "$result" | grep -oP "\d+% packet loss|\d+% 丢包" | head -1 | grep -oP "\d+")
local avg_time=$(echo "$result" | grep -oP "avg/[^/]+/\K[0-9.]+" | head -1)
[ -z "$avg_time" ] && avg_time=$(echo "$result" | grep -oP "time=\K[0-9.]+" | tail -1)
[ -z "$avg_time" ] && avg_time="N/A"
if [ "${loss:-0}" -gt 0 ]; then
echo "WARN|丢包率${loss}%|${avg_time}ms"
return 2
fi
echo "OK|丢包率0%|${avg_time}ms"
return 0
}
check_port() {
local host="$1"
local port="$2"
if command -v nc >/dev/null 2>&1; then
if nc -z -w "$PORT_TIMEOUT" "$host" "$port" 2>/dev/null; then
echo "OPEN"
return 0
else
echo "CLOSED"
return 1
fi
elif command -v telnet >/dev/null 2>&1; then
timeout "$PORT_TIMEOUT" bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null && echo "OPEN" || echo "CLOSED"
return $?
else
echo "UNCHECK(无nc/telnet)"
return 3
fi
}
log_msg "=========================================="
log_msg " 网络连通性批量检测报告"
log_msg " 检测时间: $(date '+%Y-%m-%d %H:%M:%S')"
log_msg "=========================================="
PASS_COUNT=0
FAIL_COUNT=0
WARN_COUNT=0
for item in "${HOSTS[@]}"; do
name=$(echo "$item" | cut -d'|' -f1)
host=$(echo "$item" | cut -d'|' -f2)
port=$(echo "$item" | cut -d'|' -f3)
log_msg ""
log_msg "【$name】$host"
# Ping检测
ping_result=$(check_ping "$host")
ping_status=$(echo "$ping_result" | cut -d'|' -f1)
ping_detail=$(echo "$ping_result" | cut -d'|' -f2)
ping_time=$(echo "$ping_result" | cut -d'|' -f3)
case "$ping_status" in
OK)
log_msg " 🟢 Ping: $ping_detail 延迟$ping_time"
PASS_COUNT=$((PASS_COUNT + 1))
;;
WARN)
log_msg " 🟡 Ping: $ping_detail 延迟$ping_time"
WARN_COUNT=$((WARN_COUNT + 1))
send_alert "$name 网络丢包" "$host ping丢包: $ping_detail,延迟$ping_time"
;;
FAIL)
log_msg " 🔴 Ping: $ping_detail"
FAIL_COUNT=$((FAIL_COUNT + 1))
send_alert "$name 网络不通" "$host ping失败: $ping_detail"
;;
esac
# 端口检测
if [ -n "$port" ]; then
port_status=$(check_port "$host" "$port")
if [ "$port_status" = "OPEN" ]; then
log_msg " 🟢 端口$port: $port_status"
else
log_msg " 🔴 端口$port: $port_status"
FAIL_COUNT=$((FAIL_COUNT + 1))
send_alert "$name 端口异常" "$host:$port 状态: $port_status"
fi
fi
done
log_msg ""
log_msg "=========================================="
log_msg " 检测总结: 正常$PASS_COUNT 警告$WARN_COUNT 失败$FAIL_COUNT"
log_msg "=========================================="
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "HOSTS", "label": "\u68c0\u6d4b\u5217\u8868(\u6bcf\u884c\u4e00\u4e2a\uff0c\u683c\u5f0f\uff1a\u540d\u79f0|\u4e3b\u673a|\u7aef\u53e3)", "type": "textarea", "default": "\u7f51\u5173|192.168.1.1|\n\u767e\u5ea6|www.baidu.com|443"}, {"name": "PING_COUNT", "label": "Ping\u6b21\u6570", "default": "3"}, {"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1(\u53ef\u9009)", "default": ""}]