先分清两件事:系统代理 ≠ 终端自动走代理
在 macOS 上,Clash 系图形客户端常见的「系统代理」开关,会把 HTTP/HTTPS 代理参数写入系统网络偏好,从而让 Safari、Chrome 等遵循系统代理的应用走本地代理端口(例如常见的 127.0.0.1:7890)。这一步对浏览器通常立竿见影,但对 Terminal 里的命令来说,并不保证任何效果。
原因很简单:命令行工具默认不会去读「系统偏好设置 → 网络 → 代理」那一套,而是看当前进程环境里有没有 http_proxy、HTTPS_PROXY、ALL_PROXY 等变量,或者工具自己的配置文件(如 Git 的 http.proxy)。因此你会看到一种典型分裂:菜单栏显示 Clash 已开启,网页畅通,而 brew update 或 git clone 依然慢得像直连。这不是订阅坏了,而是流量出口路径根本没被命令行接到 Clash 上。
第一步:确认你正在用哪个 Shell、哪份配置文件
从 macOS Catalina 起,默认登录 Shell 多为 zsh。若你仍使用 bash,或从某些 IDE 内置终端启动,加载的配置文件顺序会不同。同一条 export 写在错误的文件里,就会出现「开了一个终端有代理、另一个没有」的错觉。
建议先在新开的 Terminal 窗口执行 echo $SHELL 与 echo $0,确认当前解释器。对 zsh 而言,交互式登录会话通常会读 ~/.zprofile 与 ~/.zshrc(具体组合与是否 login shell 有关);若你使用 iTerm2、Warp、Kitty 等,还要确认它们是否以 login shell 启动。排查时不要假设「我改过 .zshrc 就一定生效」,用 source ~/.zshrc 或重开窗口后再 env | grep -i proxy 验证。
.zshrc。这类场景需要单独设置环境变量或使用绝对路径调用带代理前缀的命令。第二步:该设置哪些代理环境变量?
最常见的组合是同时导出 HTTP 与 HTTPS 指向 Clash 的混合端口(或分别的 HTTP/SOCKS 端口,视客户端与订阅而定):http_proxy、https_proxy,以及部分工具会认大写形式 HTTP_PROXY、HTTPS_PROXY。有的程序只读大写,有的只读小写,为减少玄学问题,实践中常成对写入两套,或至少在排错时两组都检查一遍。
涉及非 HTTP 协议或希望「一把梭」覆盖更多工具时,会用到 ALL_PROXY,通常填 socks5://127.0.0.1:7891 这类 SOCKS 地址(端口以你本机 Clash 显示为准)。注意:ALL_PROXY 并不 magically 让所有软件变聪明;例如 npm、pip、ssh 各自还有额外开关。但对 curl、不少 Ruby/Python 库、以及部分下载器,ALL_PROXY 往往能减少「只设了 HTTP 却走了 HTTPS URL」的遗漏。
在终端里可先用下面思路自检(把端口换成你的实际监听端口):
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export ALL_PROXY=socks5://127.0.0.1:7891
curl -I https://www.google.com
若加上 export 后 curl 明显变快或返回正常,而去掉后又恢复直连,即可断定问题在环境变量未持久化或未加载,而不是 Clash 内核本身。
第三步:检查 NO_PROXY / no_proxy 是否把目标「豁免」了
很多公司内网、Docker、Kubernetes、私有 Git 域名会被写进 NO_PROXY 或 no_proxy。当目标主机名或 IP 命中例外列表时,工具会刻意不走代理。若你从别处复制了一长串 NO_PROXY,里面可能含有过于宽泛的条目(例如误写的通配),就会导致「明明开了代理,特定域名仍直连」——有时这正是你想要的(局域网加速),有时却是配置错误。
排错时请打印变量: echo $NO_PROXY,并对照你要访问的域名是否在列表中。对需要强制走代理的场景,可临时在子 shell 里 unset NO_PROXY no_proxy 再试,以判断问题是否由例外引起。
第四步:Homebrew、Git、curl 各自还要注意什么?
Homebrew 在安装与更新时会发起大量 HTTPS 请求。仅系统代理往往不够;通常需要上述环境变量在运行 brew 的 shell 中已生效。若仍异常,可检查是否配置了公司 SSL 检查、自定义 curlrc、或网络中间件改写证书。
Git 除环境变量外,还可能读取 git config --global http.proxy。若历史上设过错误代理,会覆盖你对环境变量的预期。用 git config --global --get http.proxy 查看;不需要时 git config --global --unset http.proxy。SSH 协议的 [email protected]: 仓库不走 HTTP 代理环境变量,需要 ProxyCommand 或改用 HTTPS 远端。
curl 支持 --proxy 参数,也读环境变量。若你使用了 ~/.curlrc,其中可能写死了 proxy = "" 或其它值,导致与环境变量表现不一致。
第五步:利用 Clash GUI 的「复制终端代理命令」
多数 Mihomo 系桌面客户端在菜单或设置里提供「复制环境变量」「终端代理」一类功能,会生成一段可直接粘贴进 shell 的 export 语句。务必核对端口与协议是否与你当前模式一致:有的配置 HTTP 与 SOCKS 分开监听,有的使用单一 mixed 端口。复制后建议立刻用 curl -I 或客户端自带「连接测试」交叉验证。
把这段 export 固化进 ~/.zshrc 时,注意文件末尾是否有条件判断(例如「仅在某网络下启用」)。条件写错会导致你一直以为「配置写了」,实际从未执行到那一段。
什么时候该考虑 TUN,而不是死磕环境变量?
环境变量方案的本质是:让每个工具自觉把流量送到 Clash 端口。这对大多数开源 CLI 足够,但总有个别二进制完全忽略代理。若你希望终端与图形程序、游戏等行为更一致,减少「漏网之鱼」,可以在权限允许的前提下启用 TUN 模式,由系统路由把流量交给内核侧虚拟网卡,再由 Clash 按规则分流。这与本文主题互补:一个管「变量与 Shell」,一个管「路由层统一接管」。更系统的说明见本站《Clash TUN 模式完全指南》。
对照排查表(建议按顺序打勾)
| 步骤 | 检查项 | 期望结果 |
|---|---|---|
| 1 | Clash 是否监听本机预期端口(HTTP/SOCKS/mixed) | 客户端日志或状态页无报错,本机 nc -vz 127.0.0.1 端口 可通 |
| 2 | 当前 shell 与将加载的 rc 文件 | 修改的是正在使用的 zsh/bash 对应文件,重开终端后变量仍在 |
| 3 | http_proxy / HTTPS_PROXY / ALL_PROXY |
env | grep -i proxy 输出与 Clash 端口一致,大小写覆盖目标工具习惯 |
| 4 | NO_PROXY 例外 |
目标域名未被误加入例外;需要代理时已临时排除干扰 |
| 5 | Git / brew / curl 单独配置 | 无陈旧 git config、无冲突 .curlrc |
小结
macOS 上 Clash 图形界面显示「已代理」,只说明系统层或部分应用收到了代理建议;终端是否走代理,取决于当前进程是否携带正确的环境变量、以及各工具自身配置是否覆盖。按本文顺序确认 Shell、变量、NO_PROXY 与单工具设置后,大多数「brew/git/curl 仍直连」的问题都能定位到具体环节,而无需盲目更换节点或重装客户端。
若你希望客户端版本与本地端口、内核能力一致,减少「界面显示开了、实际端口未监听」的错配,可从本站客户端下载页获取当前平台安装包,并结合使用文档核对混合端口与 SOCKS 端口说明。相比零散渠道,统一来源能降低版本与文档不对齐带来的隐性成本。
相比仅依赖系统代理,显式配置终端环境变量或启用 TUN 后,命令行与图形应用的行为更容易对齐;在稳定性与易用性上,Mihomo 系 Clash 生态也提供了较成熟的规则与模式组合。若你尚未选定客户端,不妨从本站获取适配 macOS 的版本,再按本文步骤做一次完整验证。