Claude Code 总闯祸?5 个钩子替你踩刹车

Claude Code 推理代码很在行,却不会像人一样在动手前先想后果。好在它提供”钩子(Hooks)”机制:在工具调用前或后自动触发一段脚本,用确定性的规则拦住危险操作。把这些钩子写进 .claude/settings.json,Claude Code 就从”需要时刻盯着的工具”变成”可以放心交键盘的搭档”。

一、拦住毁灭性命令

Bash 工具每次调用前加一道 PreToolUse 守卫,扫描命令文本,命中危险模式就拦截。脚本从标准输入读 JSON,取出 command 字段,匹配 rm -rf、dd if=、mkfs 等就退出码 2,Claude 会收到原因并改提替代方案,而不是盲目重试。

#!/bin/bash
command=$(cat | jq -r '.tool_input.command')
[[ "$command" =~ rm\ -rf|dd\ if=|mkfs\. ]] && echo "Blocked: destructive command" >&2 && exit 2
exit 0

二、保护密钥和环境变量

针对 Edit、Write 工具加钩子,禁止改写路径里含 .env、secrets、credentials 的文件。这一步格外重要:调试配置时 Claude 常想”顺手修一下”环境文件,而密钥文件恰恰最不该由 AI 在无人看管时改动。

#!/bin/bash
path=$(cat | jq -r '.tool_input.file_path')
[[ "$path" =~ \.env|secrets|credentials ]] && echo "Blocked: protected file" >&2 && exit 2
exit 0

三、阻止强制推送和危险 Git 操作

Git 事故最难挽回,因为它会改写共享历史。钩子可专门识别 git push –force、推送到 main 或 master,以及 git reset –hard,在命令执行前拦下,避免一个下午的工作被静默清空。

#!/bin/bash
command=$(cat | jq -r '.tool_input.command')
[[ "$command" =~ push\ --force|push\ .*\ main|reset\ --hard ]] && echo "Blocked: dangerous git command" >&2 && exit 2
exit 0

四、拦住破坏性的数据库语句

对含 DROP TABLE、TRUNCATE 的命令直接拒绝,并返回结构化 JSON 说明原因,让 Claude 在下一次尝试时调整方向,而不是单纯报错。

#!/bin/bash
command=$(cat | jq -r '.tool_input.command')
[[ "$command" =~ DROP\ TABLE|TRUNCATE ]] && echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Destructive SQL detected"}}'

五、规范包管理器与 CI 配置

若项目用 pnpm,检测到 npm install 就拦下,避免生成冲突的锁文件;同理可禁止改动 CI 配置和生产部署脚本,除非人工明确批准。这类小错累积起来,破坏力不亚于一次大事故。

#!/bin/bash
command=$(cat | jq -r '.tool_input.command')
[[ -f pnpm-lock.yaml && "$command" =~ ^npm\ install ]] && echo "Blocked: use pnpm instead" >&2 && exit 2
exit 0

统一接入:一个 JSON 文件

以上钩子都写在 .claude/settings.json 的 PreToolUse 数组里,按工具(Bash、Edit、Write)配置 matcher。脚本可用 Bash 加 jq 编写,也可用 Python 写更易读的逻辑,建议随仓库提交,让所有协作者共用同一套护栏。

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash", "hooks": [{ "type": "command", "command": ".claude/hooks/block-destructive-bash.sh" }] },
      { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": ".claude/hooks/protect-secrets.sh" }] }
    ]
  }
}

注意事项:钩子依赖 jq 解析输入;拦截以正则匹配命令文本,复杂场景建议结合官方文档细化规则,避免误伤正常操作。

来源:MakeUseOf