Mac 用户迟早会遇到这个分裂时刻:浏览器里 Google 秒开,切到终端 brew install 却卡到超时。原因很简单——图形界面的系统代理和终端是两套世界,终端里的命令行工具默认根本不走代理。这篇把终端走代理的原理和设置一次讲透。
插图来源:Storyset
核心原理:环境变量#
大多数命令行工具(curl、wget、git、brew、npm、pip)都认三个环境变量:
http_proxy=http://127.0.0.1:7890
https_proxy=http://127.0.0.1:7890
all_proxy=socks5://127.0.0.1:7890后面的地址和端口是你代理客户端的本地监听地址。Clash 系客户端默认一般是 127.0.0.1:7890(HTTP)和 127.0.0.1:7891(SOCKS5),具体以你客户端设置里显示的为准,不要照抄,先去客户端里确认。
临时生效:只管当前窗口#
在终端里直接执行:
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:7890关闭这个终端窗口就失效。适合临时用一次的场景。取消也很简单:unset http_proxy https_proxy all_proxy。
永久生效:写入 shell 配置文件#
想每次打开终端自动生效,把上面三行写进 shell 的配置文件:
- 用 zsh(macOS 默认):
~/.zshrc - 用 bash:
~/.bash_profile
# 代理设置
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:7890
export no_proxy="localhost,127.0.0.1,*.local"注意 no_proxy 这一行:本地回环地址不要走代理,否则可能引发奇怪的问题。写完后执行 source ~/.zshrc 让它立即生效。
验证:三招确认真的走了代理#
- curl 看 IP:
curl -s ipinfo.io或curl -s ifconfig.me,返回的 IP 应该是代理节点的 IP; - git 测试:
git ls-remote https://github.com能正常返回引用说明通了; - brew 测试:
brew update不再超时。
如果 curl 通但 git 不通,检查 git 自己的代理配置:git config --global http.proxy 是否和环境变量冲突,冲突时以 git 自身配置优先。
进阶:按需开关#
不想终端永远走代理?写两个 alias 放进 ~/.zshrc:
alias proxyon='export http_proxy=http://127.0.0.1:7890 https_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890'
alias proxyoff='unset http_proxy https_proxy all_proxy'之后在终端里敲 proxyon / proxyoff 一键切换,哪个终端窗口需要代理就开哪个,互不干扰。配合这篇食用更佳:Mac 上用快捷键一键切换代理。
常用工具的代理配置差异#
环境变量是通用方案,但有些工具有自己的代理设置,优先级高于环境变量:
- git:
git config --global http.proxy http://127.0.0.1:7890,取消用--unset。如果和环境变量冲突,以 git 自身配置为准; - npm:
npm config set proxy http://127.0.0.1:7890,yarn/pnpm 类似; - brew:认环境变量,但偶尔会清环境,
sudo -E可以保留; - ssh:走
~/.ssh/config里配ProxyCommand,和环境变量无关; - docker:Docker Desktop 在设置里单独配代理,终端环境变量管不到它。
建议:日常用环境变量一把梭,遇到某个工具不通再去查它自己的代理配置,八成是"自有配置覆盖了环境变量"。
常见坑#
- 端口写错:每个客户端的监听端口可能不同,复制前先看客户端设置页;
- 大小写:有些工具只认小写
http_proxy,有些只认大写HTTP_PROXY,图省事可以大小写各 export 一套; - sudo 不继承:
sudo默认不继承用户环境变量,sudo -E才能带上代理。