AI工具使用从专家到小白 文章目录ClaudeBash 危险命令防护配置作用域项目级 vs 全局级方法 A全局配置推荐所有项目生效文件分布步骤 1将检测脚本放到全局目录步骤 2在 ~/.claude/settings.json 中注册 Hook步骤 3验证方法 B当前项目配置已有文件分布步骤 1.claude/settings.local.json — 注册 Hook步骤 2check-dangerous-bash.py — 检测逻辑步骤 3Hook 交互协议工作流程拦截的危险模式1. cat — 直接覆盖写入文件2. rm -r / rm -rf — 递归强制删除3. dd if — 磁盘/文件原始读写4. — Shell 覆盖重定向使用说明被拦截时如何处理临时禁用修改检测规则ClaudeBash 危险命令防护配置通过 Claude Code 的PreToolUseHook 机制在每次执行 Bash 命令前自动检测危险模式强制弹出权限确认提示防止意外覆盖或删除文件。作用域项目级 vs 全局级Claude Code 支持三个层级的配置文件优先级从低到高层级文件路径Git适用场景全局~/.claude/settings.jsonN/A所有项目生效个人偏好项目.claude/settings.json提交团队共享的 hook、权限项目本地.claude/settings.local.jsongitignore个人项目级覆盖本配置已同时部署到全局和当前项目对所有项目生效。方法 A全局配置推荐所有项目生效文件分布文件作用~/.claude/settings.json全局 Hook 注册~/.claude/hooks/check-dangerous-bash.py全局检测脚本步骤 1将检测脚本放到全局目录mkdir-p~/.claude/hooks将check-dangerous-bash.py复制到~/.claude/hooks/。步骤 2在~/.claude/settings.json中注册 Hook在已有的全局配置中新增hooks字段与其他字段平级{hooks:{PreToolUse:[{matcher:Bash,hooks:[{type:command,command:python \$HOME/.claude/hooks/check-dangerous-bash.py\,timeout:5,statusMessage:Checking command safety...}]}]}}路径区别全局配置使用$HOME/.claude/hooks/...不能用$CLAUDE_PROJECT_DIR那是项目根目录。步骤 3验证在新终端中打开任意项目执行cat test.txt——应弹出权限确认提示。然后删除测试文件即可验证全局生效。方法 B当前项目配置已有文件分布文件作用.claude/settings.local.json当前项目 Hook 注册.claude/hooks/check-dangerous-bash.py当前项目检测脚本步骤 1.claude/settings.local.json— 注册 Hook{hooks:{PreToolUse:[{matcher:Bash,hooks:[{type:command,command:python \$CLAUDE_PROJECT_DIR/.claude/hooks/check-dangerous-bash.py\,timeout:5,statusMessage:Checking command safety...}]}]}}字段说明层级字段值说明根hooks{}所有 hook 的容器→PreToolUse[]在工具执行之前触发可拦截→ →matcherBash只匹配Bash工具调用→ → →typecommand执行 Shell 命令另有prompt/agent/http类型→ → →commandpython ...调用 Python 检测脚本$CLAUDE_PROJECT_DIR为项目根目录→ → →timeout5超时 5 秒防止脚本卡死阻塞→ → →statusMessageChecking...执行时 spinner 旁显示的提示文字Hook 事件类型选择事件时机能否拦截PreToolUse✅工具执行前可拦截本次选用PostToolUse工具执行成功后仅通知PostToolUseFailure工具执行失败后仅通知Hook 执行方式选择type原理适用场景command✅执行 Shell/Python 脚本规则明确速度快零成本本次选用prompt调用 LLM 判断需要语义理解如这个命令是否危险有 API 费用agent启动子 Agent需要多步骤验证httpPOST 到外部服务企业级集中管控步骤 2check-dangerous-bash.py— 检测逻辑 PreToolUse hook: check Bash commands for destructive patterns. Reads tool call JSON from stdin, outputs hook result JSON to stdout. Blocked patterns: - cat file (bypasses Write tools read first protection) - rm -r / rm -rf (irreversible delete) - dd if... (disk write) - file (redirect overwrite, not append ) importsysimportjsonimportredefmain():# 1. 解析 stdin 中的 JSON提取 Bash 命令字符串try:datajson.load(sys.stdin)exceptjson.JSONDecodeError:print({})# 解析失败 → 放行returncmddata.get(tool_input,{}).get(command,)ifnotcmd:print({})# 空命令 → 放行return# 2. 按顺序匹配危险模式命中即停不继续检查# cat file — 绕过 Write 工具保护ifre.search(r\bcat\s,cmd):warn(cat file — overwrites without confirmation, bypasses Write tool)# rm -r / rm -rf — 不可逆删除elifre.search(r\brm\s-r,cmd):warn(rm -r — irreversible delete)# dd if — 块设备写入elifre.search(r\bdd\sif,cmd):warn(dd — can destroy disks)# 覆盖重定向排除 追加、21 合并elifnotincmdand21notincmdand2notincmd \andre.search(r(?!)(?!)\s*\S,cmd):warn( overwrite redirect — bypasses Write tool)# 3. 安全命令 → 输出空 JSON放行else:print({})defwarn(reason):输出拦截指令 JSON强制弹出权限提示print(json.dumps({continue:True,# 不阻断流程改为弹窗systemMessage:fWARNING:{reason}. Permission required.,hookSpecificOutput:{hookEventName:PreToolUse,permissionDecision:ask,# allow | deny | askpermissionDecisionReason:reason}}))if__name____main__:main()脚本关键设计决策决策选择原因拦截方式permissionDecision: ask弹确认框而非硬阻断真正需要的操作可以放行匹配顺序if/elif链命中即停避免一条命令触发多条警告排除跳过追加重定向追加到文件末尾不覆盖内容安全排除21跳过 stderr 合并只是合并输出流不写入文件排除2跳过 stdout→stderr同上解析失败输出{}放行宁可漏过也不误阻断fail-open脚本语言Python比 bash 正则更可靠JSON 处理更安全步骤 3Hook 交互协议stdin 输入Claude Code → 脚本{tool_name:Bash,tool_input:{command:cat test.txt,description:...,timeout:120000}}stdout 输出 — 安全命令脚本 → Claude Code{}输出空 JSON 对象 放行不做任何干预。stdout 输出 — 危险命令脚本 → Claude Code{continue:true,systemMessage:WARNING: cat file — overwrites without confirmation, bypasses Write tool. Permission required.,hookSpecificOutput:{hookEventName:PreToolUse,permissionDecision:ask,permissionDecisionReason:cat file — overwrites without confirmation, bypasses Write tool}}字段作用continue: true不中断会话流程systemMessage在 UI 中显示的警告文字permissionDecision: ask强制弹出权限确认对话框permissionDecisionReason对话框中展示的拦截原因工作流程Bash 命令 → PreToolUse Hook → check-dangerous-bash.py │ ┌───────┴───────┐ │ 检测危险模式 │ └───────┬───────┘ 安全 │ 危险 {} │ { permissionDecision: ask } │ │ │ 直接执行 │ 弹出权限确认 │ ┌────┴────┐ │ 允许 拒绝 │ 执行 不执行拦截的危险模式1.cat — 直接覆盖写入文件catoutput.txtcat/path/to/file命令作用cat默认将标准输入的内容输出到终端。加上重定向后会将终端输入的内容直接覆盖写入目标文件原有内容全部丢失。为何危险Claude Code 的Write/Edit工具有必须先 Read 才能覆盖的保护机制但cat 是 Bash 原生命令绕过了这道保护可能静默覆盖重要文件。这正是本配置要解决的核心问题。2.rm -r/rm -rf— 递归强制删除rm-rdirectory/# 递归删除目录及其内容rm-rfdirectory/# 递归删除强制模式不提示确认rm-rfnode_modules/# 常见场景清理依赖目录命令作用rmremove删除文件或目录-rrecursive递归删除目录及其所有子目录和文件-fforce强制删除忽略不存在的文件不弹出确认提示为何危险一旦执行不可逆不经过回收站-f参数会让命令静默执行不提示极易误删整个项目目录。3.dd if— 磁盘/文件原始读写ddif/dev/zeroofdisk.imgbs1Mcount100# 创建镜像文件ddifbackup.isoof/dev/sdb# 写入U盘/磁盘命令作用dddata duplicator底层数据复制工具ifinput file指定输入源ofoutput file指定输出目标bsblock size每次读写的块大小为何危险dd直接操作块设备of可以指向磁盘分区如/dev/sda错误的of参数会彻底摧毁磁盘数据连文件系统结构都被覆盖无法通过常规手段恢复。4.— Shell 覆盖重定向echohellofile.txt# 将 echo 输出覆盖写入文件some-commandresult.log# 将命令输出覆盖写入文件data.json# 清空文件内容Bash 允许省略命令命令作用是 Shell 的输出重定向操作符将左侧命令的标准输出覆盖写入右侧文件。如果文件已存在原有内容先被清空再写入新内容。为何危险与cat 同理绕过了Write/Edit工具的保护。 important_file会在瞬间清空文件且不会经过确认。区分是追加append重定向不覆盖原有内容因此不被拦截。使用说明被拦截时如何处理当命令被拦截时Claude Code 会弹出权限确认提示显示拦截原因。你有三个选择Allow允许确认安全放行执行Deny拒绝阻止执行Ask询问回到对话手动确认或用其他方式完成临时禁用如需大量执行文件操作可在对话中告知暂时关闭 hook我将通过修改配置临时禁用检测。修改检测规则编辑.claude/hooks/check-dangerous-bash.py修改main()函数中的正则模式即可增删拦截规则。修改后下次 Bash 调用即刻生效无需重启。