Claude Code Hooks 入门:自动格式化 + 文件保护这样配
Claude Code Hooks 入门:自动格式化 + 文件保护这样配
Prorise第四章. Hooks 自动化机制
本章摘要:每次让 Claude 改完代码,你都要手动运行 prettier 格式化?每次 Claude 要执行危险命令,你都担心漏看?Hooks 机制让你可以在 Claude 执行操作的 “前后” 自动触发脚本——格式化、校验、通知,全部自动化。
本章学习路径
| 阶段 | 内容 | 解锁能力 |
|---|---|---|
| 第一阶段 | Hooks 事件全景 | 理解 Claude 生命周期中的所有可拦截点 |
| 第二阶段 | Hook 配置与编写 | 掌握 Hook 的配置语法和输入输出格式 |
| 第三阶段 | 实战案例 | 实现自动格式化、文件保护、语音通知 |
4.1. Hooks 事件全景
上一章我们学会了用 MCP 扩展 Claude 的能力。但有个问题没解决:Claude 执行操作时,我们能不能 “插一脚”?
“Claude 每次改完 TypeScript 文件,我都要手动运行 prettier,太烦了。”
“Claude 要删除文件时,我想先备份一下,但它执行太快我来不及。”
钩子在特定事件发生时自动触发的脚本 机制就是为了解决这些问题。它让你可以在 Claude 执行操作的 之前 或 之后 自动运行自定义脚本。4.1.1. 工具执行类事件
这类事件与 Claude 调用工具(如读写文件、执行命令)相关:
| 事件名 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse | 工具执行 之前 | 拦截危险操作、修改参数 |
PostToolUse | 工具执行 之后 | 自动格式化、日志记录 |
PermissionRequest | 弹出权限确认框时 | 自动批准/拒绝特定操作 |
PreToolUse 的特殊能力:
这个事件不仅能 “观察”,还能 “干预”。你的脚本可以:
- 返回
allow:自动批准,跳过用户确认 - 返回
deny:直接拒绝,阻止执行 - 返回
ask:弹出确认框,让用户决定
4.1.2. 会话生命周期事件
这类事件与 Claude Code 会话的开始、结束相关:
| 事件名 | 触发时机 | 典型用途 |
|---|---|---|
SessionStart | 会话开始时 | 加载环境变量、安装依赖 |
SessionEnd | 会话结束时 | 清理临时文件、保存状态 |
Stop | Claude 完成响应时 | 检查任务是否真正完成 |
SubagentStop | 子代理完成任务时 | 验证子代理输出质量 |
SessionStart 的特殊能力:
这个事件可以向会话注入环境变量。你的脚本可以写入 $CLAUDE_ENV_FILE 文件,里面的环境变量会在后续所有 Bash 命令中生效。
4.1.3. 其他事件
| 事件名 | 触发时机 | 典型用途 |
|---|---|---|
Notification | Claude 发送通知时 | 自定义通知方式(桌面弹窗、语音提醒) |
UserPromptSubmit | 用户提交提示词时 | 校验输入、添加上下文 |
PreCompact | 执行压缩操作前 | 保存重要上下文 |
4.1.4. 本节小结
Hooks 事件的分类:
| 类别 | 事件 | 核心能力 |
|---|---|---|
| 工具执行类 | PreToolUse, PostToolUse, PermissionRequest | 拦截、修改、记录工具调用 |
| 会话生命周期 | SessionStart, SessionEnd, Stop, SubagentStop | 初始化、清理、验证 |
| 其他 | Notification, UserPromptSubmit, PreCompact | 通知、校验、压缩 |
4.2. Hook 配置与编写
知道了有哪些事件可以拦截,现在来看看如何配置和编写 Hook。
4.2.1. 配置文件结构
Hooks 配置在 settings.json 中,基本结构如下:
1 | { |
字段说明:
| 字段 | 作用 | 示例 |
|---|---|---|
matcher | 匹配工具名(支持正则) | "Write", "Edit|Write", "Bash" |
type | Hook 类型 | "command"(执行命令)或 "prompt"(LLM 评估) |
command | 要执行的 Shell 命令 | "prettier --write \"$file\"" |
timeout | 超时时间(秒) | 60 |
4.2.2. matcher 匹配规则
matcher 决定了 Hook 在什么情况下触发:
| 模式 | 含义 | 示例 |
|---|---|---|
| 精确匹配 | 只匹配指定工具 | "Write" 只匹配 Write 工具 |
| 正则匹配 | 匹配多个工具 | "Edit|Write" 匹配 Edit 或 Write |
| 通配符 | 匹配所有工具 | "*" 或 "" |
常见工具名:
Bash—— 执行 Shell 命令Read—— 读取文件Write—— 创建/覆盖文件Edit—— 修改文件Glob—— 文件模式匹配Grep—— 内容搜索
4.2.3. 输入 JSON 结构
Hook 脚本通过 stdin 接收 JSON 格式的输入数据。不同事件的输入结构略有不同。
PreToolUse / PostToolUse 输入示例:
1 | { |
Notification 输入示例:
1 | { |
4.2.4. 输出与决策控制
Hook 脚本通过 退出码 和 stdout 来控制 Claude 的行为。
退出码含义:
| 退出码 | 含义 | 效果 |
|---|---|---|
0 | 成功 | 继续执行,stdout 内容可选择性展示 |
2 | 阻断 | 阻止操作,stderr 内容反馈给 Claude |
| 其他 | 非阻断错误 | 继续执行,stderr 内容记录到日志 |
JSON 输出格式(高级控制):
对于 PreToolUse 事件,你可以输出 JSON 来精细控制:
1 | { |
permissionDecision 可选值:
"allow"—— 自动批准"deny"—— 拒绝执行"ask"—— 弹出确认框
4.2.5. 本节小结
Hook 配置的核心要素:
| 要素 | 作用 | 关键点 |
|---|---|---|
matcher | 决定何时触发 | 支持正则表达式 |
command | 决定执行什么 | 通过 stdin 接收 JSON |
| 退出码 | 决定是否阻断 | 2 表示阻断 |
| stdout | 决定如何控制 | 可输出 JSON 精细控制 |
4.3 实战案例
4.3.1. 桌面通知 + 语音提醒(Notification)
痛点:Claude 在后台干活时,你切到别的窗口了。它需要你确认权限,但你根本没注意到。等你回来一看,它已经等了 10 分钟。
方案:当 Claude 需要你输入时,自动弹出桌面通知 + 语音提醒。
macOS 配置:
1 | { |
Linux 配置:
1 | # 先安装依赖 |
1 | { |
Windows 配置:
1 | { |
验证方式:启动 Claude Code,让它执行一个需要权限确认的操作(如删除文件),观察是否收到通知。
4.3.2. 命令执行日志(PreToolUse)
痛点:Claude 执行了一堆命令,事后你想回顾一下它到底干了啥,但终端历史已经被冲掉了。
方案:把 Claude 执行的每一条 Bash 命令都记录到日志文件。
步骤 1:创建日志脚本
创建文件 ~/.claude/hooks/log-command.sh:
1 |
|
步骤 2:设置执行权限
1 | chmod +x ~/.claude/hooks/log-command.sh |
步骤 3:配置 Hook
1 | { |
验证方式:让 Claude 执行几条命令,然后查看 ~/.claude/command-history.log。
4.3.3. 自动格式化代码(PostToolUse)
痛点:Claude 改完代码后,格式经常不符合项目规范。你每次都要手动跑 prettier 或 eslint --fix。
方案:Claude 修改文件后,自动运行格式化工具。
步骤 1:创建格式化脚本
创建文件 ~/.claude/hooks/auto-format.sh:
1 |
|
步骤 2:设置执行权限
1 | chmod +x ~/.claude/hooks/auto-format.sh |
步骤 3:配置 Hook
1 | { |
验证方式:让 Claude 创建一个格式混乱的 .ts 文件,观察保存后是否被自动格式化。
4.3.4. 文件修改前自动备份(PreToolUse)
痛点:Claude 改坏了一个文件,你想回滚,但 Git 还没提交,改动已经丢了。
方案:在 Claude 修改任何文件之前,自动备份原文件。
步骤 1:创建备份脚本
创建文件 ~/.claude/hooks/auto-backup.sh:
1 |
|
步骤 2:设置执行权限
1 | chmod +x ~/.claude/hooks/auto-backup.sh |
步骤 3:配置 Hook
1 | { |
验证方式:让 Claude 修改一个已有文件,然后检查 ~/.claude/backups/ 目录下是否生成了备份。
清理策略:备份会越积越多,建议定期清理。可以加一个 cron 任务,删除 7 天前的备份:
1 | # 添加到 crontab -e |
4.3.5. 会话启动时自动激活环境(SessionStart)
痛点:你的项目用了 Python 虚拟环境或 Node 版本管理器(nvm)。每次启动 Claude Code,它执行命令时都用的是系统默认环境,而不是项目环境。
方案:在会话启动时,自动激活项目所需的环境。
Python 虚拟环境配置:
1 | { |
Node 版本切换配置(nvm):
1 | { |
原理说明:$CLAUDE_ENV_FILE 是 Claude Code 提供的特殊环境变量,指向一个临时文件。你往这个文件里写入的内容,会在后续所有 Bash 命令执行前被 source。
验证方式:启动 Claude Code,让它执行 which python 或 node -v,观察输出是否是你期望的环境。
4.3.6. 本节小结
四个实战案例的对比:
| 案例 | 事件 | 解决的痛点 | 核心逻辑 |
|---|---|---|---|
| 桌面通知 + 语音 | Notification | Claude 等你输入时你没注意到 | 调用系统通知 API |
| 命令执行日志 | PreToolUse | 事后想回顾 Claude 执行了什么 | 提取命令写入日志文件 |
| 自动格式化 | PostToolUse | 每次都要手动跑 prettier | 根据文件类型调用格式化工具 |
| 自动备份 | PreToolUse | Claude 改坏文件后无法回滚 | 修改前复制原文件 |
| 自动激活环境 | SessionStart | Claude 用的不是项目环境 | 写入环境变量到 CLAUDE_ENV_FILE |
4.4. 本章总结与 Hooks 速查
本章我们学习了 Hooks 自动化机制——在 Claude 执行操作的前后自动触发脚本。核心思想是:把重复性的人工操作交给脚本,把人类的注意力留给真正需要判断的事情。
4.4.1. 事件速查表
| 事件 | 触发时机 | 能做什么 |
|---|---|---|
| PreToolUse | 工具执行前 | 拦截、修改、记录 |
| PostToolUse | 工具执行后 | 格式化、校验、通知 |
| SessionStart | 会话开始 | 初始化环境、加载配置 |
| SessionEnd | 会话结束 | 清理临时文件 |
| Notification | 需要用户注意时 | 自定义通知方式 |
4.4.2. 场景速查:遇到这些情况,直接用
场景 1:桌面通知 + 语音提醒(macOS)
1 | { |
场景 2:记录所有 Bash 命令到日志
1 | { |
场景 3:修改文件前自动备份
1 | { |
场景 4:修改代码后自动格式化
1 | { |
场景 5:会话开始时自动激活虚拟环境
1 | { |







