[Claude Code 스킬] 환경 변수 — settings.json의 env로 CLI 기본 동작 바꾸기 | DAKER 커뮤니티
무엇
환경 변수는 Claude Code의 기판 뒷면 딥스위치입니다. 슬래시 커맨드와 /config가 앞면의 손잡이라면, 환경 변수는 타임아웃·재시도 횟수·동시 실행 수·인증 경로·렌더링 방식처럼 UI로는 노출되지 않는 동작을 직접 건드립니다. 공식 문서에 정리된 변수만 200개가 넘고, settings.json의 env 블록에 적어 두면 claude를 어떤 방식으로 띄우든 항상 적용됩니다.
중요한 성질 하나. 셸에서 export한 값은 그 터미널 세션 하나에만 살아 있고 다음 claude 실행 때부터 반영되지만, 설정 파일의 env 값은 파일을 저장하는 순간 실행 중인 세션에도 반영됩니다 (OpenTelemetry처럼 시작 시 한 번만 읽는 기능은 예외).
언제 쓰나
느린 빌드·테스트가 2분에 잘릴 때 —
BASH_DEFAULT_TIMEOUT_MS,BASH_MAX_TIMEOUT_MS,BASH_MAX_OUTPUT_LENGTH사내 프록시·LLM 게이트웨이 뒤에서 쓸 때 —
ANTHROPIC_BASE_URL,API_TIMEOUT_MS,CLAUDE_CODE_CERT_STORE,ANTHROPIC_CUSTOM_HEADERSCI·이밸·야간 배치처럼 사람이 없는 세션 —
CLAUDE_CODE_RETRY_WATCHDOG,CLAUDE_CODE_MAX_TURNS,CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS팀 전원에게 같은 조건을 강제할 때 —
.claude/settings.json을 커밋 (조직 차원이면 managed settings)설정이 꼬여 원인을 못 찾을 때 —
CLAUDE_CODE_SAFE_MODE=1로 CLAUDE.md·스킬·플러그인·훅·MCP를 전부 끈 채 한 세션 실행
사용법
같은 목적을 세 가지 층위에서 걸 수 있습니다. 아래로 갈수록 영구적이고 넓게 적용됩니다.
# 1) 이번 터미널에서만 — Bash 도구 타임아웃을 2분 -> 5분으로
export BASH_DEFAULT_TIMEOUT_MS=300000
echo $BASH_DEFAULT_TIMEOUT_MS # 대입문은 아무것도 출력하지 않는다. 반드시 확인할 것
claude
# Windows PowerShell
$env:BASH_DEFAULT_TIMEOUT_MS = "300000"// 2) ~/.claude/settings.json — 실행 방식과 무관하게 항상 적용
{
"env": {
"BASH_DEFAULT_TIMEOUT_MS": "300000", // 느린 빌드/테스트 (기본 120000)
"API_TIMEOUT_MS": "1200000", // 느린 프록시 (기본 600000)
"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "8", // 동시 서브에이전트 (기본 20)
"CLAUDE_CODE_USE_VERTEX": "" // 셸이 export한 낡은 값을 빈 문자열로 무력화
}
}# 3) 무인 CI 세션 프로파일 — 사람이 지켜보지 않는 실행용
export CLAUDE_CODE_RETRY_WATCHDOG=1 # 429/529 용량 에러를 무한 재시도
export CLAUDE_CODE_MAX_TURNS=40 # 폭주 방지 상한 (--max-turns 와 동일)
export CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 # 백그라운드 작업을 끝까지 기다림
export CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1 # 제목 생성용 백그라운드 호출 절약
claude -p "실패한 테스트의 원인을 찾아 고쳐줘"누가 누구를 덮어쓰는가
여기가 사람들이 가장 많이 헛발질하는 지점입니다. 규칙은 하나가 아니라 세 갈래입니다. 기본은 환경 변수가 설정 키를 이긴다이지만, --model과 /model은 거꾸로 ANTHROPIC_MODEL을 이깁니다. 반대로 CLAUDE_CODE_EFFORT_LEVEL은 /effort를 이깁니다. 즉 ‘커맨드가 항상 이긴다’는 직관은 틀렸고, 변수마다 문서에 명시된 대로 갈립니다.
셸과 설정 파일에 같은 변수를 두면 설정 파일이 이깁니다. Claude Code가 시작 시점과 파일 변경 시점에 env 항목을 프로세스 환경에 덮어쓰기 때문입니다. 그리고 설정 파일 사이에서는 managed settings가 사용자·프로젝트 설정을 덮어씁니다.
손대기 전에 알아야 할 기본값
값을 올리기 전에 원래 눈금이 어디인지 아는 편이 안전합니다. 특히 BASH_DEFAULT_TIMEOUT_MS(2분)와 stdio MCP 서버의 idle 타임아웃(30분)은 체감 차이가 커서, 명령이 ‘멈춘 것처럼 보이는’ 상황의 대부분이 이 두 숫자로 설명됩니다.
팁
1) 숫자는 자릿수 그대로 쓰세요. 문서상 2e3(=2000)이나 64_000 같은 표기가 허용되지만, v2.1.211 이전 버전에서는 이런 표기가 조용히 훨씬 작은 값으로 해석되는 버그가 있었습니다. 1e6이 타임아웃 1ms가 되는 식입니다. 또 API_TIMEOUT_MS는 최대 2147483647을 넘기면 내부 타이머가 오버플로되어 요청이 즉시 실패합니다. 넉넉하게 준 값이 오히려 즉사 스위치가 되는 셈입니다. 일부 변수(CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS 등)는 아예 ‘plain digits 양의 정수’만 받고, 잘못된 값은 무시하고 기본값으로 돌아갑니다.
2) ‘0으로 끄기’가 통하지 않는 변수를 조심하세요. CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, DISABLE_TELEMETRY, DISABLE_ERROR_REPORTING 같은 변수는 값이 아니라 ‘설정되었는지 여부’만 봅니다. 0이나 false를 넣어도 기능은 그대로 꺼져 있고, 되살리려면 변수를 unset해야 합니다. 그런데 설정 파일에서는 변수를 지울 수 없습니다. 그래서 공식 우회법이 "CLAUDE_CODE_USE_VERTEX": ""처럼 빈 문자열을 넣는 것입니다. 다만 하위 프로세스는 여전히 빈 값을 상속한다는 점은 기억해 두세요.
3) 과금 경로를 조용히 바꾸는 변수가 있습니다. ANTHROPIC_API_KEY가 설정되어 있으면 로그인 상태여도 구독 대신 그 키로 청구됩니다. 인터랙티브 모드에서는 한 번 확인을 받지만, claude -p에서는 확인 없이 항상 키를 씁니다. 구독으로 돌아가려면 unset ANTHROPIC_API_KEY.