为什么「Clash 已开」,终端与 Homebrew 却仍像直连?

在 macOS 上,这是很多开发者都会踩的坑:菜单栏里的 Clash 客户端显示已连接,Safari 或 Chrome 访问检测站能看到节点出口 IP,可一打开「终端」,跑 curlgit clonebrew update,延迟与出口却仍是本地宽带。于是搜索里会出现「Clash macOS 终端代理」「Homebrew 代理」这类关键词——本质不是订阅坏了,而是图形界面里勾选的「系统代理」并不会自动写进你当前 Shell 的环境变量

macOS 的「网络 → 代理」或 Clash 写入的系统代理,主要影响遵循系统代理栈的应用;而终端里的命令行工具往往直接读 http_proxyhttps_proxyall_proxy 等变量,或各自自带的配置(例如 git 的 http.proxy)。两者不同轨。若你希望同一套 Clash 本地监听端口同时服务浏览器与命令行,就需要把端口对齐,并在 Shell 里显式导出代理环境变量。下文按「概念 → 端口 → 导出 → 验证 → 持久化」顺序给出可复现步骤。

若你更熟悉 Windows,可对照我们另一篇《Clash Windows 11 系统代理不生效》:那边侧重系统代理写入、浏览器与 UWP;本篇侧重 macOS + 终端 + Homebrew,形成平台互补。

系统代理与 Shell 环境变量:不是一回事

简单记:系统代理告诉「会听话」的 App「请把 HTTP(S) 流量送到某地址:端口」;Shell 里的 http_proxy / https_proxy 告诉「会读这些变量」的命令行程序同样的事情。许多 CLI 默认不读 macOS 系统代理,只认环境变量或自己的配置文件,所以你会看到浏览器正常、终端直连的分裂现象。

Clash 系客户端通常在本地开一个混合端口(常见如 7890,具体以你界面为准),同时提供 HTTP 与 SOCKS 入站。命令行侧一般这样对应:

  • HTTP/HTTPS 走 HTTP 代理http_proxyhttps_proxy 常设为 http://127.0.0.1:端口
  • 需要 SOCKS 时all_proxy 可设为 socks5://127.0.0.1:端口(与客户端 SOCKS 监听一致)。

若你刚完成安装与基础配置,请先确认客户端已启动、订阅可用,并记下「混合端口」数字,再往下做——端口抄错一步,后面全部无效。

第一步:在 Clash 客户端确认本地监听端口

以 Clash Verge Rev、ClashX Meta、FlClash 等为例,在设置或概览页找到混合端口 / Mixed Port(或分别列出的 HTTP 端口、SOCKS 端口)。本文以下用 7890 作为占位符,请你替换为自己机器上的实际值

同时确认没有其它代理软件占用同一端口;若端口冲突,先在客户端里改监听端口,再同步修改下文所有环境变量里的端口数字。Clash 日志里若出现大量 address already in use,优先排查端口占用。

ℹ️
仅开「系统代理」不够:若你希望终端默认走代理,仍需在 Shell 中导出 http_proxy 等变量,或改用下文提到的 TUN 模式从更底层接管(见后文链接)。

第二步:在当前终端会话中临时导出代理变量

打开「终端」或 iTerm2,使用 zsh(macOS 默认)或 bash 均可。下面是一段可直接粘贴测试的示例(请将 7890 换成你的混合端口):

# Temporary proxy env for current shell session — replace 7890 with your mixed port
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
export all_proxy="socks5://127.0.0.1:7890"
export ALL_PROXY="$all_proxy"

说明:http_proxyHTTP_PROXY 在部分工具里大小写敏感策略不一,两行同时设可减少踩坑。all_proxy 给需要 SOCKS 或走「全协议」代理的程序使用;若你确认某工具只走 HTTP 代理,可仅保留前三项。

若你使用 fish 或其它 Shell,语法仍是「把同名环境变量设为上述 URL」,仅 export 写法不同,可查对应 Shell 文档。

第三步:验证 curl、git 与网络出口

在同一终端窗口执行:

echo "$http_proxy" "$https_proxy"
curl -I --connect-timeout 10 https://www.google.com

若代理链路正常,curl 应能返回 HTTP 头而不是长时间卡住或直连超时(具体结果受节点与目标站点策略影响)。再试:

git ls-remote https://github.com/git/git.git HEAD

若此前 git 因网络失败,而导出变量后恢复正常,说明git 使用的 HTTP 库已读到代理环境变量。若仍失败,可再检查是否单独设置过 git config --global http.proxy 与之冲突,必要时用 git config --global --unset http.proxy 清除旧值后重试。

也可用 scutil --proxy 观察系统级代理是否与 Clash 一致——但请记住:系统显示正确 ≠ 当前 Shell 已设好环境变量,两步都要各自验证。

第四步:Homebrew(brew)与代理

Homebrew 代理本质是让 brew 底层调用的 curl 能发现代理。通常只要在同一终端里已正确设置 http_proxy / https_proxybrew updatebrew install 即可走 Clash。若仍异常,可检查:

  • 是否在非交互脚本或 launchd 任务里运行 brew,导致未继承你手动 export 的环境;
  • 是否配置了 ~/.curlrc 强制 --proxy 指向错误端口;
  • 公司证书或 MITM 是否与 HTTPS 解密冲突(需单独排查,超出本文范围)。

部分用户会设置 HOMEBREW_CURL_RETRIES 等提高容错,但与「是否走代理」无直接关系;优先保证代理变量与端口正确。

第五步:no_proxy 与国内直连

当你同时希望「国内站点直连、海外走代理」时,可在环境变量里配置 no_proxy,列出不走代理的域名或 IP 段(具体语法因工具而异,常见为逗号分隔列表)。这与 Clash 内的规则分流是两层概念:Clash 决定流量进哪个节点;no_proxy 决定命令行是否尝试经由 HTTP 代理连接。若配置不当,可能出现「Clash 规则正确但 curl 仍绕弯」的困惑,需要两边对照。

更系统的分流设计仍建议以 Clash 配置为准,可结合《Clash 规则分流配置详解》维护规则集与策略组。

第六步:写入 ~/.zshrc 持久生效(可选)

临时 export 只在当前终端会话有效。若希望每次打开终端自动加载,可将同一组 export 追加到 ~/.zshrc(bash 用户常用 ~/.bash_profile),然后执行 source ~/.zshrc 或重开终端。

⚠️
安全提示:全局持久化代理意味着所有在该 Shell 启动的工具默认可能走代理。若你在不可信网络或多人共用账户,请评估是否需要改为按需手动开启,或使用单独脚本切换「代理开 / 关」别名。

备选:不想折腾环境变量时,考虑 TUN 模式

若你希望少配环境变量、让更多程序默认被接管,可在硬件与权限允许的前提下评估 Clash 的 TUN 模式:在更底层转发流量,减少对「每个工具是否读 http_proxy」的依赖。适用场景与注意点见《Clash TUN 模式详解》;与本文的 Shell 导出方案并不冲突,按需求二选一或组合使用即可。

排查清单(简版)

  • 客户端已运行,混合端口与下文环境变量中的端口完全一致
  • 当前终端已 export http_proxy/https_proxy,且 echo 可见非空。
  • curl -I https:// 测试通过或与预期一致;git、brew 在同一终端复测。
  • 无旧版 git proxy.curlrc 错误端口覆盖。
  • 需要分国内直连时,检查 no_proxy 与 Clash 规则是否「各管一层」。

写在最后

Clash macOS 终端代理问题的核心,是分清「系统代理」「Clash 入站端口」与「Shell 里的 http_proxy / https_proxy」三者的关系:前两者保证本机有一个可用的本地代理服务;最后一项让终端里的命令行工具知道要把请求送到哪里。把混合端口对齐、按步骤导出并验证,Homebrew 代理与 git 类操作通常会立刻改观。相比反复重装客户端,按清单自检能更快定位问题。

若你希望使用维护活跃、对 Mihomo 内核兼容友好的发行版,可从我们的客户端下载页获取适合 macOS 的安装包,再结合文档完成基础配置后,回到本文核对端口与环境变量即可。与零散论坛帖相比,固定工具链与可复现实验步骤更利于长期维护。→ 立即免费下载 Clash,开启流畅上网新体验