Skip to content
claude ~ claude-code/42-env-vars— 19 min read

42 · 环境变量:藏在背后那排「总开关」

📚 系列导航:上一篇 41 并行任务 教你怎么把活儿拆开、让多个 Claude 同时开跑。这一篇钻到水面下——那些控制 Claude Code 怎么连模型、超时多久、要不要上报数据的「总开关」,全靠环境变量拨。它不在哪个菜单里,藏在你的 shell 和 settings.json 里,今天把这排开关认全、拨明白。

都说环境变量是「高阶玩家才碰的东西」,说句实话——这话害了不少人。

太多人连模型、配代理、调超时,全靠每次开会话手动 /model 点一遍、手动改一遍,改完下次开新会话又得重来。问起为啥不一次配死,答案多半是「环境变量听着好硬核,怕搞坏」。

可你回头看看前面四十一篇——第 04 篇配 API key、第 05 篇接国产模型、第 19 篇管上下文、第 21 篇关遥测……这些事的底层,几乎全是同一套机制在兜底:环境变量。 你早就在用了,只是没人把它们摊开摆在一起讲。

这么说吧:环境变量不是「高阶才碰」,而是**「一次拨好、终身受益」的那排总开关**。怕它,纯粹是因为没人告诉你哪几个开关常用、拨错了顶多什么后果。今天就把这层窗户纸捅破。

看完这一篇,你会拿到:

  • 一句话讲明白环境变量在 Claude Code 里到底管什么、为什么值得花十分钟搞懂
  • 三种设置方式(shell 临时 / shell 配置文件持久 / settings.jsonenv 字段)分别什么时候用,一张表说清
  • settings.json 那四类文件各管多大范围、哪个进 git 哪个不进——直接接上第 31 篇
  • 一份「最该认识的环境变量」清单:连接、超时、隐私、配置目录,带默认值和踩坑提示
  • 当同一件事既能用环境变量又能用设置字段时,到底谁说了算(优先级规则)
  • 一个能照着跑、给了预期输出的实战:亲手设一个变量并验证它真的生效了

01 先搞懂:环境变量在 Claude Code 里到底管什么

先给结论:环境变量是 Claude Code 启动时读的一组「键值对开关」,用来定它怎么连模型、怎么认证、超时多久、要不要上报数据这些底层行为。

你前面用的那些功能——/model 换模型、claude mcp add 接服务、/config 调设置——大多是「会话里临时拨一下」。但有些行为,你希望每次启动都按你的来,不用每回手动设:比如「我永远走自建代理的地址」「我所有请求超时都给我放宽到 20 分钟」「我这台机器绝不上报任何遥测」。这些「定下来就别变」的底层规矩,就是环境变量管的。

官方一句话给它定了性:

环境变量可以控制 Claude Code 的行为,例如模型选择、身份验证、请求路由和功能切换。

类比:咖啡机上的预设按钮。 一台带预设的咖啡机,你可以每次现调——水量多少、浓度几档、要不要加奶,按一杯调一次;也可以把常喝的那杯存成「我的预设」,以后一键出杯,机器自己记着参数。 环境变量就是后者:它把那些你「每次都想这么来」的设置固化下来,Claude Code 一启动就照着读,省得你回回手动拨。

落到真实场景,你大概率会在这几种时候想起它:

  • 「我接了 DeepSeek,不想每次都手动指模型」——把模型和地址写进环境变量(第 05 篇那套,底层就是它)
  • 「公司网络慢,默认 10 分钟超时老不够」——一个变量把超时放宽
  • 「这台是公司机器,合规要求一律不上报遥测」——一个变量直接关掉(第 21 篇提过)
  • 「我有工作和个人两个账号,想分开互不干扰」——一个变量切换配置目录

看出来没?这些全是「设一次,长期生效」的需求。 环境变量就是为这类需求生的。

💡 一句话总结:环境变量是 Claude Code 启动时读的一组「键值对总开关」,管连接、认证、超时、隐私这些底层行为;它的价值在于把「每次都想这么来」的设置一次固化,不用回回手动拨


02 在哪设:三种方式,从「就这一次」到「永远生效」

知道了它管什么,接下来最实在的问题——到底在哪儿设? 答案是三个地方,差别就一条线:这次设的,影响多久、影响谁。

官方把这条线讲得很干脆:

在 shell 中设置的变量仅在该终端会话期间有效,而在设置文件中的变量在每次运行 claude 时都适用。

我把三种方式按「生效范围从窄到宽」排开,你对着选:

方式一:shell 里临时设(就管这一个终端)

在启动 claude 之前,在终端里 export 一下。只对当前这个终端窗口有效,关掉就没了。

macOS / Linux / WSL:

bash
export API_TIMEOUT_MS="1200000"
claude

Windows PowerShell:

powershell
$env:API_TIMEOUT_MS = "1200000"
claude

这种适合**「我就想这一次试试」**——临时放宽个超时、临时换个地址,跑完关掉终端,啥也没留下。

方式二:写进 shell 配置文件(这台机器每次都生效)

如果你想每开一个终端都自动带上,把那行 export 加进你的 shell 配置文件。Mac 上默认是 ~/.zshrc,很多 Linux 是 ~/.bashrc

bash
# 加到 ~/.zshrc 末尾
export API_TIMEOUT_MS="1200000"

存盘后开新终端(或 source ~/.zshrc)就生效。这是「我这台机器上,所有项目、所有终端都这么来」的做法。

Windows 上要持久化,用 setx API_TIMEOUT_MS "1200000"(CMD)或 [Environment]::SetEnvironmentVariable("API_TIMEOUT_MS", "1200000", "User")(PowerShell),然后开一个新终端才生效。

方式三:写进 settings.json 的 env 字段(跟着配置走,跟启动方式无关)

第三种,也是最常用的——写进 settings.json 里的 env 键。官方说得很清楚它的好处:

Claude Code 在启动时直接从文件读取它们,因此无论如何启动 claude,它们都会生效。

json
{
  "env": {
    "API_TIMEOUT_MS": "1200000",
    "BASH_DEFAULT_TIMEOUT_MS": "300000"
  }
}

这个文件路径和写法,第 31 篇讲 settings.json 时已经铺过底了。这里你只要记住:env 是它专门留给环境变量的那个口子,把变量写这儿,跟你怎么敲 claude 无关,它都读得到。

三种方式并排一看就清楚该怎么选:

设置方式生效范围关掉终端还在吗最适合
shell 临时 export仅当前终端❌ 没了「就想这一次试试」
写进 ~/.zshrc这台机器所有终端✅ 在「我个人机器全局这么来」
写进 settings.jsonenv跟着该配置文件作用范围走✅ 在「跟项目/团队绑定,谁启动都生效」

一个顺手的习惯:临时验证一个变量管不管用,用 shell export 试;确认要长期用,就挪进 settings.jsonenv 为啥偏爱 settings.json 而不是 ~/.zshrc?因为下一节那张「文件分级」表——settings.json 能让你精确控制「这个变量是只给我、还是全团队、还是只这个项目」,~/.zshrc 做不到这种区分。

💡 一句话总结:三种设置方式按生效范围排开——shell 临时 export(就这一次)、写进 ~/.zshrc(本机全局)、写进 settings.jsonenv(跟配置走、跟启动方式无关);临时试探用第一种,长期生效推荐第三种。


03 settings.json 的四类文件:谁能管到、哪个进 git

上一节说 settings.jsonenv 是我最推荐的口子,但这里有个新手必踩的坑settings.json 不止一个文件,它有四类,写进不同的文件,这个变量管的「人」完全不一样。

这事第 31 篇专门拆过,这里就环境变量的角度再钉一遍——因为放错文件的后果很真实:你以为只给自己设的代理地址,一不小心提交进了 git,全团队都被你带跑偏了

类比:公司报销标准贴公告栏 vs 你自己记在便签。 财务把「打车 50 封顶」打印出来贴在公告栏,全公司都得照办,这是公开规矩;你自己嫌麻烦,在工位便签上写「这个月我自费的咖啡别报」,这是只管你自己的私人备注。环境变量写进哪个文件,就是在选「贴公告栏」还是「记便签」。

官方给的这张表,直接告诉你每类文件「管到谁」:

文件适用于
~/.claude/settings.json你,在每个项目中
.claude/settings.json在项目中工作的每个人,检入源代码控制
.claude/settings.local.json你,仅在此项目中,未检入
托管设置你组织中的每个人,由管理员部署

翻成大白话,四句话记住:

  • ~/.claude/settings.json——在你家目录下,「我自己,所有项目都这么来」。你个人偏好放这儿。
  • .claude/settings.json(项目根)——「这个项目里所有人都这么来」,而且它进 git,队友拉下来就带上。团队统一的规矩放这儿。
  • .claude/settings.local.json(项目根)——「只有我,只在这个项目」,而且它不进 git.local 后缀默认被忽略)。带私人凭据、只属于你的临时设置放这儿。
  • 托管设置——管理员给全组织统一下发的,你一般改不了,也轮不到你设。

这里有个不大不小的跟头很容易栽。接自建网关时,图省事把 ANTHROPIC_BASE_URL 连同一个带个人 token 的地址写进项目根的 .claude/settings.json,然后顺手 git commit——推之前要是没扫一眼 diff,就麻烦了:那玩意儿一旦推上去,等于把私有地址(还可能带凭据)公开给了所有能看到这个仓库的人。 所以有条铁律记死:凡是带「个人专属」性质的变量(私有地址、个人配置目录这种),一律进 .local 那个不上 git 的文件;只有「全队都该一样」的,才往 .claude/settings.json 里放。

这个变量的性质该写进哪个文件
我个人偏好,所有项目通用~/.claude/settings.json(家目录)
全队统一,要随项目共享.claude/settings.json(进 git)
我私人的、带凭据的、只这个项目.claude/settings.local.json(❌ 不进 git)

💡 一句话总结:settings.json 分四类文件,写进哪个决定这变量管「谁」——家目录管自己全局、项目根 settings.json 进 git 管全队、.local 不进 git 只管自己;带个人凭据的变量,死活别往进 git 的文件里放。


04 最该认识的那几个变量:连接、超时、隐私、目录

官方那张环境变量表,说实话,长得吓人——上百个,从 AWS Bedrock 到 OpenTelemetry 导出器,绝大多数你这辈子都用不上。所以这一节我不堆清单,只挑小白真实会碰到的那十来个,按用途分四组,每个给你说清「干啥的、默认多少、什么时候动它」。

一组:连接与认证(怎么连上模型)

这组是前面第 04、05 篇的底层。三个核心:

bash
ANTHROPIC_API_KEY      # 你的 API 密钥
ANTHROPIC_BASE_URL     # 把请求改道到代理或网关
ANTHROPIC_MODEL        # 默认用哪个模型
  • ANTHROPIC_API_KEY——你的 API 密钥。这里有个特别容易踩的点,官方写得明明白白:一旦设了这个 key,即使你已经登录了订阅(Pro / Max / Team / Enterprise),也会改用这个 key。想换回订阅,得 unset ANTHROPIC_API_KEY 把它清掉。**注意:交互模式下,Claude Code 会弹一次确认提示,让你批准或拒绝用这个 key,选择记住后续自动沿用;非交互模式(-p)则直接使用,不弹确认。**这个坑很容易踩——明明开了 Max 订阅,账单却走了 API 计费,查半天才发现是 ~/.zshrc 里残留了一行 export ANTHROPIC_API_KEY(第 04 篇详谈了订阅 vs API key 怎么选)。

  • ANTHROPIC_BASE_URL——把 API 请求改道到你的代理或网关。接国产模型、走自建中转,核心就是它(第 05 篇那套配置,主角就是这个变量)。

  • ANTHROPIC_MODEL——指定默认模型。注意它的优先级:--model 标志和会话里的 /model 命令会盖过它(下一节细讲)。

二组:超时(嫌它太快放弃就调这个)

网络慢、或者走代理绕远路时,最常调的就是超时。两个最常用:

变量管什么默认值
API_TIMEOUT_MS单次 API 请求的超时600000(10 分钟)
BASH_DEFAULT_TIMEOUT_MS长跑 bash 命令的默认超时120000(2 分钟)
  • API_TIMEOUT_MS——API 请求多久算超时。官方提示:网络慢或走代理时把它调大。但别瞎填——它有个上限 2147483647超过这个数会让底层计时器溢出,请求直接秒失败(手抖多打个 0 是常见情形,结果每次请求瞬间报错,排查半天才发现是溢出)。

  • BASH_DEFAULT_TIMEOUT_MS——Claude 跑那种长命令(比如装依赖、跑构建)默认给多久。默认 2 分钟,跑大型构建不够时调它。

三组:隐私与遥测(合规/强隐私场景)

第 21 篇讲安全时点过的几个,这组管「往外发不发数据」:

bash
DISABLE_TELEMETRY=1      # 关掉遥测上报
DO_NOT_TRACK=1           # 同上,跨工具通用的约定
  • DISABLE_TELEMETRY——设成 1 退出遥测。官方明确说遥测数据不含你的代码、文件路径或 bash 命令;但合规要求严的环境,设上它图个干净。
  • DO_NOT_TRACK——设成 1等同于 DISABLE_TELEMETRY。这是个被很多开发者 CLI 共同遵守的跨工具约定,你设过一次,好些工具都认。

还有个一键全关的——CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1,官方说它等同于同时设了 DISABLE_AUTOUPDATERDISABLE_FEEDBACK_COMMANDDISABLE_ERROR_REPORTINGDISABLE_TELEMETRY。强隐私 / 隔离环境一个变量全关掉,省事。

四组:多账号与上下文(进阶但好用)

两个高频、强烈推荐你认识的:

  • CLAUDE_CONFIG_DIR——覆盖配置目录(默认 ~/.claude)。所有设置、凭证、会话历史、插件都存这底下。它最大的用处是并行跑多个账号——官方给的例子就很实用:
bash
# 给工作账号开个独立配置目录,互不干扰
alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'

工作号和个人号就可以这么分:平时 claude 走个人配置,敲 claude-work 走另一套完全隔离的设置和登录态,两边的历史、凭证、MCP 配置井水不犯河水

  • DISABLE_AUTO_COMPACT——设成 1 关掉「接近上下文上限时的自动压缩」(第 19 篇讲过 auto-compact 这个机制)。手动 /compact 仍然能用。想完全自己掌控什么时候压缩,才设它——多数人保持默认即可。

⚠️ 一句重要提醒:官方说得很死——Claude Code 只在「启动时」读环境变量。所以你改完任何变量(无论改 shell 还是改 settings.json),都得退出 claude 重开,新值才生效。改完没反应,十有八九是没重启。

💡 一句话总结:真正常碰的就四组——连接认证(ANTHROPIC_API_KEY/BASE_URL/MODEL)、超时(API_TIMEOUT_MS 默认 10 分钟)、隐私(DISABLE_TELEMETRY/DO_NOT_TRACK)、多账号(CLAUDE_CONFIG_DIR;改完务必重启 claude 才生效。


05 优先级:同一件事好几个地方都能设,到底谁说了算

学到这儿你会冒出一个很自然的疑问:模型既能用 ANTHROPIC_MODEL 设、又能用 /model 命令选、还能在 settings.json 里写 model 字段——三个都设了,听谁的?

这就是「优先级(precedence)」要回答的事。不搞清它,你会遇到「我明明设了啊怎么没用」的灵异现象。

先记住官方给的第一条总纲——环境变量 > 设置字段

当相同的行为同时具有环境变量和设置字段时,环境变量优先。例如,ANTHROPIC_MODEL 覆盖 model 设置。当环境变量未设置时,设置字段适用。

类比:老板当面那句话,压过员工手册。 员工手册(settings.json 的字段)白纸黑字写着「报销打车 50 封顶」;可老板今天当面跟你说「这趟远,你打车实报实销」(环境变量)——这一趟你当然听老板当面那句的。环境变量就是那句「当面交代」,比手册里写死的字段更优先。等老板没特别交代时(环境变量没设),才回去按手册(设置字段)办。

但这里有个反直觉的拐点,新手最容易栽:不是所有东西环境变量都压得住。 模型这件事,官方专门点了名:

--model/model 覆盖 ANTHROPIC_MODEL

也就是说,模型这条链是这样的:

text
/model 命令 / --model 标志   ←  最优先(你当场的选择)
        ↓ 盖过
ANTHROPIC_MODEL 环境变量      ←  其次
        ↓ 盖过
settings.json 的 model 字段   ←  兜底

为啥模型这儿反过来了?其实很合理——你在会话里手动 /model 切一下,是「我现在就想用这个」的明确当场意图,它当然该压过你之前设死的那个环境变量。 这跟「老板当面那句压过手册」是同一个逻辑:越「当场、越明确」的指令,优先级越高。

配置方式相对优先级一句话
/model 命令 / --model 标志最高你会话里/启动时当场的明确选择
ANTHROPIC_MODEL 环境变量你预先设死的默认
settings.jsonmodel 字段兜底都没设时才用

注意:这个「命令/标志盖过环境变量」是模型这类配置的规矩,不是放之四海皆准。官方原话提醒不同功能交互方式不一样——比如 CLAUDE_CODE_EFFORT_LEVEL 反而会覆盖 /effort 命令。所以拿不准某个具体变量时,回官方那张变量表查它那一行的说明,别想当然。

这条很容易栽一次:在 settings.json 里写死了 ANTHROPIC_MODEL,结果某次会话里随手 /model 切了个别的,切完就忘了——下半场一直在用临时切的那个,还纳闷怎么跟配置的不一样。其实道理很直白:/model 当场选的,本来就该压过预设的环境变量。这不是 bug,是设计。

💡 一句话总结:总纲是环境变量 > 设置字段(老板当面话压过员工手册);但模型这类有例外——/model/--model 这种「当场明确指令」反过来压过 ANTHROPIC_MODEL;规律是「越当场越明确,优先级越高」,拿不准就查官方那行说明。


06 动手:设一个变量,亲手验证它真的生效了

光看不练,环境变量这东西永远隔层纱。下面带你走一遍最小闭环:设一个变量 → 进会话 → 确认它真生效了。全程不依赖你任何已有的复杂配置,几分钟搞定。

我们拿 BASH_DEFAULT_TIMEOUT_MS(bash 命令默认超时)来练——选它是因为它安全、可观察、改错了也不影响连接

第一步:先看默认状态(在终端,启动 claude 之前)

什么都别设,直接开一个会话:

bash
claude

进去后,让它跑一句话,问它当前的 bash 超时:

text
我现在的 bash 命令默认超时是多少毫秒?读一下你环境里的 BASH_DEFAULT_TIMEOUT_MS,没设的话就说默认值

预期:它会告诉你这个变量没显式设置,走默认 120000(2 分钟)。记住这个基线值,等会儿对照。然后退出会话(敲 /exit 或 Ctrl+C 两下)。

第二步:用 shell 临时设一个值,再开会话

回到终端,临时 export 一个不一样的值(设成 5 分钟),紧接着开会话:

bash
export BASH_DEFAULT_TIMEOUT_MS="300000"
claude

Windows PowerShell 用:$env:BASH_DEFAULT_TIMEOUT_MS = "300000" 然后 claude

进去后,问同样的问题

text
我现在的 bash 命令默认超时是多少毫秒?

预期:这次它该读到 300000(5 分钟),而不是默认的 120000看到值从 120000 变成了 300000 = 你的临时设置真的被读进去了。 这就验证了「方式一:shell 临时设」确实管用。

第三步:验证「关掉终端就没了」

退出会话,完全关掉这个终端窗口,重新开一个新的,直接 claude(这次什么都不 export),再问一遍同样的问题。

预期:又变回 120000(默认值)。因为 export 只对那个已经关掉的终端有效——这就亲眼印证了第 02 节那条「shell 临时设,关掉终端就没了」。

第四步(可选):写进 settings.json,让它持久

如果你想让这个值长期生效、跟启动方式无关,把它写进 settings.json。最稳妥是写进只属于你、不上 git 的那个文件:

json
{
  "env": {
    "BASH_DEFAULT_TIMEOUT_MS": "300000"
  }
}

写进 .claude/settings.local.json(当前项目根、不进 git),或 ~/.claude/settings.json(你的家目录、所有项目通用),按你想要的范围选——参考第 03 节那张表。

存盘后,新开终端、直接 claude(不 export),再问一遍——这次该稳定读到 300000 了,而且无论你以后怎么启动 claude,它都在。这就是「方式三:写进 settings.json」相比 shell 临时设的好处:一次写好,不用回回 export。

跑完这四步,你就把环境变量「设 → 验证生效 → 验证范围 → 持久化」整条链路亲手走了一遍。以后设任何变量,本质都是这套:先临时试管不管用,确认了再挪进 settings.json 固化。

💡 一句话总结:验证一个变量生不生效,最稳的办法就是「问 Claude 它读到的值」;先 shell 临时 export 试探(关终端就没)、确认管用再写进 settings.json 持久化——亲手走一遍这条链路,环境变量就再也不玄了。


07 小结

这一篇我们钻到水面下,把控制 Claude Code 底层行为的那排「总开关」——环境变量——认全、拨明白了。

归纳一下,整篇讲的核心就五件事:它管什么、在哪设、写进哪个文件、常用的那几个长啥样、多处都设了听谁的。一张表串起来:

你要搞清的事答案关键点
环境变量管啥连接、认证、超时、隐私这些底层行为启动时读的键值对开关,「设一次长期生效」
在哪设shell 临时 / ~/.zshrc / settings.jsonenv按生效范围选,长期用推荐 settings.json
写进哪个 settings 文件家目录 / 项目根(进 git) / .local(不进 git)带凭据的别进 git
最常用哪几个ANTHROPIC_*API_TIMEOUT_MSDISABLE_TELEMETRYCLAUDE_CONFIG_DIR各有默认值,改完重启才生效
多处都设了听谁的环境变量 > 设置字段;但 /model 压过 ANTHROPIC_MODEL越当场越明确,优先级越高

你现在应该能: 看懂环境变量在 Claude Code 里到底管什么、知道三种设置方式各自的生效范围、清楚 settings.json 四类文件谁进 git 谁不进、认识连接/超时/隐私/多账号这几组最常用的变量、并且想明白当同一件事多处都能设时该听谁的。更重要的是——你亲手设了一个变量、验证了它真生效、还看到了「关掉终端就没」和「写进文件就持久」的区别。 这层窗户纸一旦捅破,环境变量就从「高阶玄学」变成了你随手能拨的开关。

回到开头那句话:环境变量从来不是「高阶才碰」,而是「一次拨好、终身受益」。 你前面四十一篇里那些「每次都得手动设一遍」的别扭,现在多半都能用一个变量一劳永逸地解决了。


下一篇 43「Git 工作流」——环境变量帮你把 Claude Code 的底层行为安顿明白了,接下来该让它真正融进你每天的开发节奏。说到开发,绕不开的就是 Git:让 Claude 帮你写提交信息、理清 diff、开 PR、处理冲突……它在 Git 这块到底能帮到哪一步、又有哪些坑得你自己盯着?下一篇好好聊聊。想想看:你愿意让 AI 替你 git commit,但 git push 到生产分支这一下,你敢撒手吗?