第六部分:FAQ(20个常见问题)
基础问题
Q1: Hook和CLAUDE.md有什么区别?
| 对比 | Hook | CLAUDE.md |
|---|---|---|
| 执行方式 | 自动执行Shell命令 | Claude解读后决定是否遵循 |
| 可靠性 | 100%执行 | 不确定(AI可能忘记) |
| 用途 | 强制规则、自动化 | 提供上下文、建议 |
Q2: Hook可以用什么语言写?
任何可执行程序都可以:
- Python(推荐,跨平台)
- Bash/Shell(macOS/Linux)
- Batch(Windows)
- Node.js
- Go、Rust等(需要编译)
Q3: Hook的timeout默认是多少?
默认60秒。建议根据任务复杂度设置:
- 简单检查:5-10秒
- 代码格式化:30秒
- 完整测试:120秒
Q4: 一个事件可以配置多个Hook吗?
可以!多个Hook会按顺序执行:
{
"matcher": "Write",
"hooks": [
{"type": "command", "command": "python hook1.py"},
{"type": "command", "command": "python hook2.py"}
]
}Q5: PreToolUse的decision有哪些值?
PreToolUse 有新旧两套API(新旧并存):
新版(推荐) — 通过 hookSpecificOutput.permissionDecision 字段:
| 值 | 效果 |
|---|---|
"allow" | 允许执行,绕过权限系统 |
"deny" | 拒绝执行,原因会反馈给Claude |
"ask" | 暂停,询问用户决定 |
| 无输出 | 默认允许 |
旧版(已废弃但仍支持):通过 decision 字段返回,映射关系见前文“旧版决策值”表。这里不重复展开,实际新脚本优先使用 hookSpecificOutput.permissionDecision。
PostToolUse 和 UserPromptSubmit 使用 "block" 来阻止/提供反馈,无输出则默认允许。
配置问题
Q6: settings.json应该放在哪里?
项目根目录的 .claude/settings.json
Q7: Matcher支持正则表达式吗?
支持!例如:
"Write"- 精确匹配"Write|Edit"- 匹配Write或Edit".*"- 匹配所有工具(慎用)
Q8: 如何让Hook只对特定目录的文件生效?
在脚本中检查文件路径:
if '/articles/' not in file_path:
sys.exit(0) # 不在目标目录,跳过Q9: 环境变量怎么传递给Hook脚本?
Claude Code自动传递的环境变量:
CLAUDE_PROJECT_DIR- 项目根目录的绝对路径(Claude Code启动目录)
⚠️ 注意:
session_id不是环境变量,而是通过stdin的JSON输入传递!
使用方法:
import os
import json
import sys
# 从环境变量获取项目目录
project_dir = os.getenv('CLAUDE_PROJECT_DIR', os.getcwd())
# 从stdin的JSON获取session_id(不是环境变量!)
input_data = json.loads(sys.stdin.read())
session_id = input_data.get('session_id', '')Q10: 如何临时禁用Hook?
方法1:重命名配置文件
mv .claude/settings.json .claude/settings.json.bak方法2:注释掉Hook配置(JSON不支持注释,需要删除)
脚本问题
Q11: 如何读取Hook的输入?
import sys
import json
# stdin读取JSON
input_data = json.loads(sys.stdin.read())
tool_name = input_data.get('tool_name')Q12: 如何在Hook中向用户输出信息?
重要:不同Hook类型的输出机制不同!
PostToolUse Hook:无法直接输出给用户
- Claude Code只会显示"Hook执行成功/失败"
- 如需调试,写入日志文件:
from pathlib import Path
log_file = Path.home() / '.claude' / 'hooks' / 'debug.log'
with open(log_file, 'a') as f:
f.write(f"调试信息\n")UserPromptSubmit Hook:通过stdout JSON的additionalContext字段
import json
output = {
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "要显示给用户的内容"
}
}
print(json.dumps(output))PreToolUse Hook:通过stdout JSON返回决策
import json
decision = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": {
"decision": "deny",
"message": "拒绝原因(用户可见)"
}
}
}
print(json.dumps(decision))stderr输出:仅用于调试,不会显示在Claude Code界面
print("调试信息", file=sys.stderr) # 只在终端可见,用户看不到Q13: 如何返回决策(PreToolUse)?
使用stdout输出JSON:
print(json.dumps({"decision": "deny", "message": "原因"}))Q14: 脚本报错会影响Claude Code吗?
不会!Hook脚本出错不会阻止Claude Code运行,只是该Hook功能失效。
Q15: 如何处理Windows/macOS/Linux兼容性?
import platform
system = platform.system()
if system == 'Windows':
# Windows特定代码
elif system == 'Darwin': # macOS
# macOS特定代码
else: # Linux
# Linux特定代码高级问题
Q16: Hook可以修改Claude的输出吗?
不能直接修改。但可以:
- PostToolUse后修改文件内容
- UserPromptSubmit修改用户输入
Q17: 多个Hook的执行顺序是什么?
按配置文件中的顺序依次执行。
Q18: Hook可以调用Claude API吗?
可以,但要注意:
- 会消耗额外Token
- 可能导致无限循环
- 建议设置调用限制
Q19: 如何在团队中共享Hook配置?
将 .claude/ 目录加入Git版本控制:
git add .claude/settings.json
git add .claude/hooks/
git commit -m "Add Claude Code hooks"Q20: Hook有性能影响吗?
有一定影响:
- 每次工具调用都会触发Hook
- 复杂脚本会增加延迟
- 建议优化脚本性能,设置合理timeout