结论:应优先使用 nmcli 管理网络连接,而非手动执行 ip route 或 ifconfig;因为 nmcli 能自动同步路由、dns、dhcp 和 ipv6 状态,避免冲突、断连或配置回滚。

直接说结论:别手动改 route 或 ifconfig,优先用 nmcli 管理连接配置,否则容易路由冲突、DNS 失效、甚至断连后无法恢复。
为什么不能直接用 ip route 切换网口
很多人一上来就写脚本反复执行 ip route del default 和 ip route add default via ... dev eth0,结果是:路由表看似切换了,但 DNS 不走新接口、DHCP 租约没更新、NetworkManager 后台还在“抢”控制权——最终表现是 ping 得通但 curl 打不开网页,或者切完几分钟后自动回滚。
根本原因是:ip route 只操作内核路由表,不通知 NetworkManager,也不刷新 resolv.conf、不重载 DHCP 客户端状态。它适合调试或临时救急,不适合长期自动切换。
- NetworkManager 默认会覆盖你手动加的 default 路由(尤其在 DHCP 场景下)
- 不同网口可能对应不同 DNS 服务器,手动切路由不会同步更新
/etc/resolv.conf - 如果两个网口在同一子网(比如都接 192.168.1.0/24),
ip route无法自动处理冲突,得自己删光旧子网路由再加,极易漏项
nmcli connection up 是最稳妥的切换方式
NetworkManager 把每个物理网口 + 网络配置组合封装成一个「connection」,比如 Wired-eth0-chinaunicom 和 Wired-eth1-cnctel。切换本质是激活一个 connection,停用另一个——它会自动处理路由、DNS、DHCP 续租、IPv6 RA 等全套逻辑。
实操步骤:
- 先列出所有已定义连接:
nmcli connection show,确认名字(不是设备名eth0,而是 connection 名) - 查当前激活的连接:
nmcli connection show --active - 停用当前连接:
nmcli connection down "Wired-eth0-chinaunicom" - 启用目标连接:
nmcli connection up "Wired-eth1-cnctel" - 验证:
ip route | grep default+cat /etc/resolv.conf+ping -c2 114.114.114.114
注意:connection 名含空格时必须加引号;首次配置 connection 请用 nmcli connection add 或图形界面保存,不要只改 /etc/network/interfaces ——那套已被 NetworkManager 忽略。
双网口同时在线时,默认路由怎么选
如果你希望 eth0 和 eth1 都 up,但只让某一个承担默认流量(比如 eth0 主线、eth1 备线),靠 connection 的 autoconnect-priority 参数控制,而不是靠脚本轮询。
设置方法:
- 给主连接设高优先级:
nmcli connection modify "Wired-eth0-chinaunicom" connection.autoconnect-priority 100 - 给备用连接设低优先级:
nmcli connection modify "Wired-eth1-cnctel" connection.autoconnect-priority 50 - 确保两者都开启 autoconnect:
nmcli connection modify "X" connection.autoconnect yes - 重启 NetworkManager:
sudo systemctl restart NetworkManager
这样当 eth0 断开时,NetworkManager 会在几秒内自动 failover 到 eth1;eth0 恢复后,也会自动切回——整个过程无需外部脚本,且 DNS、MTU、IPv6 全部同步生效。
真要写检测切换脚本,只该监控 connection 状态
如果你的场景必须用脚本(比如 NetworkManager 被禁用、或嵌入式系统没装它),那检测点和操作点必须一致:检测 nmcli device status 或 ip link show eth0 | grep "state UP",操作也只用 nmcli 或 ip link set + dhclient 组合,别混用工具链。
常见坑:
- 用
ping 网关判断线路好坏,但网关本身可能 ICMP 屏蔽——更可靠的是curl -s --connect-timeout 3 http://114.114.114.114/dns-query(测 DNS 连通性) - 脚本里用
route add却忘了删旧路由,导致多条 default 路由并存,Linux 按 metric 选但 metric 值可能混乱 - 没加锁机制,多个实例并发运行,互相覆盖路由表
真正稳定的切换不在命令多快,而在状态收敛是否干净——NetworkManager 做的就是这件事。手写脚本只是在重复造轮子,还造得不圆。











