CLAUDE.md 告诉 Claude"应该做什么",而 Hooks 是让某些事情一定发生的机制——不依赖 AI 的判断,100% 确定执行。本文用五个实用示例讲清楚 Hooks 怎么用。
Hooks 是什么?
Hooks 是在 Claude Code 生命周期特定时机触发的 Shell 命令。与 CLAUDE.md 的"建议"不同,Hooks 是强制执行的:
- 文件被编辑后,一定自动格式化
- 执行某些命令前,一定经过检查
- Claude 等待输入时,一定发送通知
配置位置
Hooks 写在 settings.json 里:
| 文件 | 作用范围 |
|---|---|
~/.claude/settings.json | 个人全局(所有项目) |
.claude/settings.json | 项目级(团队共享) |
.claude/settings.local.json | 本地个人(不提交 Git) |
查看已配置的 Hooks:
/hooks示例 1:桌面通知(最简单入门)
Claude 在等待你确认时发桌面通知,不用一直盯着终端:
macOS:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification "Claude 需要你的操作" with title "Claude Code"'"
}
]
}
]
}
}Linux:
"command": "notify-send 'Claude Code' 'Claude 需要你的操作'"Windows(PowerShell):
"command": "powershell -Command "[System.Windows.Forms.MessageBox]::Show('Claude needs input')""示例 2:文件编辑后自动格式化
每次 Claude 修改 JS/TS 文件后,自动运行 Prettier 格式化:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "if echo '$CLAUDE_TOOL_INPUT' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))" | grep -qE '\.(js|ts|jsx|tsx)$'; then npx prettier --write "$(echo '$CLAUDE_TOOL_INPUT' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))")" 2>/dev/null; fi"
}
]
}
]
}
}更简单的写法——用脚本文件:
# ~/.claude/hooks/format-on-save.sh
#!/bin/bash
FILE_PATH=$(echo "$CLAUDE_TOOL_INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))")
case "$FILE_PATH" in
*.js|*.ts|*.jsx|*.tsx) npx prettier --write "$FILE_PATH" 2>/dev/null ;;
*.py) black "$FILE_PATH" 2>/dev/null ;;
*.go) gofmt -w "$FILE_PATH" 2>/dev/null ;;
esac{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/format-on-save.sh" }]
}
]
}
}示例 3:拦截危险命令(PreToolUse)
阻止 Claude 执行某些高风险操作:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/guard-commands.sh"
}
]
}
]
}
}guard-commands.sh:
#!/bin/bash
# 从环境变量读取即将执行的命令
COMMAND=$(echo "$CLAUDE_TOOL_INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command',''))")
# 禁止的命令模式
DANGEROUS_PATTERNS=(
"rm -rf /"
"DROP TABLE"
"DELETE FROM.*WHERE 1=1"
"chmod 777"
"> /dev/null 2>&1.*--force"
)
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qi "$pattern"; then
# 退出码 2 = 阻止并显示错误
echo "{"decision": "block", "reason": "危险命令被拦截: $pattern"}"
exit 2
fi
done
# 退出码 0 = 允许继续
exit 0Hook 退出码含义:
0:正常,继续执行1:有输出(作为上下文传给 Claude),但不阻止2:阻止操作,显示错误原因
示例 4:上下文压缩后自动重新注入
会话压缩(/compact)后,一些重要上下文会丢失。用 Hook 自动补回来:
{
"hooks": {
"PostCompact": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "echo '## 项目背景(压缩后自动注入)
当前在 feature/payment 分支。支付模块使用 Stripe,测试环境 API Key 在 .env.test。数据库迁移未完成,不要修改 schema 文件。'"
}
]
}
]
}
}更动态的方式,从文件读取:
#!/bin/bash
# 读取项目关键上下文
cat .claude/context-after-compact.md 2>/dev/null || echo "(无额外上下文)"示例 5:审计配置变更
记录 Claude 对哪些配置文件做了改动(用于安全审计):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'FILE=$(echo "$CLAUDE_TOOL_INPUT" | python3 -c "import sys,json;d=json.load(sys.stdin);print(d.get(\"file_path\",\"\"))"); case "$FILE" in *.json|*.yaml|*.yml|.env*) echo "[$(date)] CONFIG CHANGED: $FILE" >> ~/.claude/audit.log ;; esac'"
}
]
}
]
}
}Hook 类型速查
| 事件 | 触发时机 | 常见用途 |
|---|---|---|
PreToolUse | 工具执行前 | 拦截危险操作、记录日志 |
PostToolUse | 工具执行后 | 格式化代码、触发 CI |
Notification | Claude 等待输入时 | 桌面通知、Slack 提醒 |
PostCompact | 上下文压缩后 | 重新注入背景信息 |
SessionStart | 会话开始时 | 加载项目状态、打招呼 |
高级:Prompt-based Hooks(AI 判断)
对于需要智能判断(不只是规则匹配)的场景,可以用 AI 来评估:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "prompt",
"prompt": "检查这个命令是否可能导致数据丢失或安全问题。如果有风险,说明原因并建议更安全的替代方案。"
}
]
}
]
}
}Prompt-based Hook 会启动一个新的 Claude 实例来评估,不影响主对话上下文。
常见问题
Hook 没有触发?
- 用
/hooks确认配置已加载 - 检查 matcher 正则是否正确
- 查看
~/.claude/hooks.log
Hook 报错?
- 退出码 1 会把错误信息传给 Claude 作为上下文
- 退出码 2 会阻止操作并显示错误
- 测试命令时在终端直接运行,确认能独立执行
来源:Automate workflows with hooks - Claude Code Docs | Anthropic 官方文档