实战

Claude Code Hooks 实战:每次保存自动格式化、拦截危险命令、桌面通知

Claude Code Hooks 实战教程:五个即用示例(桌面通知/文件自动格式化/危险命令拦截/压缩后上下文注入/配置变更审计)、Hook 配置位置(全局/项目/本地)、退出码含义(允许/上下文/阻止)、七大 Hook 事件速查表、Prompt-based AI 判断 Hook 进阶用法。

2026/3/145分钟 阅读ClaudeEagle

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:

bash
/hooks

示例 1:桌面通知(最简单入门)

Claude 在等待你确认时发桌面通知,不用一直盯着终端:

macOS

json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification "Claude 需要你的操作" with title "Claude Code"'"
          }
        ]
      }
    ]
  }
}

Linux

json
"command": "notify-send 'Claude Code' 'Claude 需要你的操作'"

Windows(PowerShell)

json
"command": "powershell -Command "[System.Windows.Forms.MessageBox]::Show('Claude needs input')""

示例 2:文件编辑后自动格式化

每次 Claude 修改 JS/TS 文件后,自动运行 Prettier 格式化:

json
{
  "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"
          }
        ]
      }
    ]
  }
}

更简单的写法——用脚本文件:

bash
# ~/.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
json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/format-on-save.sh" }]
      }
    ]
  }
}

示例 3:拦截危险命令(PreToolUse)

阻止 Claude 执行某些高风险操作:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/guard-commands.sh"
          }
        ]
      }
    ]
  }
}

guard-commands.sh

bash
#!/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 0

Hook 退出码含义:

  • 0:正常,继续执行
  • 1:有输出(作为上下文传给 Claude),但不阻止
  • 2:阻止操作,显示错误原因

示例 4:上下文压缩后自动重新注入

会话压缩(/compact)后,一些重要上下文会丢失。用 Hook 自动补回来:

json
{
  "hooks": {
    "PostCompact": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "echo '## 项目背景(压缩后自动注入)
当前在 feature/payment 分支。支付模块使用 Stripe,测试环境 API Key 在 .env.test。数据库迁移未完成,不要修改 schema 文件。'"
          }
        ]
      }
    ]
  }
}

更动态的方式,从文件读取:

bash
#!/bin/bash
# 读取项目关键上下文
cat .claude/context-after-compact.md 2>/dev/null || echo "(无额外上下文)"

示例 5:审计配置变更

记录 Claude 对哪些配置文件做了改动(用于安全审计):

json
{
  "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
NotificationClaude 等待输入时桌面通知、Slack 提醒
PostCompact上下文压缩后重新注入背景信息
SessionStart会话开始时加载项目状态、打招呼

高级:Prompt-based Hooks(AI 判断)

对于需要智能判断(不只是规则匹配)的场景,可以用 AI 来评估:

json
{
  "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 官方文档

相关文章推荐

实战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 实战完全指南:自动格式化、危险命令拦截与 CI 集成(2026)Claude Code Hooks 完整实战教程:PreToolUse/PostToolUse/Stop 四种触发时机、配置文件写法(~/.claude/settings.json)、危险命令拦截脚本(exit 2 阻止机制)、AI 写完代码后自动 Black/Prettier/gofmt 格式化、任务完成推送 Bark 手机通知、文件变更日志记录、Hook 调试技巧与 Matcher 模式参考。2026/3/28实战Claude Code GitLab CI/CD 集成指南:@claude 触发 MR 自动化与 Bedrock/Vertex AI 企业配置Claude Code GitLab CI/CD 集成完整指南:事件驱动编排原理(@claude 触发/沙箱执行/MR 审批流)、两步快速配置(ANTHROPIC_API_KEY 掩码变量 + .gitlab-ci.yml Job)、AWS Bedrock OIDC 认证示例、Google Vertex AI Workload Identity 示例、CLAUDE.md CI 专用配置、安全最佳实践(掩码变量/分支保护/工具范围限制),以及三大常见问题排查。2026/3/5实战Claude Code 45 个进阶技巧:8.1k Star 的 GitHub 精华整理ykdojo GitHub 仓库(8100+ Stars)45 个 Claude Code 实战技巧精华整理:自定义状态栏显示 Token 消耗;Git CLI 配合自动创建 PR;Gemini CLI 作为助手处理被限制的搜索;/compact 带焦点提示词保留关键信息;Fork 会话和半克隆技术;容器安全运行高风险任务;CLAUDE.md vs Skills vs Slash Commands vs Plugins 的区别;/loop 定期轮询;以及 dx 插件安装。2026/5/6实战Claude Code 团队协作配置完全指南:共享 CLAUDE.md、规则库、Hooks 和 Git 工作流Claude Code 团队配置完整指南:项目级配置目录结构(提交到 git 的 .claude/ 目录)、团队版 CLAUDE.md 模板(含团队工作流和约定章节)、共享自定义命令库(代码审查/DB Migration 模板)、/team-onboarding 使用、CODEOWNERS 配置,以及 CI 自动提醒 CLAUDE.md 变更的方案。2026/4/22