❤️ 如果你也关注 AI 的发展现状,且对 AI 应用开发感兴趣,我会跟你分享大模型与 AI 领域的开源项目和应用,提供运行实例和实用教程,帮助你快速上手AI技术!也非常欢迎你通过公众号发消息加入我们!
❤️ 微信公众号|搜一搜:蚝油菜花
Hook这部分的内容高达两万字,篇幅较长,所以我将这一部分内容分为上下两篇,建议先收藏再慢慢消化!
- 上篇:引入 hook 概念,一步步地跟随文章带你学会创建自己的 hook,循序渐进地深入了解 hook 系统。
- 下篇(本篇):以具体的 hook 示例和解析为核心内容,了解 hook 的最佳实践方法,丰富你的实战经验,学会优化 hook。
在上篇文章中,我们深入了解了 Claude Code Hook 系统的基本概念、工作原理和配置方法。相信你已经对 Hook 的强大功能有了初步认识。
在日常的 AI 编程工作中,你可能会遇到这些场景:
- 🔔 注意力分散:Claude Code 在后台工作时,你可能错过了需要确认的重要操作
- 🐛 代码质量担忧:AI 生成的代码虽然功能正确,但可能不符合团队的代码规范
- 🔒 安全风险:担心 AI 意外修改了重要的配置文件或生产环境代码
- 💾 数据丢失恐惧:长时间的编程会话后,担心重要的修改没有及时备份
- ⚡ 效率瓶颈:重复的手动操作(如代码格式化、质量检查)占用了大量时间
本篇文章将从简单到复杂的 Hook 实战案例,从基础功能到高级应用,让你进一步了解 Hook 的使用技巧。
🌟 如果你还不知道什么是 Claude Code,或者你还想知道怎么安装和快速上手,可以阅读前文:
- 一、《油菜花的Claude Code快速上手指南》--- 安装与运行 Claude Code
- 二、将GLM 4.5接入Claude Code,打造最具性价比的AI工程师
- 三、Claude Code 核心命令详解,让开发效率飙升10倍!
- 四、详解Claude Code的"大脑":CLAUDE.md让AI记住你的项目
- 五、详解Claude Code子代理功能,用AI打造私人专业团队
- 六、万字深度解析Claude Code的hook系统:让AI编程更智能、更可控|上篇---详解篇
Hook 实战案例
案例1:智能通知系统
目标 :当 Claude Code 需要你的输入或确认时,发送桌面通知提醒你。 难度 :⭐⭐ 适用系统:macOS(其他系统需要自行更改通知命令)
配置文件:
json
{
"hooks": {
"Notification": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude需要你的注意\" with title \"Claude Code\" sound name \"Glass\"'",
"timeout": 10
}
]
}
]
}
}
工作原理:
- 监听所有 Claude Code 的通知事件
- 使用 macOS 的 AppleScript 发送桌面通知
效果:当 Claude Code 需要你的输入或确认时,你会收到桌面通知和声音提醒。
案例2:代码质量检查
目标 :在 Claude Code 编辑 Python 文件后,自动运行代码风格检查。 难度:⭐⭐
前提条件:安装flake8
bash
pip install flake8
配置文件:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "file=$(echo '$CLAUDE_TOOL_INPUT' | jq -r '.file_path // .path'); if [[ \"$file\" == *.py ]]; then echo '🔍 检查Python代码风格...'; flake8 \"$file\" --max-line-length=88 || echo '⚠️ 代码风格需要改进'; fi",
"timeout": 30
}
]
}
]
}
}
工作原理:
- 检查被编辑的文件是否是 Python 文件
- 如果是,运行 flake8 进行代码风格检查
- 显示检查结果,帮助维护代码质量
效果:每次 Claude Code 编辑 Python 文件后,你都会看到代码风格检查的结果。
案例3:自动代码格式化
目标 :每次 Claude Code 编辑 JavaScript 或 TypeScript 文件后自动格式化代码。 难度 :⭐⭐⭐ 前提条件:确保你的系统已安装prettier
bash
npm install -g prettier
配置文件:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "if echo '$CLAUDE_TOOL_INPUT' | jq -r '.file_path // .path' | grep -E '\.(js|ts)$' > /dev/null; then file=$(echo '$CLAUDE_TOOL_INPUT' | jq -r '.file_path // .path'); echo '正在格式化: $file'; prettier --write \"$file\"; fi",
"timeout": 30
}
]
}
]
}
}
工作原理:
- 监听 Claude Code 的文件编辑操作
- 检查被编辑的文件是否是JS/TS文件
- 如果是,就用prettier自动格式化
- 显示格式化的文件名
效果:每次 Claude Code 修改 JavaScript 或 TypeScript 文件后,代码会自动格式化变得整齐美观。
案例4:文件保护系统
目标 :防止 Claude Code 意外编辑李重要的配置文件或生产环境的文件。 难度:⭐⭐⭐
配置文件:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "file=$(echo '$CLAUDE_TOOL_INPUT' | jq -r '.file_path // .path'); if echo \"$file\" | grep -E '(production|secrets|config\.prod|\.env\.prod)'; then echo '错误:不能编辑受保护的文件' >&2; exit 2; fi",
"timeout": 5
}
]
}
]
}
}
工作原理:
- 在 Claude Code 尝试编辑或写入文件之前检查文件路径
- 如果文件路径包含敏感关键词(如"production"、"secrets"等),则阻止操作
- 向 Claude Code 返回错误信息,说明为什么不能编辑该文件
保护的文件类型:
- 生产环境配置文件
- 密钥和秘密文件
- 生产环境变量文件
效果:当 Claude Code 尝试编辑这些敏感文件时,操作会被阻止,并显示友好的错误信息。
案例5:项目自动备份系统
目标 :每次会话结束时,自动备份重要的项目文件。 难度 :⭐⭐⭐⭐ 第一步:创建备份脚本
创建文件 ~/.claude/hooks/backup_project.sh
:
bash
#!/bin/bash
# 获取项目目录
PROJECT_DIR="$CLAUDE_PROJECT_DIR"
if [ -z "$PROJECT_DIR" ]; then
PROJECT_DIR="$(pwd)"
fi
# 创建备份目录
BACKUP_DIR="$HOME/claude_backups/$(basename "$PROJECT_DIR")"
mkdir -p "$BACKUP_DIR"
# 生成时间戳
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="$BACKUP_DIR/backup_$TIMESTAMP.tar.gz"
# 备份重要文件(排除node_modules等大文件夹)
echo "正在备份项目到: $BACKUP_FILE"
tar -czf "$BACKUP_FILE" \
--exclude="node_modules" \
--exclude=".git" \
--exclude="*.log" \
--exclude="dist" \
--exclude="build" \
-C "$(dirname "$PROJECT_DIR")" \
"$(basename "$PROJECT_DIR")"
echo "✅ 备份完成: $BACKUP_FILE"
# 只保留最近5个备份
ls -t "$BACKUP_DIR"/backup_*.tar.gz | tail -n +6 | xargs -r rm
echo "🧹 清理了旧备份,保留最近5个"
第二步:设置脚本权限
bash
chmod +x ~/.claude/hooks/backup_project.sh
第三步:配置Hook
json
{
"hooks": {
"SessionEnd": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/backup_project.sh",
"timeout": 60
}
]
}
]
}
}
工作原理:
- 在每次 Claude Code 会话结束前触发
- 自动打包项目文件(排除不必要的大文件夹)
- 按时间戳命名备份文件
- 自动清理,只保留最近5个备份
效果 :每当结束与 Claude Code 的对话时,你的项目都会被自动备份到 ~/claude_backups/
目录。
优化 Hook 的最佳实践
掌握了 Hook 的基本用法后,让我们进一步了解优化 Hook 的最佳实践,让你的 Hook 更稳定、更高效。
1. 让 Hook 运行得更快
1.1 尽可能使用简单快速的命令
bash
# ❌ 不好的做法:耗时的操作
find / -name "*.log" -exec gzip {} \; # 可能需要很长时间
# ✅ 好的做法:快速操作
echo "$(date): Hook执行" >> ~/quick_log.txt
1.2 设置合理的超时时间
json
{
"type": "command",
"command": "your_command_here",
"timeout": 10 // 10秒超时,防止Hook卡住
}
1.3 对于耗时操作,使用后台执行
bash
# 将耗时任务放到后台
echo "开始备份..."
./backup_script.sh > /dev/null 2>&1 & # &符号表示后台运行
echo "备份已启动"
2. 让 Hook 更可靠
2.1 检查依赖工具是否存在
bash
#!/bin/bash
# 检查必需的工具
if ! command -v jq &> /dev/null; then
echo "❌ 错误:需要安装jq工具" >&2
echo "请运行:brew install jq" >&2
exit 1
fi
if ! command -v prettier &> /dev/null; then
echo "❌ 错误:需要安装prettier" >&2
echo "请运行:npm install -g prettier" >&2
exit 1
fi
echo "✅ 所有依赖都已安装"
2.2 安全地处理 JSON 数据
bash
# 先检查JSON是否有效
if ! echo "$CLAUDE_TOOL_INPUT" | jq . > /dev/null 2>&1; then
echo "❌ 无效的JSON输入" >&2
exit 1
fi
# 然后安全地提取数据
file_path=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.file_path // "unknown"')
if [ "$file_path" = "unknown" ]; then
echo "⚠️ 无法获取文件路径" >&2
exit 1
fi
3. 让 Hook 更安全
3.1 验证文件路径的安全性
bash
# 检查文件路径是否安全
file_path=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.file_path // .path')
# 防止路径遍历攻击
if [[ "$file_path" == *"../"* ]] || [[ "$file_path" == "/"* ]]; then
echo "🚫 不安全的文件路径:$file_path" >&2
exit 2
fi
# 检查文件是否在允许的目录内
if [[ "$file_path" != "$CLAUDE_PROJECT_DIR"* ]]; then
echo "🚫 文件不在项目目录内:$file_path" >&2
exit 2
fi
3.2 检查文件权限
bash
# 检查是否有写入权限
if [[ ! -w "$(dirname "$file_path")" ]]; then
echo "🚫 没有写入权限:$file_path" >&2
exit 2
fi
4. 让 Hook 更容易调试
4.1 创建详细的日志
bash
# 创建一个日志函数
log_message() {
local level="$1"
local message="$2"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> ~/.claude/hook_debug.log
}
# 使用日志函数
log_message "INFO" "Hook开始执行"
log_message "DEBUG" "处理文件:$file_path"
log_message "INFO" "Hook执行完成"
4.2 保存Hook的输入信息(用于调试)
bash
# 只在调试模式下保存详细信息
if [ "$CLAUDE_DEBUG" = "true" ]; then
echo "=== Hook调试信息 ===" >> ~/.claude/hook_debug.log
echo "时间:$(date)" >> ~/.claude/hook_debug.log
echo "项目目录:$CLAUDE_PROJECT_DIR" >> ~/.claude/hook_debug.log
echo "工具输入:$CLAUDE_TOOL_INPUT" >> ~/.claude/hook_debug.log
echo "==================" >> ~/.claude/hook_debug.log
fi
5. 组织你的 Hook 配置
5.1 按环境分离配置
bash
# 在Hook中检查环境
if [ "$NODE_ENV" = "production" ]; then
echo "🔒 生产环境模式:启用严格检查"
# 生产环境的严格检查
else
echo "🛠️ 开发环境模式:宽松检查"
# 开发环境的宽松检查
fi
5.2 使用配置文件
创建 ~/.claude/hook_config.json
:
json
{
"notifications": {
"enabled": true,
"sound": "Glass"
},
"formatting": {
"auto_format": true,
"file_types": ["js", "ts", "py"]
},
"security": {
"protected_paths": ["production", "secrets", ".env.prod"]
}
}
然后在Hook中读取配置:
bash
# 读取配置
config_file="$HOME/.claude/hook_config.json"
if [ -f "$config_file" ]; then
auto_format=$(jq -r '.formatting.auto_format' "$config_file")
if [ "$auto_format" = "true" ]; then
echo "✅ 自动格式化已启用"
fi
fi
通用 Hook 模板
这个模板包含了错误处理、日志记录、调试支持等最佳实践,你可以基于它来编写自己的Hook。
bash
#!/bin/bash
# Hook模板 - 复制这个模板开始编写你的Hook
set -euo pipefail # 严格模式
# 配置
LOG_FILE="$HOME/.claude/hooks.log"
DEBUG=${CLAUDE_DEBUG:-false}
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 调试函数
debug() {
if [ "$DEBUG" = "true" ]; then
log "DEBUG: $1"
fi
}
# 主要逻辑开始
log "Hook开始执行"
debug "工具输入:$CLAUDE_TOOL_INPUT"
# 检查依赖
if ! command -v jq &> /dev/null; then
log "ERROR: jq未安装"
exit 1
fi
# 解析输入
if ! echo "$CLAUDE_TOOL_INPUT" | jq . > /dev/null 2>&1; then
log "ERROR: 无效的JSON输入"
exit 1
fi
# 你的Hook逻辑写在这里
# ...
log "Hook执行完成"
exit 0
Hook 常见问题
即使是最有经验的开发者,也会遇到 Hook 不按预期工作的情况。别担心,这里有一份完整的故障排除指南。
问题1:Hook根本不执行
症状:你设置了Hook,但它从来不运行
可能原因和解决方案:
- 检查匹配器是否正确
bash
# 检查你的配置文件
cat ~/.claude/settings.json | jq '.hooks'
# 确认匹配器名称是否正确(区分大小写)
# 正确:"Bash", "Edit", "Write"
# 错误:"bash", "edit", "write"
- 验证JSON语法
bash
# 检查JSON是否有效
cat ~/.claude/settings.json | jq .
# 如果有语法错误,会显示错误信息
- 确认配置文件位置
bash
# 检查用户级配置
ls -la ~/.claude/settings.json
# 检查项目级配置
ls -la .claude/settings.json
问题2:Hook执行但失败了
症状:Hook开始执行,但中途出错
诊断步骤:
- 检查Hook脚本权限
bash
# 确保脚本可执行
chmod +x ~/.claude/hooks/your_script.sh
- 手动测试Hook脚本
bash
# 模拟Claude的环境变量
export CLAUDE_TOOL_INPUT='{"file_path":"/path/to/test.js"}'
export CLAUDE_PROJECT_DIR="$(pwd)"
# 手动运行Hook
bash ~/.claude/hooks/your_script.sh
- 检查依赖工具
bash
# 检查Hook需要的工具是否安装
command -v jq || echo "jq未安装"
command -v prettier || echo "prettier未安装"
问题3:Hook运行太慢
症状:Hook 执行时间很长,影响 Claude Code 的响应速度
解决方案:
- 添加超时设置
json
{
"type": "command",
"command": "your_slow_command",
"timeout": 10
}
- 优化Hook逻辑
bash
# 避免全盘搜索
find / -name "*.log" # ❌ 很慢
find . -maxdepth 2 -name "*.log" # ✅ 更快
- 使用后台处理
bash
# 将耗时操作放到后台
long_running_task.sh &
echo "任务已启动"
写在最后
记住,一个好的 Hook 应该具备这些特质:
- 目标明确:解决特定的问题,不做无关的事情
- 稳定可靠:能够处理各种边界情况和错误
- 性能友好:不影响正常的工作流程
- 易于维护:代码清晰,配置简单
深度解析 Hook 系列文章回顾:
- 上篇 :万字深度解析Claude Code的hook系统:让AI编程更智能、更可控|上篇---详解篇
- 下篇(本篇):万字深度解析Claude Code的Hook系统:让AI编程更智能、更可控|下篇---实战篇
Hook 系统的真正价值不在于炫技,而在于让 AI 编程变得更加可控、安全和高效。当你发现自己在重复做某些操作时,问问自己:"这个能用 Hook 实现自动化吗?"
相信通过这两篇文章的学习,你已经具备了设计和实现自己的 Hook 系统的能力。现在,是时候在你的项目中实践这些知识,让 Claude Code 真正成为你的智能编程伙伴吧!
这篇文章将会收录到原创专栏《油菜花的Claude Code快速上手指南》中,欢迎感兴趣的小伙伴关注,一起学习,一起进步!
❤️ 感谢阅读
❤️ 如果你也关注 AI 的发展现状,且对 AI 应用开发感兴趣,我会跟你分享大模型与 AI 领域的开源项目和应用,提供运行实例和实用教程,帮助你快速上手AI技术!也非常欢迎你通过公众号发消息加入我们!
❤️ 微信公众号|搜一搜:蚝油菜花