【AI】给Codex加上rm防误删Hook
Codex里拦住直接rm命令,给误删多上一道保险。
1.起因
最近在网上看到,有很多人的文件都说被 AI 工具误删了。
正常写代码时删个测试文件、临时目录其实挺常见的,但AI工具为了完成任务,删起东西来也可能一点不手软。权限一给高,哪天模型来一句rm -rf,把目录清了,等它跑完再看终端输出,那可真是欲哭无泪。
最开始想到的办法很朴素,给zsh加一句alias:
1 | alias rm='rmtrash' |
这招平时自己在终端里敲命令还行,但放到Codex这里就不太稳了。Codex跑的shell不一定会加载你的交互式配置,/bin/rm也能直接绕过去。只靠alias,多少有点看运气。
2. 先装对工具:rmtrash
在写Hook前,先把替代命令准备好。这里推荐安装rmtrash:
1 | brew install rmtrash |
它就是按rm的使用习惯做的废纸篓版本,删普通文件和目录都直接用它:
1 | rmtrash 文件.txt |
执行后文件会进macOS废纸篓,想反悔还能在访达里面恢复。
这里不要直接用trash命令。这个名字在不同macOS版本和第三方工具里都可能对应不同实现,它不是给rm做参数兼容的。Codex常用的rm -rf一类参数直接丢给trash,要么被忽略,要么行为和预期不一样,踩坑了更难受。
后面Hook返回的提示也统一让AI使用rmtrash,这样不用再猜它该换成哪个命令。
3. Codex的PreToolUse Hook
Codex自带Hooks机制,可以在工具调用前后跑一段固定脚本。这里要用的就是PreToolUse,它能在shell命令真正执行前看一眼命令内容,发现是rm就直接拒绝。
先在用户目录创建文件:
1 | ~/.codex/hooks.json |
3.1 配置hooks.json
把下面这段放进~/.codex/hooks.json:
1 | { |
这里的matcher只匹配Codex的shell工具,其他工具不会被这个Hook影响。
3.2 写拦截脚本
接着创建~/.codex/hooks/block_rm.py:
1 | #!/usr/bin/env python3 |
拦住命令之后别只甩一句“禁用”,不然AI又得重新猜下一步该干啥。这里直接告诉它用rmtrash把目标丢进废纸篓,正常删除文件的流程还能继续跑。
最后给脚本加上执行权限:
1 | chmod 700 ~/.codex/hooks/block_rm.py |
重新打开Codex,第一次使用时如果出现Hook信任提示,确认这个脚本就是自己写的之后再选择信任。
4. 到底拦住了哪些东西?
这个脚本只干一件事:拦截顶层shell命令里真正执行的rm。
下面这些都会被拒绝:
1 | rm file.txt |
普通命令不受影响:
1 | ls -la |
可以把Hook理解成Codex执行命令前的门卫。模型把命令递出去,门卫看见rm,直接给它挡回来,命令就不会落到系统里。
5. 这玩意不是万能的
这里还是得说清楚,Hook看到的是Codex顶层发出的工具调用。
如果模型先写了一个脚本,再执行:
1 | ./cleanup.sh |
而cleanup.sh里面再去跑rm,这个Hook只看到了./cleanup.sh,看不到脚本内部的命令。同理,Python的shutil.rmtree()、Node.js的fs.rm()也不是这个Hook能处理的。
所以这个方案的目标不是给电脑装上绝对防删盾,而是先把最容易出现的直接rm误操作拦住。重要项目还是老老实实用Git提交、分支或者worktree,真出问题了才有地方回去。
The end
给Agent多加一道确定性的限制,有时候比在提示词里写十遍“不要删文件”管用得多。至少下次看到它想跑rm -rf,不会再只能干瞪眼了。



