Claude Code 가이드 #12 — 파일을 수정할 때마다 lint를 직접 실행하거나, 커밋 후 검증을 잊어서 에러를 뒤늦게 발견한 경험이 있나요. Hooks 시스템을 쓰면 이런 반복 작업을 Claude Code 이벤트에 연결해 자동화할 수 있습니다. Hooks는 Claude Code의 특정 이벤트가 발생할 때 자동으로 실행되는 셸 명령어 입니다. settings.json 에 정의하며, 이벤트 종류에 따라 실행 시점을 제어할 수 있습니다.
Claude Code 가이드 #12 — 파일을 수정할 때마다 lint를 직접 실행하거나, 커밋 후 검증을 잊어서 에러를 뒤늦게 발견한 경험이 있나요? Hooks 시스템을 쓰면 이런 반복 작업을 Claude Code 이벤트에 연결해 자동화할 수 있습니다. 이 편에서는 Hooks의 종류, settings.json 설정법, 그리고 실전 자동화 패턴까지 완전 정리합니다.
⚠️ 막히는 케이스: Hook 명령이 실행되지 않는 경우 — settings.json 구문 오류일 가능성이 높습니다. JSON은 trailing comma를 허용하지 않습니다. node -e "require('./.claude/settings.json')" 명령으로 JSON 파싱 오류를 확인하세요. 또는 hooks 키가 최상위 객체의 바로 아래에 있는지 구조를 점검하세요.
🎓 유데미 강의 추천
Claude Code 실전 강의 — AI 코딩을 지금 시작하세요
설치부터 자동화·에이전트 활용까지, 실무에서 바로 쓰는 Claude Code 활용법을 단계별로 배울 수 있습니다.
Claude Code 가이드 #12 — Hooks로 워크플로우 자동화 — PostToolUse Hook으로 파일 수정 후 자동 구문 검사 실행 흐름 (출처: 공식 문서 기반)
⚠️ 막히는 케이스: Hook 스크립트가 파일 경로를 못 읽는 경우 — CLAUDE_TOOL_INPUT 환경변수는 JSON 문자열입니다. 도구 종류(Write, Edit, Bash 등)에 따라 JSON 구조가 다릅니다. Write 도구는 path 키를, Edit 도구는 file_path 키를 사용합니다. 스크립트에서 두 키를 모두 fallback으로 처리해야 합니다.
실전 Hook 예시 2 — 알림 자동화
Claude가 작업을 완료하거나 입력을 기다릴 때 터미널 소리나 슬랙 알림을 보낼 수 있습니다.
#!/bin/bash
# scripts/hook-notify-slack.sh
# Stop 이벤트 시 슬랙으로 완료 알림
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H 'Content-type: application/json' \
--data '{
"text": "Claude Code 작업이 완료됐습니다.",
"username": "Claude Code",
"icon_emoji": ":robot_face:"
}' > /dev/null
💡 팁:Stop Hook은 Claude가 응답을 완전히 완료했을 때만 실행됩니다. 긴 작업(파일 대량 생성, 코드 리팩토링 등)을 백그라운드에서 실행할 때 완료 알림을 받으면, 다른 작업을 하다가 돌아올 수 있어서 생산성이 높아집니다.
실전 Hook 예시 3 — PreToolUse로 실행 차단
PreToolUse Hook은 도구 실행 전에 실행됩니다. Hook 명령이 exit code 2를 반환하면 해당 도구 실행이 차단됩니다.
이를 이용해 특정 파일이나 명령어를 보호할 수 있습니다.
PreToolUse — 프로덕션 파일 수정 차단
#!/bin/bash
# scripts/hook-guard.sh
# PreToolUse Write|Edit 이벤트에서 호출됨
# 특정 파일(settings.json, .env 등)을 실수로 수정하는 것을 차단
FILE=$(echo "$CLAUDE_TOOL_INPUT" | python3 -c "
import sys, json
try:
d = json.load(sys.stdin)
print(d.get('path') or d.get('file_path') or '')
except:
print('')
")
# 보호할 파일 목록
PROTECTED_FILES=(
".env"
".env.production"
"vercel.json"
)
for protected in "${PROTECTED_FILES[@]}"; do
if [[ "$FILE" == *"$protected"* ]]; then
echo "BLOCKED: $FILE 는 보호된 파일입니다. 직접 수정이 필요하면 수동으로 편집하세요." >&2
exit 2 # exit 2 = 도구 실행 차단
fi
done
exit 0
Claude Code 가이드 #12 — Hooks로 워크플로우 자동화 — PreToolUse Hook exit code 2로 도구 실행 차단 패턴 (출처: 공식 문서 기반)
⚠️ 막히는 케이스:PreToolUse Hook에서 exit 2를 반환했는데 도구가 여전히 실행되는 경우 — exit code 2는 PreToolUse Hook에서만 차단 신호로 해석됩니다. PostToolUse Hook에서 exit 2를 반환해도 도구는 이미 실행된 이후이므로 차단이 되지 않습니다. 실행 전 차단은 반드시 PreToolUse에서만 가능합니다.
Hook에서 사용 가능한 환경변수
Hook 명령어 실행 시 Claude Code가 자동으로 설정하는 환경변수 목록입니다:
변수명
내용
사용 가능 이벤트
CLAUDE_TOOL_NAME
실행된 도구 이름 (Write, Edit, Bash 등)
Pre/PostToolUse
CLAUDE_TOOL_INPUT
도구 입력값 (JSON 문자열)
Pre/PostToolUse
CLAUDE_TOOL_OUTPUT
도구 실행 결과 (JSON 문자열)
PostToolUse
CLAUDE_NOTIFICATION
알림 메시지 내용
Notification
CLAUDE_PROJECT_DIR
현재 프로젝트 루트 경로
모든 이벤트
⚠️ 막히는 케이스: Hook 스크립트 실행 시간이 너무 길어서 Claude Code가 멈추는 경우 — Hook의 기본 타임아웃은 60,000ms(60초)입니다. lint나 테스트처럼 빠른 명령은 timeout: 15000 (15초)으로 낮춰서 설정하세요. 타임아웃이 초과하면 Hook이 실패로 처리되고, PreToolUse에서 타임아웃이 나면 도구 실행이 차단될 수 있습니다.
제일 흔한 건 Hook이 아예 안 도는 경우인데, 대부분 settings.json의 JSON 구문 오류입니다. JSON은 trailing comma를 허용하지 않으니 node -e require('./.claude/settings.json') 으로 파싱부터 확인하세요. 두 번째는 PostToolUse에서 exit 2를 반환하며 도구를 막으려는 실수입니다. 차단 신호는 PreToolUse에서만 유효하고 PostToolUse는 이미 실행된 뒤라 막히지 않습니다. 또 파일 경로가 안 읽히면 CLAUDE_TOOL_INPUT의 JSON에서 Write는 path, Edit는 file_path 키를 쓴다는 차이를 둘 다 fallback으로 처리해야 합니다.
다른 대안과 비교했을 때 어떤 상황에 적합한가요?
Hooks는 '파일을 저장할 때마다', '도구가 실행되기 직전에'처럼 특정 이벤트에 무조건 끼어들어야 하는 자동화에 적합합니다. 파일 수정 후 자동 lint(PostToolUse), .env 같은 보호 파일 수정 차단(PreToolUse, exit 2), 작업 완료 알림(Stop)처럼 사람이 매번 기억해서 호출할 수 없는 작업이 대표적입니다. 반대로 사용자가 필요할 때만 직접 부르는 작업(커밋 생성, PR 리뷰)이라면 Hooks보다 Skills(가이드 #11)가 맞습니다. 또 Hook이 너무 자주 트리거돼 작업을 방해한다면 matcher 정규식을 좁혀 특정 도구·파일에만 반응하도록 범위를 줄이는 게 핵심입니다.
더 깊게 공부하려면 어떤 자료를 보면 좋을까요?
이벤트 타입(PreToolUse, PostToolUse, Notification, Stop 등)과 settings.json 스키마의 정확한 정의는 공식 Hooks 문서(code.claude.com/docs/en/hooks)와 Settings 문서(code.claude.com/docs/en/settings)에서 먼저 확인하세요. exit code 처리나 환경변수(CLAUDE_TOOL_INPUT, CLAUDE_TOOL_OUTPUT) 동작은 버전에 따라 달라질 수 있어 1차 자료가 안전합니다. 이어서 Hooks를 슬래시 명령과 엮고 싶다면 가이드 #11(Skills 완벽 가이드)을, PreToolUse 가드를 보안 관점에서 더 다지고 싶다면 가이드 #17(보안 & 권한 관리)을 보면 이 글의 자동화 패턴이 한 단계 확장됩니다.
Claude Code 가이드 #12, 한 줄로 정리하면 어떻게 되나요?
Hooks는 Claude Code의 특정 이벤트(파일 수정, 도구 실행, 응답 완료 등)에 셸 명령을 연결해 lint·검증·차단·알림을 자동으로 돌리는 기능입니다. settings.json에 정의하며, PreToolUse는 실행 전(exit 2로 차단 가능), PostToolUse는 실행 후 검증·알림에 씁니다. 복잡한 명령은 scripts/ 폴더의 bash 스크립트로 분리하고 matcher로 반응 범위를 좁히는 것이 안정적인 운영의 핵심입니다.
실무에서 처음 도입할 때 가장 먼저 확인할 것은 무엇인가요?
먼저 Hook을 어디에 둘지 정하세요. 이 프로젝트에만 적용할 거면 .claude/settings.json, 모든 작업에 공통이면 ~/.claude/settings.json 입니다. 그다음 matcher로 반응할 도구를 좁히는 게 중요합니다. 예를 들어 파일 수정에만 lint를 걸려면 Write|Edit 정규식을 지정합니다. 복잡한 명령은 인라인으로 길게 쓰지 말고 scripts/ 폴더의 bash 스크립트로 분리한 뒤 command에서 호출하는 방식을 권하며, lint처럼 빠른 작업은 기본 60초인 timeout을 15000(15초) 정도로 낮춰 두면 멈춤을 피할 수 있습니다.