快速修复
# 一键:四种变量全设小写+大写,并配好 NO_PROXY(在 ~/.bashrc 里加这几行)
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.1,.local
# 验证:确认真的走代理了(看请求耗时/出口 IP,或临时把代理指向死端口看是否报错)
env | grep -i proxy # 四种变量 + NO_PROXY 都在
curl -I --max-time 5 https://example.com # 成功且不超时 = 代理生效
验证技巧:临时 http_proxy=http://127.0.0.1:1 curl https://example.com——报代理连接失败 = 代理变量生效(变量被读了);不报错 = 变量没被这个工具读(大小写不对)。你会遇到什么
你在 .bashrc 里 export HTTP_PROXY=http://127.0.0.1:7890,结果 curl 还是直连超时、git 还是慢、pip install 还是报错——明明设了代理,有的命令就是不听话。更迷惑的是:同一个代理变量,pip 走了、curl 不走,或反过来。
本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。
为什么会这样
不同工具对代理环境变量的读取契约不一样,这是「有的走有的不走」的机制根因:curl 故意忽略大写 HTTP_PROXY(CGI 环境下大写变量可能被外部注入、可被恶意设置的旧安全设计),只认小写 http_proxy/https_proxy,HTTPS_PROXY 大写生效是官方唯一特批;pip/git 认大写(也认小写);
npm 以 npm config get proxy 配置优先。
NO_PROXY 是第二契约:匹配的域名/地址直接绕过代理,缺了它本地请求会被塞进代理。确定性验证路径是「死端口反向验证」:把代理临时指向不存在的端口(如 http://127.0.0.1:1),报连接失败 = 该工具确实读了变量;不报错 = 大小写不对/该工具不读这个写法——比看日志快得多。
不同的工具对代理环境变量的「大小写敏感度」不一样,这是所有混乱的根源(2026-09-01 本机实测,curl 8.18 / pip 25.1):
- curl 只认小写
http_proxy/https_proxy:它故意忽略大写HTTP_PROXY(安全设计——CGI 环境里大写变量可能被外部注入,防止代理被恶意设置)。HTTPS_PROXY是大写却生效的唯一特例(curl 官方特批)。 - pip 认大写
HTTP_PROXY/HTTPS_PROXY(也认小写)。 - git 认大写(也认小写
http.proxy配置项)。 - npm 认小写 + 大写都有,但以
npm config get proxy配置优先。
所以「export 一个大写 HTTP_PROXY」时:pip 走了代理,curl 无视它直连——这就是「有的走有的不走」的直接原因。
第二个坑是 NO_PROXY:设了代理后本地/内网请求(localhost、公司内网、127.0.0.1)也可能被塞进代理导致失败,需要 NO_PROXY=localhost,127.0.0.1,内网域名 显式绕过(实测:http_proxy=死端口 + NO_PROXY=127.0.0.1 时 curl 直连成功,去掉 NO_PROXY 立即失败)。
一步步来
1. 先确认代理端口真的在监听 — 必做
ss -ltn | grep 7890(或你代理软件的端口)。代理软件没起,设啥变量都没用。
2. 逐工具验证 — 必做
http_proxy=http://127.0.0.1:1 curl -s --max-time 3 http://example.com; echo "curl: $?"
HTTP_PROXY=http://127.0.0.1:1 pip3 download --no-deps -d /tmp/t six; echo "pip: $?"
curl 返回非 0 = 小写生效;pip 失败 = 大写生效。
3. git 单独查 — 必做
git config --global --get http.proxy——git 除了环境变量还认 http.proxy 配置,两者都有时配置优先。
4. 代理只对部分域名生效 — 必做
公司/校园网代理常有白名单:用 NO_PROXY 排除内网,用 ALL_PROXY(socks5 场景)兜底。
5. 容器/服务里不继承 — 必做
Docker 容器默认不继承宿主代理环境变量,需要 docker run -e http_proxy=... 或 compose environment: 显式传。
怎么确认修好了
# 1. 环境变量四件套 + NO_PROXY 都在
env | grep -i proxy
# 2. 真实请求成功且快(走代理 vs 直连的耗时差异一眼可见)
curl -o /dev/null -s -w 'time=%{time_total}s
' --max-time 8 https://example.com
# 3. 反向验证(代理真的被读取):指向死端口应立刻失败
http_proxy=http://127.0.0.1:1 curl -s -o /dev/null --max-time 3 http://example.com && echo "BAD: 没走代理" || echo "OK: 代理变量生效"
其它环境的表现
| 环境 | 表现 | |
|---|---|---|
| Windows(PowerShell) | 大小写不敏感,$env:HTTP_PROXY 与 $env:http_proxy 等价;curl.exe / git 行为与 WSL 一致(curl.exe 同样忽略大写 HTTP_PROXY) | |
| macOS | 与 Linux 完全一致(curl 同款安全设计) | |
| 代理软件自带系统代理 | Clash/V2Ray「系统代理」改的是系统级设置(Windows 代理开关//etc/environment),不写 shell 环境变量——`env | grep proxy` 为空是正常,命令走系统代理不依赖变量 |
症状
设了代理环境变量但表现不一致的典型形态:
curl仍然直连超时/失败,而pip install却能走通——同一个变量,有的命令听、有的不听;- 只
export HTTP_PROXY=...(大写)时curl完全无视,git/pip却生效; - 设了代理后
localhost、127.0.0.1、内网请求反而失败——被代理截走(NO_PROXY 缺失); - 容器/服务里设了变量却依旧直连——环境变量没被传进容器。
同族但别在本页死磕:报错明确指向「代理服务器拒绝连接」时,先确认代理软件本身在监听(ss -ltn),再回来看变量大小写。
原因
不同工具对代理环境变量的「大小写敏感度」不一样:curl 故意忽略大写 HTTP_PROXY(CGI 环境下大写变量可能被外部注入的安全设计,HTTPS_PROXY 是唯一特批生效的大写),只认小写 http_proxy/https_proxy;pip/git 认大写(也认小写);npm 以 npm config get proxy 配置优先。所以「只设一个大写 HTTP_PROXY」时,curl 直连、pip 走代理——「有的走有的不走」是设计使然,不是配置写错。第二个坑是 NO_PROXY 缺失:本地/内网请求被塞进代理导致失败。
解法
- 四件套全设 + NO_PROXY(一键命令见「快速修复」):小写+大写四个变量都 export,并配
NO_PROXY=localhost,127.0.0.1,.local——覆盖所有工具的大小写偏好,一劳永逸。 - 逐工具反向验证(见「快速修复」):临时指向死端口,报错 = 变量被读;不报错 = 这个工具不认这个写法。
- git 单独查:
git config --global --get http.proxy——git 除了环境变量还认http.proxy配置,两者都有时配置优先。 - 容器/服务显式传:Docker 默认不继承宿主变量,
docker run -e或 composeenvironment:补上。 - 系统代理模式不冲突:Clash/V2Ray 的「系统代理」不写 shell 变量,
env | grep proxy为空属正常,不用重复设。
验证证据
- 2026-09-01 本机实测(WSL Ubuntu 26.04,curl 8.18 / pip 25.1):
实测复现日志(2026-09-01) - 基线直连 127.0.0.1:8089 → 200;大写
HTTP_PROXY=死端口下 curl 仍 200(忽略大写,实锤); - 小写
http_proxy=死端口→ curl 000(小写生效,实锤); HTTPS_PROXY=死端口+ https 目标 → 000(HTTPS_PROXY 大写生效,实锤);http_proxy=死端口 + NO_PROXY=127.0.0.1→ 200(NO_PROXY 绕过,实锤);- pip 在大写 HTTP_PROXY=死端口下报
Could not find a version(pip 认大写,实锤);加NO_PROXY=pypi.org后下载成功。
适用工具 (1)
本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。
curl · 外部工具来源与证据
← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡