第 13 章 · Hooks 自动化钩子
本章目标:理解 Claude Code 的 Hooks 机制——在工具调用的关键节点自动执行自定义命令,实现代码格式化、安全审计、通知推送等自动化。
13.1 什么是 Hooks
Hooks 是 Claude Code 在特定生命周期节点自动执行的 shell 命令。你不需要手动触发——它们在每次工具调用时自动运行。
text
用户输入 → Claude 思考 → 调用工具
↑
PreToolUse hook(工具执行前拦截)
↓
工具实际执行
↓
PostToolUse hook(工具执行后处理)核心价值:把工程规范从"口头约定"变成"强制执行"。比如你告诉 Claude "每次写完代码要跑 lint",它可能会忘;但配置一个 PostToolUse hook,每次写文件后 lint 会自动执行,无法绕过。
13.2 Hook 类型
Claude Code 支持以下 hook 事件:
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse | 工具调用前 | 拦截危险命令、阻止写入敏感文件 |
PostToolUse | 工具调用后 | 自动格式化、运行测试、更新索引 |
Notification | Claude 发通知时 | 推送到 Slack/钉钉/桌面通知 |
Stop | Claude 完成响应时 | 发送完成通知、触发 CI |
SubagentStop | 子代理完成时 | 收集子代理结果 |
13.3 配置 Hooks
Hooks 在 .claude/settings.json(项目级)或 ~/.claude/settings.json(全局)中配置:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_FILE_PATHS\" 2>/dev/null || true"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$TOOL_INPUT\" | grep -q 'rm -rf /' && echo 'BLOCK: Dangerous command' && exit 1 || exit 0"
}
]
}
],
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code 需要你的注意\" with title \"Claude Code\"'"
}
]
}
]
}
}关键概念:
matcher:正则匹配工具名(Write|Edit匹配写文件工具);command:要执行的 shell 命令;- 退出码:
exit 0继续,exit 1阻止(仅 PreToolUse 有效)。
13.4 实用场景
场景一:写文件后自动格式化
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "npx prettier --write \"$CLAUDE_FILE_PATHS\" 2>/dev/null || true" },
{ "type": "command", "command": "npx eslint --fix \"$CLAUDE_FILE_PATHS\" 2>/dev/null || true" }
]
}
]
}
}每次 Claude 写完代码,prettier 和 eslint 自动执行——代码风格永远不会跑偏。
场景二:阻止修改敏感文件
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_FILE_PATHS\" | grep -qE '(\\.env|credentials|secrets)' && echo 'BLOCK: 敏感文件不允许修改' && exit 1 || exit 0"
}
]
}
]
}
}任何尝试修改 .env、credentials 等敏感文件的操作会被自动拦截。
场景三:Slack 通知
json
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "curl -s -X POST $SLACK_WEBHOOK -H 'Content-Type: application/json' -d '{\"text\":\"Claude Code: 需要人工确认\"}'"
}
]
}
]
}
}13.5 调试 Hooks
Hooks 不生效时的排查步骤:
bash
# 1. 确认 settings.json 语法正确
cat .claude/settings.json | python3 -m json.tool
# 2. 手动执行 hook 命令测试
echo '{"file_path": "/tmp/test.ts"}' | npx prettier --stdin-filepath test.ts
# 3. 查看 Claude Code 的 hook 日志
claude --debug安全提醒
Hooks 以你的用户权限执行任意 shell 命令。不要在不信任的项目中盲目接受 hooks 配置——恶意 hook 可以做任何事。Claude Code 会在首次遇到新 hooks 时要求你确认。
本章小结
- Hooks 在工具调用的生命周期节点自动执行,把规范从"约定"变成"强制";
- 五种事件:PreToolUse(拦截)、PostToolUse(后处理)、Notification、Stop、SubagentStop;
- 配置在 settings.json 中,
matcher匹配工具名,exit 1阻止执行; - 典型场景:自动格式化、敏感文件保护、通知推送。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 想在 Claude 每次写完文件后自动运行 prettier,应该用哪个 hook 事件?
2. PreToolUse hook 的 command 返回 exit 1 会发生什么?
3. hooks 配置中的 matcher 字段作用是什么?
4. 关于 hooks 的安全性,正确的做法是?
🛠️ 动手实践
- 配置一个 PostToolUse hook:每次 Claude 写 Python 文件后自动运行
ruff check --fix。 - 配置一个 PreToolUse hook:阻止 Claude 执行任何包含
DROP TABLE或DELETE FROM(无 WHERE 子句)的 Bash 命令。 - 配置一个 Notification hook:当 Claude 完成长任务时发送系统桌面通知。
完成后进入下一章:IDE 集成。