linux网络脚本需主动设限、分层判断、明确退出码:用timeout包裹命令防挂起,按物理可达→端口开放→服务响应逐级验证,依据不同退出码精准区分故障类型,并实施带退避与上限的自动重试。

Linux 脚本处理网络超时与连接失败,核心是**不依赖单一命令的默认行为,而是主动设限、分层判断、明确退出码**。光靠 curl 或 ping 默认执行容易卡住或掩盖真实问题,必须用超时控制 + 状态检查 + 错误分支来兜底。
用 timeout 包裹所有网络命令
这是最直接有效的防线。Linux 自带的 timeout 命令可强制终止任何耗时过长的操作,避免脚本挂起:
-
timeout 5 ping -c 1 8.8.8.8—— 5 秒内没收到响应就退出,返回非零码 -
timeout 10 curl -f --connect-timeout 3 --max-time 7 http://api.example.com—— 同时限制连接建立(3s)和整体请求(7s),-f确保 HTTP 非2xx也报错 - 搭配
||捕获失败:if timeout 8 nc -zv example.com 443; then echo "端口通"; else echo "连接失败"; fi
根据退出码区分失败类型
不同错误对应不同原因,不能一概当作“网络不通”:
-
ping退出码 1:目标主机不可达(路由/防火墙问题) -
curl退出码 7:无法连接到服务器(端口未监听或被拦截) -
curl退出码 28:连接超时(--connect-timeout触发) -
nc退出码 1:连接被拒绝(ECONNREFUSED,服务没起来或 bind 错了地址) - 统一写法:
case $? in 0) ... ;; 1|7|28) handle_network_error ;; *) handle_unexpected ;; esac
组合诊断:从链路层到应用层逐级验证
单点测试易误判,应按“物理可达 → 端口开放 → 服务响应”顺序推进:
- 先
timeout 3 ping -c 1 $HOST &>/dev/null确认 ICMP 可达 - 再
timeout 3 nc -z $HOST $PORT测试 TCP 连通性(绕过 DNS 和 HTTP) - 最后
timeout 5 curl -sSf http://$HOST:$PORT/health验证服务逻辑正常 - 任一环节失败,立即中断并记录具体哪步失败,避免无效重试
自动重试需带退避与上限
临时抖动可重试,但必须防雪崩:
- 简单重试:
for i in {1..3}; do if timeout 5 curl -f http://x; then break; fi; sleep $((i * 2)); done - 更稳妥用
--retry(curl 内置):curl --retry 3 --retry-delay 2 --retry-all-errors,它能重试 DNS、连接、超时等多数错误 - 关键原则:重试间隔递增(如 1s→3s→9s),总尝试不超过 3–5 次,失败后明确退出而非无限循环











