Bash 종료 코드 127: 회귀 버그와 당일 패치
종료 코드 127은 'command not found'를 의미하는 POSIX 셸 규약입니다. v2.1.147에서 회귀 버그가 발생해 Bash 도구가 모든 호출에서 127을 반환하게 됐습니다 — 대상 바이너리가 없을 때뿐 아니라 명령이 무엇을 하든 상관없이 . Anthropic은 회귀가 확인된 당일, 단일 변경 핫픽스인 v2.1.148을 배포했습니다. 수정 사항을 다음 콘텐츠 배포에 묶지 않고 독립적으로 분리한 것입니다. 전용 포인트 릴리스를 발행한 결정은 도구 실행 무결성이 차단 우려 사항으로 취급된다는 신호입니다 — 다음 콘텐츠 주기를 기다리지 않는다는 뜻이기도 합니다.
여기서 영향 범위가 중요합니다. Bash는 Claude Code의 에이전트 작업 흐름에서 가장 많이 호출되는 도구입니다. 테스트 실행, 파일 읽기, 빌드 파이프라인, 패키지 설치, 조건부 로직이 모두 이를 거칩니다. 도구가 127을 반환하면 모델은 결과를 "command not found"로 해석하고 복구 경로를 택할 수 있습니다 — 다른 바이너리 경로로 재시도하거나, 누락된 도구 설치를 시도하거나, 단계를 완전히 포기하는 식으로. 기반 명령이 정상적으로 실행됐을 때 이 경로들은 모두 옳지 않습니다. 실제 원인을 가리키는 표면적 오류 신호 없이 의미론적으로 잘못된 동작을 만들어낼 뿐입니다.
"Bash 도구가 종료 코드 127(command not found)을 잘못 반환하던 문제 수정 — 이전 버전의 회귀 버그." — Claude Code Changelog, v2.1.148
단일 변경 핫픽스 방식은 버전이 고정된 배포 환경의 운영자에게도 이점이 있습니다. 업그레이드 대상이 명확합니다: v2.1.148로 올리기만 하면 다른 것은 바뀌지 않습니다. 수정 사항이 새 기능과 함께 묶였다면 운영자들은 회귀를 해소하기 위해 무관한 변경 사항까지 수용해야 했을 것입니다 — Claude Code의 릴리스 프로세스가 도구 실행 버그에 대해 명시적으로 피하는 트레이드오프입니다.
v2.1.147 기간에 자동화 파이프라인이 실행됐다면 , 폴백 브랜치를 촉발한 예상치 못한 127 반환이 있는지 작업 로그를 감사하십시오. 잘못된 command-not-found 오류에 대응해 실행된 복구 코드 — 재시도, 대체 설치 경로, 단계 건너뛰기 로직 — 를 검토해야 합니다. 이 기간의 성공적인 출력은 신뢰할 수 있지만, 복구 경로의 출력은 그렇지 않습니다.
v2.1.149의 권한 레이어 보안 수정 4건
5월 22일 두 번째 릴리스인 v2.1.149는 Claude Code의 Bash 및 PowerShell 권한 레이어에서 네 가지 취약점을 해결했습니다. 모두 공통 패턴을 공유합니다: 규칙 엔진은 호출 시점에 명령을 검사했지만, 대체 호출 형식과 셸 상태 변수는 동일한 검사를 받지 않았습니다 . 이를 합치면 에이전트 세션 내 스크립트가 작업 디렉터리를 변경하거나 운영자의 허용 규칙이 강제하려던 경계 밖의 실행 파일을 호출할 수 있는 의미 있는 우회 표면을 이룹니다. macOS 전용 별도 수정도 대형 디렉터리 트리에서 find가 시스템 vnode 테이블을 소진할 수 있는 사례를 해결했습니다 — 자세한 내용은 Claude Code 공식 체인지로그에서 확인할 수 있습니다.
| 취약점 | 구성요소 | 공격 벡터 | 적용된 수정 |
|---|---|---|---|
| cd 우회 | Bash / PowerShell | cd.., cd\, cd~, X: (Windows 드라이브 문자)가 허용 규칙 감지를 트리거하지 않고 디렉터리를 변경 |
이제 모든 대체 cd 형식이 실행 전 허용 규칙과 대조됨 |
| Git 워크트리 샌드박스 잘못된 설정 | Git 통합 | 공유 .git 디렉터리 경계가 전체 리포지터리 루트로 설정됨 — git 내부만이 아닌 추적된 모든 파일에 접근 가능 |
경계가 .git 내부 디렉터리만 노출하도록 수정됨 |
| 접두사 / 와일드카드 허용 규칙 공백 | 권한 레이어 | 와일드카드 규칙으로 적용된 네이티브 실행 파일이 호출 시점에 여전히 명시적 재승인을 요구함 | 이제 와일드카드 규칙이 명시적 승인 없이 일치하는 네이티브 바이너리를 사전 승인함 |
| PWD / OLDPWD / DIRSTACK 추적 공백 | 셸 상태 추적기 | pushd / popd 시퀀스로 추적된 작업 디렉터리가 오래된 상태로 남겨짐 — 스크립트가 허용된 하위 트리 밖을 감지되지 않고 탐색할 수 있었음 |
cd, pushd, popd 전반에서 동기화가 유지되도록 변수 추적이 확장됨 |
macOS vnode 소진 (find) |
macOS 도구 바인딩 | 대형 디렉터리 트리에서 find가 시스템 vnode 테이블을 소진 |
이제 macOS에서 find 호출이 제한됨 |
"여러 보안 문제 수정: cd 우회 변형(cd.., cd\, cd~, X: 드라이브 문자 형식), 전체 리포지터리 루트를 노출하는 git 워크트리 샌드박스 잘못된 설정, 네이티브 실행 파일을 사전 승인하지 않는 와일드카드 허용 규칙, pushd/popd 시퀀스에서의 PWD/OLDPWD/DIRSTACK 추적." — Claude Code Changelog, v2.1.149
cd 우회는 네 가지 중 가장 광범위하게 적용되는 취약점입니다. Windows에서 드라이브 문자 접두사(C:, D:)는 cd C:\의 유효한 대체 형식이며, Unix에서는 공백 없는 cd..이 일부 셸에서 파싱됩니다. 허용 규칙이 경로 접두사 매칭을 사용한다면, 스크립트가 인식되지 않은 호출 형식을 사용해 범위 밖 디렉터리로 이동하고, 재검사를 트리거하지 않고 그곳에서 작업한 뒤 돌아왔을 수 있습니다 — 경계가 침범됐다는 흔적을 권한 감사 추적에 남기지 않은 채로 .
git 워크트리 잘못된 설정은 워크트리를 경량 작업공간 격리로 활용하는 팀에게 별도의 주의가 필요합니다. 샌드박스의 의도는 에이전트를 작업 트리로 제한하면서 전체 리포지터리 루트 — .git/ 아래의 설정 파일, 훅, 자격증명, 커밋 기록 — 를 접근 가능한 경계 밖에 두는 것입니다. 잘못된 설정은 이를 역전시켰습니다: 경계가 .git 디렉터리 자체가 아닌 리포지터리 루트로 설정됐습니다. v2.1.147에서 v2.1.149 사이에 git 워크트리 샌드박스를 사용한 모든 에이전트 세션은 운영자가 의도한 것보다 더 넓은 파일시스템 접근권을 가졌습니다.
PWD/OLDPWD/DIRSTACK 공백은 샌드박스 강제 적용에서의 검사 시점 대 사용 시점 불일치입니다. 스크립트가 pushd /allowed/path를 호출한 뒤 popd를 호출하면, 추적기는 모든 상태 전환 시 업데이트해야 합니다. popd에서 업데이트에 실패하면, 추적기는 허용된 경로를 표시하는 동안 셸의 실제 현재 디렉터리는 다른 곳으로 이동해 있을 수 있습니다. 수정은 추적기를 항상 셸의 자체 디렉터리 스택과 동기화 상태로 유지합니다.
/code-review --fix: 제안에서 직접 파일 편집으로
v2.1.152에서 도입된 /code-review --fix 는 이 명령어를 단순 조언 도구에서 직접 편집기로 바꿉니다. 이전에는 /code-review가 작업 트리를 분석해 재사용 기회, 단순화 대상, 효율 개선 지점을 찾아 텍스트로 출력하면 개발자가 직접 변경 사항을 적용했습니다. --fix를 사용하면 분석과 편집이 한 번에 이루어집니다. 별도의 확인 단계나 쓰기 전 diff 미리보기 없이 결과가 즉시 작업 트리에 반영됩니다.
"재사용, 단순화, 효율" 결과는 Claude Code의 분석 과정에서 각각 구체적인 의미를 가집니다. 재사용 결과는 공유 함수나 상수로 추출할 수 있는 중복 로직을 식별합니다. 단순화 결과는 불필요하게 복잡한 표현, 중복 조건, 의미적 이점 없이 장황한 패턴을 대상으로 합니다. 효율 결과는 불필요한 루프, 캐싱 가능한 반복 조회, 합칠 수 있는 데이터 변환 등 구조적 문제를 다룹니다. --fix를 사용하면 세 가지 카테고리가 작업 트리에 단일 변경으로 동시에 적용됩니다.
"
/code-review --fix는 이제 재사용, 단순화, 효율 결과를 작업 트리에 직접 적용합니다./simplify는 내부적으로/code-review --fix를 호출하도록 업데이트되어 — 두 명령어는 이제 동일한 편집 결과를 만들어냅니다." — Claude Code Releases, v2.1.152
/simplify 재연결은 이 명령어를 일상적으로 사용하는 개발자에게 가장 중요한 동작 변화입니다. v2.1.152 이전에는 /simplify와 /code-review --fix가 각각 독립된 구현을 가진 별개의 명령어 경로였습니다. v2.1.152부터 /simplify는 내부적으로 /code-review --fix를 호출합니다. 지금까지 /simplify를 조언 도구로 사용해왔다면 — 제안을 확인한 뒤 적용 여부를 결정하는 방식 — 해당 워크플로우는 더 이상 유효하지 않습니다. 두 명령어 모두 호출 즉시 파일을 수정합니다.
자동 포맷팅되거나 생성된 코드는 특별히 주의가 필요합니다. 단순화 휴리스틱과 포맷터 규칙이 충돌할 수 있기 때문입니다. 멀티라인 표현을 축약하는 휴리스틱이 프로젝트에 설정된 줄 길이 제약을 위반하면, 다음 CI 실행 시 gofmt, prettier, black이 실패하는 상태가 될 수 있습니다. 가장 안전한 워크플로우는 /code-review --fix 또는 /simplify 실행 후 즉시 포맷터를 실행하고, 스테이징 전에 통합된 diff를 검토하는 것입니다. --fix 없이 /code-review를 실행하면 여전히 조언 전용 출력만 생성됩니다 — 적용 여부를 결정하기 전에 제안을 검토해야 하는 개발자를 위한 기본 동작은 변경되지 않았습니다.
CI에서 스타일 검사를 강제하는 프로젝트라면, Claude Code 세션 이후 포맷터를 재실행하는 pre-commit 훅을 추가하면 단순화 편집이 첫 lint 검사에서 실패하는 풀 리퀘스트로 이어질 위험을 줄일 수 있습니다. 이 패턴은 커밋 이력도 일관되게 유지해줍니다. 단순화 편집과 포맷터 수정이 함께 스테이징되므로, 스타일 회귀가 나중에 발생하더라도 bisection이 수월합니다.



