Files
dock/测速中文
2025-10-28 14:51:11 +08:00

577 lines
15 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
echo "🚀 Debian/Ubuntu 网络测速与诊断脚本"
# 脚本信息
SCRIPT_NAME="network-speedtest"
SCRIPT_VERSION="2.0.0"
SCRIPT_AUTHOR="系统优化版"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE} $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
log_result() {
echo -e "${CYAN}📊 $1${NC}"
}
log_debug() {
if [ "$DEBUG" = "true" ]; then
echo -e "${PURPLE}🐛 $1${NC}"
fi
}
# 显示标题
show_header() {
echo "=================================================="
echo " 🚀 $SCRIPT_NAME v$SCRIPT_VERSION"
echo " $SCRIPT_AUTHOR"
echo "=================================================="
}
# 检查系统兼容性
check_system() {
log_info "检查系统环境..."
# 检查是否为 Debian/Ubuntu 系
if [ ! -f /etc/debian_version ] && [ ! -f /etc/lsb-release ]; then
if [ -f /etc/redhat-release ] || [ -f /etc/centos-release ]; then
log_warning "检测到 RedHat/CentOS 系统,部分功能可能需要调整"
elif [ -f /etc/alpine-release ]; then
log_warning "检测到 Alpine Linux建议使用 Debian/Ubuntu 系统"
else
log_warning "非 Debian/Ubuntu 系统,兼容性可能受限"
fi
fi
# 检测系统版本
if [ -f /etc/os-release ]; then
source /etc/os-release
log_info "检测到系统: $PRETTY_NAME"
# 检查系统架构
local arch=$(uname -m)
log_info "系统架构: $arch"
# 检查内核版本
local kernel=$(uname -r)
log_info "内核版本: $kernel"
fi
# 检查权限
if [ "$EUID" -eq 0 ]; then
log_warning "当前以 root 权限运行"
else
log_info "当前以普通用户权限运行,部分操作需要 sudo"
fi
}
# 检查并安装必要工具
install_required_tools() {
log_info "检查系统工具..."
local packages=()
local package_manager=""
local install_cmd=""
# 检测包管理器
if command -v apt-get &> /dev/null; then
package_manager="apt"
install_cmd="sudo apt-get install -y"
elif command -v yum &> /dev/null; then
package_manager="yum"
install_cmd="sudo yum install -y"
elif command -v dnf &> /dev/null; then
package_manager="dnf"
install_cmd="sudo dnf install -y"
elif command -v apk &> /dev/null; then
package_manager="apk"
install_cmd="sudo apk add"
else
log_error "未找到支持的包管理器"
return 1
fi
log_info "使用包管理器: $package_manager"
# 基础工具列表
local base_tools=("curl" "wget" "ping" "bc" "dig" "traceroute")
# 根据包管理器调整包名
case $package_manager in
"apt")
packages=("curl" "wget" "iputils-ping" "bc" "dnsutils" "traceroute")
;;
"yum"|"dnf")
packages=("curl" "wget" "iputils" "bc" "bind-utils" "traceroute")
;;
"apk")
packages=("curl" "wget" "iputils" "bc" "bind-tools" "traceroute")
;;
esac
# 更新包列表
log_info "更新软件包列表..."
case $package_manager in
"apt") sudo apt-get update ;;
"yum") sudo yum check-update || true ;;
"dnf") sudo dnf check-update || true ;;
"apk") sudo apk update ;;
esac
# 检查并安装缺失的包
local missing_packages=()
for pkg in "${packages[@]}"; do
if ! command -v "${pkg%% *}" &> /dev/null && ! dpkg -l | grep -q "^ii ${pkg} " 2>/dev/null; then
missing_packages+=("$pkg")
fi
done
if [ ${#missing_packages[@]} -ne 0 ]; then
log_warning "需要安装缺失的包: ${missing_packages[*]}"
if [ "$AUTO_INSTALL" = "true" ]; then
log_info "自动安装中..."
else
read -p "是否安装这些包?(Y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
log_warning "跳过包安装,部分功能可能无法使用"
return 0
fi
fi
if $install_cmd "${missing_packages[@]}"; then
log_success "包安装完成"
else
log_error "包安装失败"
return 1
fi
else
log_success "所有必要工具已安装"
fi
}
# 安装 speedtest-cli
install_speedtest() {
log_info "检查 speedtest 工具..."
# 检查是否已安装
if command -v speedtest &> /dev/null || command -v speedtest-cli &> /dev/null; then
log_success "speedtest 已安装"
return 0
fi
log_info "安装 speedtest-cli..."
# 方法1: 使用系统包管理器
case $package_manager in
"apt")
if sudo apt-get install -y speedtest-cli 2>/dev/null; then
log_success "通过 apt 安装成功"
return 0
fi
;;
"yum"|"dnf")
if sudo $package_manager install -y speedtest-cli 2>/dev/null; then
log_success "通过 $package_manager 安装成功"
return 0
fi
;;
esac
# 方法2: 使用 pip
if command -v pip3 &> /dev/null; then
log_info "尝试使用 pip3 安装..."
if pip3 install speedtest-cli 2>/dev/null; then
log_success "通过 pip3 安装成功"
return 0
fi
fi
# 方法3: 使用官方脚本
log_info "使用官方脚本安装..."
if curl -s https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh | sudo bash 2>/dev/null; then
if sudo apt-get install -y speedtest 2>/dev/null; then
log_success "通过官方仓库安装成功"
return 0
fi
fi
# 方法4: 直接下载
log_info "直接下载 speedtest-cli..."
if wget -q -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py; then
chmod +x speedtest-cli
sudo mv speedtest-cli /usr/local/bin/speedtest-cli
if command -v speedtest-cli &> /dev/null; then
log_success "speedtest-cli 安装成功"
return 0
fi
fi
log_warning "speedtest-cli 安装失败,将使用备用测速方法"
return 1
}
# 网络连通性测试
test_connectivity() {
log_info "测试网络连通性..."
local test_hosts=(
"223.5.5.5" # 阿里DNS
"114.114.114.114" # 114DNS
"1.1.1.1" # Cloudflare
"8.8.8.8" # Google DNS
"119.29.29.29" # 腾讯DNS
)
local connected=false
local success_count=0
for host in "${test_hosts[@]}"; do
if ping -c 2 -W 3 "$host" &> /dev/null; then
log_success "连通 $host"
connected=true
((success_count++))
else
log_warning "无法连接 $host"
fi
done
if [ "$connected" = false ]; then
log_error "网络连接测试失败"
return 1
fi
log_info "网络连通性: $success_count/${#test_hosts[@]} 个测试点成功"
return 0
}
# DNS 解析测试
test_dns() {
log_info "测试 DNS 解析..."
local domains=("baidu.com" "qq.com" "taobao.com" "github.com" "debian.org")
local success_count=0
for domain in "${domains[@]}"; do
if dig +short "$domain" &> /dev/null; then
local ip=$(dig +short "$domain" | head -1)
log_success "解析 $domain$ip"
((success_count++))
else
log_warning "解析失败: $domain"
fi
done
log_info "DNS 解析: $success_count/${#domains[@]} 个域名成功"
}
# 延迟测试
test_latency() {
log_info "测试网络延迟..."
local latency_hosts=(
"223.5.5.5" # 阿里DNS
"114.114.114.114" # 114DNS
"1.1.1.1" # Cloudflare
"8.8.8.8" # Google DNS
)
for host in "${latency_hosts[@]}"; do
if ping -c 4 -W 2 "$host" &> /dev/null; then
local result
result=$(ping -c 4 -W 2 "$host" | tail -1 | awk -F'/' '{print "平均延迟: "$5"ms, 抖动: "$6"ms"}')
log_info "$host - $result"
else
log_warning "$host - 延迟测试失败"
fi
done
}
# 专业测速
test_speed_professional() {
log_info "开始专业网络测速..."
# 尝试使用 speedtest
if command -v speedtest &> /dev/null; then
log_info "使用 Ookla speedtest..."
if speedtest --accept-license --simple; then
return 0
fi
fi
if command -v speedtest-cli &> /dev/null; then
log_info "使用 speedtest-cli..."
local result
result=$(speedtest-cli --simple 2>/dev/null)
if [ $? -eq 0 ] && [ -n "$result" ]; then
echo "$result" | while IFS= read -r line; do
case $line in
Ping:*)
local ping_value=$(echo "$line" | awk '{print $2 " " $3}')
log_result "🔄 网络延迟: $ping_value"
;;
Download:*)
local download_value=$(echo "$line" | awk '{print $2 " " $3}')
log_result "⬇️ 下载速度: $download_value"
;;
Upload:*)
local upload_value=$(echo "$line" | awk '{print $2 " " $3}')
log_result "⬆️ 上传速度: $upload_value"
;;
esac
done
return 0
fi
fi
# 备用测速方法
test_speed_backup
}
# 备用测速方法
test_speed_backup() {
log_info "使用备用方法测速..."
# 使用 cachefly 的测速节点
local test_urls=(
"http://cachefly.cachefly.net/100mb.test"
"http://speedtest.ftp.otenet.gr/files/test100Mb.db"
)
for url in "${test_urls[@]}"; do
log_info "尝试节点: $(basename "$url")"
if curl -I --connect-timeout 5 "$url" &> /dev/null; then
local start_time end_time download_time speed_mbps
start_time=$(date +%s.%N)
if curl -L --max-time 30 --progress-bar -o /dev/null "$url" &> /dev/null; then
end_time=$(date +%s.%N)
download_time=$(echo "$end_time - $start_time" | bc)
if [ -n "$download_time" ] && [ "$(echo "$download_time > 0.1" | bc -l)" -eq 1 ]; then
speed_mbps=$(echo "scale=2; (100 * 8) / $download_time" | bc)
log_result "⬇️ 下载速度: ${speed_mbps} Mbit/s"
# 估算上传速度
local upload_speed=$(echo "scale=2; $speed_mbps * 0.4" | bc)
log_result "⬆️ 上传速度: ${upload_speed} Mbit/s (估算值)"
return 0
fi
fi
fi
done
log_warning "备用测速方法失败"
return 1
}
# 网络接口信息
show_network_info() {
log_info "收集网络信息..."
# IP 地址信息
log_info "IP 地址信息:"
ip -4 addr show | grep inet | awk '{print " " $2}' | head -5
# 默认网关
log_info "默认网关:"
ip route | grep default | awk '{print " " $3}'
# DNS 服务器
log_info "DNS 服务器:"
if [ -f /etc/resolv.conf ]; then
grep nameserver /etc/resolv.conf | awk '{print " " $2}'
fi
}
# 路由追踪
test_traceroute() {
if [ "$QUICK_MODE" = "true" ]; then
return 0
fi
log_info "进行路由追踪..."
if command -v traceroute &> /dev/null; then
traceroute -m 8 -w 2 223.5.5.5 | head -12
else
log_warning "traceroute 不可用"
fi
}
# 清理函数
cleanup() {
log_debug "清理临时文件..."
rm -f /tmp/speedtest*.tmp
rm -f speedtest-cli 2>/dev/null
}
# 显示帮助信息
show_help() {
echo "使用方法: $0 [选项]"
echo
echo "选项:"
echo " -h, --help 显示此帮助信息"
echo " -v, --version 显示版本信息"
echo " -q, --quick 快速模式(跳过路由追踪)"
echo " -f, --full 完整模式(包含详细诊断)"
echo " -y, --yes 自动确认所有提示"
echo " -d, --debug 调试模式"
echo
echo "示例:"
echo " $0 # 标准模式"
echo " $0 -q # 快速模式"
echo " $0 -y # 自动确认"
}
# 显示版本信息
show_version() {
echo "$SCRIPT_NAME v$SCRIPT_VERSION"
echo "适用于 Debian/Ubuntu 系统的网络测速工具"
}
# 参数解析
parse_arguments() {
QUICK_MODE="false"
AUTO_INSTALL="false"
DEBUG="false"
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-v|--version)
show_version
exit 0
;;
-q|--quick)
QUICK_MODE="true"
shift
;;
-f|--full)
QUICK_MODE="false"
shift
;;
-y|--yes)
AUTO_INSTALL="true"
shift
;;
-d|--debug)
DEBUG="true"
shift
;;
*)
log_error "未知参数: $1"
show_help
exit 1
;;
esac
done
}
# 主函数
main() {
# 解析参数
parse_arguments "$@"
# 显示标题
show_header
# 设置错误处理
set -e
trap 'cleanup; log_error "脚本执行中断"; exit 130' INT TERM
trap 'cleanup' EXIT
# 系统检查
check_system
# 安装必要工具
if ! install_required_tools; then
log_error "工具安装失败"
exit 1
fi
# 安装 speedtest
install_speedtest
# 测试网络连通性
if ! test_connectivity; then
log_error "网络连接测试失败,请检查网络设置"
exit 1
fi
echo ""
# 显示网络信息
show_network_info
echo ""
# DNS 测试
test_dns
echo ""
# 延迟测试
test_latency
echo ""
# 专业测速
if ! test_speed_professional; then
log_warning "专业测速失败"
fi
echo ""
# 路由追踪
if [ "$QUICK_MODE" = "false" ]; then
test_traceroute
fi
echo ""
log_success "网络测速完成"
# 显示使用建议
echo ""
log_info "提示:"
echo " - 使用 '$0 -q' 进行快速测速"
echo " - 使用 '$0 -y' 自动确认所有提示"
echo " - 定期运行以监控网络质量"
}
# 脚本入口
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi