networksetup 是 macos 切换代理最可靠的原生命令,直接操作网络服务配置、无需第三方工具且重启生效;需动态识别活跃服务名、正确设置 bypass 列表并刷新系统缓存以确保生效。

networksetup 命令切换代理预设最可靠
macOS 原生不支持“代理预设”概念,但 networksetup 可直接读写当前网络服务(如 Wi-Fi、Ethernet)的代理配置,是唯一无需第三方工具、不触发隐私弹窗、且系统重启后仍生效的方案。
常见错误是试图修改 ~/Library/Preferences/com.apple.systempreferences.plist 或用 AppleScript 模拟点击——前者权限受限、易被 SIP 阻断;后者在 macOS Sonoma+ 上常因辅助功能授权失效而卡住。
-
networksetup -setwebproxy "Wi-Fi" 127.0.0.1 8080开启 HTTP 代理(服务名需与networksetup -listallnetworkservices输出一致) -
networksetup -setwebproxystate "Wi-Fi" off关闭代理,比清空地址+端口更稳妥 - 若使用 PAC,用
-setautoproxyurl+-setautoproxystate,URL 必须是本地 file:// 或 http:// 地址,https:// 不被信任
Shell 脚本封装代理开关要处理服务名动态识别
硬编码 “Wi-Fi” 在 MacBook 接网线或使用 iPhone USB 共享时会失败。必须先检测当前活跃服务,否则脚本静默失效。
典型场景:公司内网走全局代理,回家自动关代理——不能只靠网络名称判断,得结合路由表或 DNS。
- 用
route -n get default 2>/dev/null | grep 'interface:' | awk '{print $2}'获取当前出口接口名 - 再用
networksetup -listnetworkserviceorder | awk -F'\) ' '/^ \([0-9]+\. [^ ]+/{print $2}' | grep -E '^(Wi-Fi|Ethernet|iPhone.*USB)$'映射到网络服务名 - 务必加
sudo权限检查:脚本开头跑networksetup -getwebproxy "Wi-Fi" 2>/dev/null || { echo "需要 sudo 权限"; exit 1; }
绕过本地地址和公司域名必须手动填 bypass 列表
GUI 中勾选的 “Bypass proxy settings for these Hosts & Domains” 对应 networksetup -setwebproxy 的 -exceptionslist 参数,但命令行不支持通配符或域名自动补全。
容易踩的坑是漏掉 .local、192.168.0.0/16、10.0.0.0/8 这些 macOS 内置绕过项——它们不会出现在 networksetup -getwebproxy 输出里,但 GUI 修改后会保留。
- 设置时用
networksetup -setproxybypassdomains "Wi-Fi" "localhost" "127.0.0.1" ".local" "192.168.0.0/16" - 注意:空格分隔,不能用逗号;
.local前的点必须保留;CIDR 格式仅部分 macOS 版本支持,稳妥起见拆成192.168.*和10.* - 每次调用
-setproxybypassdomains会**完全覆盖**原有列表,不是追加
脚本执行后代理不生效?检查 networkservice 状态和系统缓存
执行完 networksetup 命令,终端里看返回值是 0 并不等于 GUI 已刷新——Safari、Chrome 可能仍用旧配置,因为它们读取的是 CFNetwork 缓存。
这不是脚本问题,而是 macOS 网络栈设计:配置写入成功,但应用层需主动 reload 或等待几秒。
- 强制刷新系统网络状态:
sudo ifconfig $(route -n get default 2>/dev/null | grep 'interface:' | awk '{print $2}') down && sudo ifconfig $(route -n get default 2>/dev/null | grep 'interface:' | awk '{print $2}') up(慎用,会断连 1–2 秒) - 更温和的做法是发通知:
killall -HUP mDNSResponder清 DNS 缓存,对多数代理场景已足够 - 验证是否生效:运行
curl -I http://httpbin.org/ip --proxy http://127.0.0.1:8080 2>/dev/null | head -1,别只信networksetup -getwebproxy的输出
复杂点在于,不同 macOS 版本对 networksetup 的异常处理不一致——Monterey 会静默忽略无效端口,Ventura 则报错;绕过列表在 Sonoma 上对 CIDR 支持变严格。这些细节不试一遍根本不知道。










