实战

Claude Code Hooks 实战完全指南:自动格式化、危险命令拦截与 CI 集成(2026)

Claude Code Hooks 完整实战教程:PreToolUse/PostToolUse/Stop 四种触发时机、配置文件写法(~/.claude/settings.json)、危险命令拦截脚本(exit 2 阻止机制)、AI 写完代码后自动 Black/Prettier/gofmt 格式化、任务完成推送 Bark 手机通知、文件变更日志记录、Hook 调试技巧与 Matcher 模式参考。

2026/3/284分钟 阅读ClaudeEagle

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 0

Hooks 调试技巧

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

相关文章推荐

实战Claude Code Hooks 实战:自动格式化、危险命令拦截、任务通知,6 个开箱即用配置Claude Code Hooks 实战:6 个开箱即用配置——Prettier 自动格式化、rm -rf 拦截、路径保护、任务完成通知、ESLint 自动修复、会话日志。Hooks 是 100% 确定执行的。2026/4/10实战Claude Code Hooks 进阶:用事件钩子打造自动格式化、安全检查和部署流水线Claude Code Hooks 进阶教程:5 个实战案例覆盖自动格式化、安全守卫、commit 消息生成和通知转发。含完整配置和 Hook 输出协议详解。2026/4/7实战Claude Code Hooks 实战:每次保存自动格式化、拦截危险命令、桌面通知Claude Code Hooks 实战教程:五个即用示例(桌面通知/文件自动格式化/危险命令拦截/压缩后上下文注入/配置变更审计)、Hook 配置位置(全局/项目/本地)、退出码含义(允许/上下文/阻止)、七大 Hook 事件速查表、Prompt-based AI 判断 Hook 进阶用法。2026/3/14实战Claude Code 企业级部署最佳实践:大规模团队的成本控制、安全治理与可观测性Claude Code 企业规模化使用完整指南:AI 网关架构解决成本黑盒/隔离缺失/单点故障三大痛点,含凭证层级化管理、预算速率限制配置、请求打标成本归因、Provider 故障转移、输入输出过滤,以及企业 CLAUDE.md 标准化模板。2026/4/18实战Claude Code 子 Agent 实战:如何用多个 Agent 并行处理复杂任务Claude Code 子 Agent 实战指南:如何用多个独立 Agent 并行处理复杂任务。含 4 个实战示例、自定义 Agent 配置和成本优化建议。2026/4/7实战OpenClaw 与 Claude Code 协同使用实战:AI 聊天助手 + AI 编程助手的终极组合OpenClaw 与 Claude Code 协同使用的完整实战指南:两款工具的定位差异(OpenClaw=聊天AI助手框架,Claude Code=代码库直接操作的编程工具)、在 OpenClaw 中通过 exec 工具调用 Claude Code CLI(claude 命令)执行编程任务、把 OpenClaw 的 Telegram 消息转化为 Claude Code 任务(用自然语言描述→Claude Code执行→返回结果)、使用 OpenClaw Cron 定期触发 Claude Code 执行代码审查/依赖更新/测试/文档生成、CRS 代理在两者中的统一接入方案,以及常见的协同架构模式(主动触发/被动响应/定时执行)。2026/3/24