Claude Code Hooks 是在 AI 执行动作前后插入自定义脚本的机制—— 可以在 AI 读写文件、执行命令时触发检查, 实现代码格式自动化、安全拦截、日志记录等功能。
Hooks 是什么?
Claude Code 在执行以下动作时,可以触发你自定义的脚本:
动作类型(hookable):
PreToolUse — AI 调用工具【之前】触发
PostToolUse — AI 调用工具【之后】触发
Notification — AI 发出通知时触发
Stop — AI 完成任务时触发
通过 Hooks,你可以:
- 阻止 AI 执行某些危险命令
- 在 AI 写完代码后自动运行 linter/formatter
- 记录所有文件变更到日志
- 在任务完成时发送通知到手机
配置文件
Hooks 配置写在 ~/.claude/settings.json(全局)
或项目根目录的 .claude/settings.json(项目级):
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/check-dangerous-cmd.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/auto-format.sh"
}
]
}
],
"Stop": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/notify-done.sh"
}
]
}
]
}
}实战一:阻止危险命令(安全护栏)
Hook 脚本通过退出码通信:
- 退出码 0:允许继续执行
- 退出码 2:阻止当前工具调用,并向 AI 返回错误信息
bash
#!/bin/bash
# ~/.claude/hooks/check-dangerous-cmd.sh
# 阻止删除系统目录的命令
# Claude Code 通过 stdin 传入工具调用的 JSON 数据
input=$(cat)
command=$(echo "$input" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))")
# 危险命令模式
dangerous_patterns=(
"rm -rf /"
"rm -rf ~"
"dd if="
"> /dev/sda"
"mkfs"
)
for pattern in "${dangerous_patterns[@]}"; do
if echo "$command" | grep -qF "$pattern"; then
echo "BLOCKED: 检测到危险命令 '$pattern',已阻止执行" >&2
exit 2 # 退出码 2 = 阻止 + 报错给 AI
fi
done
exit 0 # 允许执行实战二:写完代码自动格式化
bash
#!/bin/bash
# ~/.claude/hooks/auto-format.sh
# AI 写入文件后自动运行对应格式化工具
input=$(cat)
file_path=$(echo "$input" | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(d.get('tool_input', {}).get('path', ''))
")
if [ -z "$file_path" ]; then
exit 0
fi
ext="${file_path##*.}"
case "$ext" in
py)
# Python:先 isort 整理 import,再 black 格式化
isort "$file_path" 2>/dev/null
black "$file_path" 2>/dev/null
echo "Python: formatted $file_path"
;;
ts|tsx|js|jsx)
# JavaScript/TypeScript:prettier
npx prettier --write "$file_path" 2>/dev/null
echo "JS/TS: formatted $file_path"
;;
go)
# Go:gofmt
gofmt -w "$file_path"
echo "Go: formatted $file_path"
;;
rs)
# Rust:rustfmt
rustfmt "$file_path" 2>/dev/null
echo "Rust: formatted $file_path"
;;
esac
exit 0实战三:任务完成时发送通知
bash
#!/bin/bash
# ~/.claude/hooks/notify-done.sh
# AI 完成任务后通过 Bark 推送手机通知
input=$(cat)
# 提取 AI 的最后一条消息(任务摘要)
summary=$(echo "$input" | python3 -c "
import sys, json
d = json.load(sys.stdin)
msgs = d.get('messages', [])
if msgs:
last = msgs[-1]
content = last.get('content', '')
if isinstance(content, list):
for block in content:
if isinstance(block, dict) and block.get('type') == 'text':
print(block['text'][:100])
break
else:
print(str(content)[:100])
" 2>/dev/null || echo "任务完成")
# Bark 通知(替换为你的 Bark Key)
BARK_KEY="${BARK_KEY:-your-bark-key}"
curl -s "https://api.day.app/${BARK_KEY}/Claude%20Code%20完成/$(python3 -c "import urllib.parse; print(urllib.parse.quote('${summary}'))")" > /dev/null
exit 0实战四:记录所有文件变更
bash
#!/bin/bash
# ~/.claude/hooks/log-changes.sh
input=$(cat)
file_path=$(echo "$input" | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(d.get('tool_input', {}).get('path', 'unknown'))
" 2>/dev/null)
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
log_file="$HOME/.claude/change-log.txt"
echo "[$timestamp] WRITE: $file_path" >> "$log_file"
exit 0Hooks 调试技巧
bash
# 查看 Hook 是否被触发(临时 debug hook)
# 在 settings.json 添加:
# "command": "echo 'HOOK TRIGGERED' >> /tmp/hook-debug.log && cat >> /tmp/hook-debug.log"
# 查看传入 Hook 的完整 JSON 数据
cat /tmp/hook-debug.log | python3 -m json.tool
# 测试你的 Hook 脚本
echo '{"tool_input": {"command": "rm -rf /"}}' | bash ~/.claude/hooks/check-dangerous-cmd.sh
echo "Exit code: $?"常用 Matcher 模式
json
"matcher": "Bash" // 只匹配 Bash 工具
"matcher": "Write|Edit" // 匹配 Write 或 Edit
"matcher": ".*" // 匹配所有工具
"matcher": "Read" // 匹配文件读取
"matcher": "WebSearch" // 匹配网络搜索
"matcher": "Bash|Python" // 匹配 Bash 或 Python 执行最佳实践
安全原则:
Hook 脚本使用 exit 2 阻止危险操作
不要在 Hook 中执行耗时操作(会阻塞 AI)
Hook 脚本要有执行权限:chmod +x hook.sh
性能原则:
格式化 Hook 放在 PostToolUse(不阻塞 AI 写代码)
安全检查 Hook 放在 PreToolUse(写前检查)
通知 Hook 放在 Stop(任务结束后)
调试原则:
先用 debug hook 观察传入数据结构
Hook 失败不应阻止正常工作流
重要日志写到固定位置方便排查
来源:Anthropic Claude Code 文档 - docs.anthropic.com/en/docs/claude-code/hooks