从路由器到云端:一个Shell脚本搞定Linux公网上下行测速
1. 为什么你需要这个Shell测速脚本?
每次网络卡顿的时候,你是不是也经历过这样的场景?打开网页转圈圈,视频缓冲到天荒地老,远程办公时文件传输慢如蜗牛。作为网络工程师,我经常遇到用户抱怨"网速慢",但真正要定位问题却无从下手。运营商提供的测速工具往往只能测内网速度,而实际公网传输质量才是影响用户体验的关键。
这个Shell脚本最初是我在路由器厂商工作时开发的内部工具。当时我们需要测试不同型号路由器在真实公网环境下的吞吐性能,市面上常见的测速工具要么不够精准,要么无法适配嵌入式设备。经过多次迭代优化,最终形成了这个不足50行的脚本,现在分享给大家。
它的核心优势在于:
- 真实模拟用户场景:直接测试公网服务器上下行速度,而非局域网内虚假的"千兆速率"
- 轻量级无依赖:纯Shell编写,从低配路由器到云服务器都能运行
- 结果直观可量化:精确到小数点后三位的数值,方便对比优化前后的效果
2. 脚本工作原理深度解析
2.1 测速站点的智能选择机制
脚本开头的这段代码是精髓所在:
fasted_site=$(cat /tmp/1.txt | sed 's/https:/\n/g' | sed 's/Url/\n/g' | grep "/hello" | awk -F '","' '{print $1}' | sed 's/\\\//\//g' | awk -F "/" '{print "http://"$3"/hello"}' | xargs curl --connect-timeout 2 -r 0-1048576 -L -w "%{speed_download}--%{http_code}--%{url_effective}--" -s | sort -n | grep "\-\-200--" | grep "\-\-Client" -v | head -1 | awk -F "--" '{print $3}' | awk -F "/" '{print $3}')它实际上完成了三个关键步骤:
- 从speedtest.cn获取当前地理位置最近的测速节点列表
- 对每个节点发起1MB大小的测试请求(-r 0-1048576参数)
- 根据响应时间自动选择最优节点
这种动态选择机制比固定使用某个测速站点更科学。我在深圳办公室测试时,脚本自动选择了广州的节点;而当我在北京家中测试时,它又切换到了天津的服务器。这种智能适配确保了测试结果真实反映本地网络质量。
2.2 下载速度测试的黑科技
下载测试部分使用了curl的隐藏功能:
curl --connect-timeout 10 -m 40 -L -o/dev/null http://$fasted_site/download?size=1000000000这里有几个值得注意的参数:
-o/dev/null表示不保存下载文件size=1000000000请求1GB大小的测试数据(实际不会完整传输)-m 40设置最大操作时间为40秒
脚本会实时分析curl输出的速度统计信息,通过awk计算平均速度。我特别添加了单位自动转换逻辑,无论结果是MB/s还是KB/s都能正确显示。
3. 在不同设备上的实战部署
3.1 OpenWrt路由器的特殊配置
在MT7621芯片的路由器上部署时,我发现需要做这些调整:
- 确保已安装curl和coreutils-timeout:
opkg update opkg install curl coreutils-timeout - 由于路由器存储空间有限,修改临时文件路径:
speed_result=/mnt/sda1/testspeed.txt - 对于低性能设备,减少测试数据量:
# 修改下载测试的size参数 size=100000000 → size=10000000
实测在小米AX3600路由器上运行完整测试约需2分钟,内存占用始终低于10MB。
3.2 云服务器上的优化技巧
在阿里云ECS上使用时,要注意这些特殊情况:
- 部分云厂商会限制出站带宽测试,建议使用
-A "Mozilla/5.0"伪装UA - 对于按流量计费的实例,可以在脚本开头添加:
if [ -f /tmp/last_test_time ] && [ $(expr $(date +%s) - $(cat /tmp/last_test_time)) -lt 3600 ]; then echo "测试间隔小于1小时,跳过本次检测" exit 0 fi date +%s > /tmp/last_test_time - 多地域服务器对比测试时,可以批量执行:
for ip in 47.101.1.1 120.77.2.2 139.199.3.3; do ssh root@$ip "wget -O speedtest.sh https://example.com/speedtest.sh && bash speedtest.sh" done
4. 结果分析与网络优化建议
4.1 如何解读测试数据
脚本输出的结果类似:
download_speed:15.160M upload_speed:15.926M这里需要注意:
- 单位是MB/s(兆字节每秒),换算成常见带宽单位要×8
- 数值波动在±10%内属于正常现象
- 建议在不同时段多次测试取平均值
我整理了一个参考标准:
| 网络类型 | 合格下行速度 | 合格上行速度 |
|---|---|---|
| 家庭宽带100M | ≥8MB/s | ≥1MB/s |
| 企业专线500M | ≥50MB/s | ≥20MB/s |
| 云服务器1Gbps | ≥80MB/s | ≥80MB/s |
4.2 典型问题排查指南
当测试结果异常时,可以这样排查:
速度远低于预期
- 检查
fasted_site变量是否选择了合适的节点 - 运行
traceroute $fasted_site查看路由跳数 - 尝试更换DNS服务器(如8.8.8.8)
- 检查
上传下载速度差异大
- 家庭宽带通常上行带宽较小
- 如果是云服务器,检查安全组规则
结果波动剧烈
- 避免在网络高峰期测试
- 关闭其他占用带宽的应用
最近帮某创业公司排查网络问题时,发现他们的阿里云服务器到深圳办公室速度只有2MB/s。用这个脚本测试后发现是跨运营商传输问题,最终通过部署BGP线路解决了问题。
