AI Agent 时代运维安全:rm 防误删方案对比

写于 2026-07-29,基于 OpenCode / Claude Code / Cursor 等 AI 编程工具的实际经验。


问题

AI 编程 Agent(OpenCode、Claude Code、Cursor、Codex 等)拥有 bash 执行权限。
一个 rm -rf 就能永久删除文件,没有 Ctrl+Z。

真实事故

事件 后果
Claude Code 执行 rm -rf 删除用户家目录 项目代码全丢
Claude Code 执行 terraform destroy 删除生产库 2.5 年数据蒸发
Agent 执行 git reset --hard 丢弃未提交代码 数小时工作白费
Agent 执行 git clean -fd 清理"临时文件" 删除重要配置

根本原因: rm 是不可逆操作。Agent 会把破坏性命令当"捷径"用。


方案对比

1. alias rm=‘trash’(bashrc)

echo "alias rm='trash'" >> ~/.bashrc
维度 评价
原理 shell alias,执行 rm 时替换为 trash
优点 最简单,一行搞定
缺点 非交互式 shell 不读 .bashrc,alias 不生效
适合 个人终端手动操作

致命缺陷: AI Agent 的 bash 工具通常启动非交互式 shell(如 Claude Code),
.bashrc 根本不被加载,alias 直接被跳过。对 Agent 无效。


2. safe-rm

apt install safe-rm
维度 评价
原理 替换 /usr/bin/rm,保护关键路径(//etc 等)
优点 防删系统目录,零配置
缺点 只保护系统路径,不保护项目文件
适合 基础防护层

局限: Agent 删 src/package.json 等项目文件,safe-rm 不管。


3. trash-cli(Python)

apt install trash-cli
# 或 pip install trash-cli
维度 评价
原理 Python 实现 FreeDesktop Trash 规范
优点 成熟稳定,社区大,文档多
缺点 依赖 Python,ARM 上安装麻烦,体积大
命令 trash-puttrash-listtrash-restoretrash-empty
适合 桌面 Linux 环境

问题: 盒子是 ARM + Ubuntu 20.04,Python 环境可能冲突。
trash-put 命令名和 rm 不兼容,需要额外 alias。


4. gtrash(Go)

curl -fsSL https://github.com/umlx5h/gtrash/releases/latest/download/gtrash-linux-armhf \
  -o /usr/local/bin/gtrash && chmod +x /usr/local/bin/gtrash
维度 评价
原理 Go 单文件,遵循 FreeDesktop Trash 规范
优点 2MB 单文件,无依赖,armhf 原生,rm 参数兼容好
缺点 社区比 trash-cli 小
命令 gtrash putgtrash listgtrash restoregtrash empty
适合 服务器、ARM 设备、容器环境

亮点: gtrash put 不需要 -r 参数就能删目录,和 rm 行为一致。


5. ai-trash(专门为 AI Agent 设计)

curl -fsSL https://raw.githubusercontent.com/forethought-studio/ai-trash/main/install.sh | bash
维度 评价
原理 PATH shim + 进程树检测,自动识别 AI 工具
优点 自动区分"你的 rm"和"Agent 的 rm",只拦截 Agent
缺点 复杂,macOS 为主,Linux 支持不完善
支持 Claude Code、Cursor、Copilot、Codex、Aider、OpenCode 等全系列
适合 macOS 多工具环境

亮点: 你自己用 rm 正常执行,Agent 用 rm 自动进回收站。


6. rm-airbag

# macOS only
curl -fsSL https://raw.githubusercontent.com/gy-0/rm-airbag/main/install.sh | zsh
维度 评价
原理 PATH shim,把 rm 替换为 trash 脚本
优点 透明拦截,零配置
缺点 仅 macOS(依赖 /usr/bin/trash
适合 Mac 用户

7. OpenCode 插件

// .opencode/plugins/rm-guard.js
export const RmGuard = async () => {
  return {
    "tool.execute.before": async (input, output) => {
      if (input.tool === "bash") {
        output.args.command = output.args.command
          .replace(/\brm\s+(-[a-zA-Z]*\s+)?/g, 'trash ')
      }
    },
  }
}
维度 评价
原理 tool.execute.before 钩子,拦截 bash 命令并改写
优点 原生集成,可以精确控制
缺点 只保护 OpenCode,需要写代码
适合 只用 OpenCode 的环境

8. Claude Code hooks

// .claude/settings.json
{
  "permissions": {
    "deny": ["Bash(rm:*)"],
    "allow": ["Bash(trash *)"]
  }
}
<!-- CLAUDE.md -->
## No `rm` Rule
Never use `rm`. Always use `trash` instead.
维度 评价
原理 权限 deny + 系统提示
优点 Claude Code 官方推荐
缺点 只保护 Claude Code,Agent 可能忽略提示
适合 只用 Claude Code 的环境

综合对比

方案 拦截范围 Agent 无感 安装难度 ARM 支持 推荐度
alias rm=‘trash’ 仅交互式 shell
safe-rm 系统路径 ⭐⭐
trash-cli 需配合 alias ⭐⭐ ⚠️ ⭐⭐
gtrash 需配合 shim ⭐⭐⭐
ai-trash AI 工具自动识别 ⭐⭐ ⚠️ ⭐⭐⭐
rm-airbag PATH shim ⭐⭐
OpenCode 插件 仅 OpenCode ⭐⭐⭐ ⭐⭐
Claude hooks 仅 Claude Code ⭐⭐ ⭐⭐

我们的方案:PATH shim + gtrash

为什么选这个

  1. PATH shim 是唯一对所有 shell 都生效的方案

    • alias 只对交互式 shell 生效
    • 插件只对特定工具生效
    • PATH 是环境变量,子进程继承,不管是交互式还是非交互式
  2. gtrash 是最轻的回收站工具

    • Go 单文件,2MB,无依赖
    • armhf 原生支持,直接 curl 下载
    • rm 参数兼容好,不需要特殊处理
  3. 完全无感

    • Agent 照常用 rm,不知道背后换了 trash
    • 不需要改配置,不需要写插件,不需要改提示词

实现步骤

第 1 步:安装 gtrash
# ARM 设备(盒子)
ssh hi-box "curl -fsSL https://github.com/umlx5h/gtrash/releases/latest/download/gtrash-linux-armhf \
  -o /usr/local/bin/gtrash && chmod +x /usr/local/bin/gtrash"

# x86 机器
curl -fsSL https://github.com/umlx5h/gtrash/releases/latest/download/gtrash-linux-amd64 \
  -o /usr/local/bin/gtrash && chmod +x /usr/local/bin/gtrash
第 2 步:写 PATH shim
cat > /usr/local/bin/rm << 'SHIM'
#!/bin/bash
# rm shim - 把 rm 转发给 gtrash,保护文件不被永久删除
# 真删请用 /bin/rm
args=()
for arg in "$@"; do
  [[ "$arg" == -* ]] && continue
  args+=("$arg")
done
if [ ${#args[@]} -eq 0 ]; then
  exec /bin/rm "$@"
fi
exec /usr/local/bin/gtrash put "${args[@]}"
SHIM
chmod +x /usr/local/bin/rm
第 3 步:确认 PATH 优先级
which rm
# 应该输出 /usr/local/bin/rm(不是 /bin/rm)

# 如果不是,确保 PATH 最前面有 /usr/local/bin
export PATH="/usr/local/bin:$PATH"

日常使用

操作 命令
删文件(安全,进回收站) rm file.txt / rm -rf dir/
查看回收站 gtrash list
恢复文件 gtrash restore
交互式恢复 gtrash restore(带选择界面)
清空回收站 gtrash empty
清空 30 天前的 gtrash empty 30
真删(绕过保护) /bin/rm -rf xxx

已知限制

场景 问题 解决
sudo rm sudo 重置 PATH,shim 不生效 sudo /usr/local/bin/rm
/bin/rm 完整路径绕过 shim 这是有意的,真删时用这个
find . -delete 不走 rm,走 unlink 系统调用 shim 无法拦截
xargs rm 取决于 shell 是否加载 PATH 大多数情况生效
回收站占空间 trash 不释放磁盘 定期 gtrash empty

推荐分层防护

┌─────────────────────────────────────┐
│  第 1 层:PATH shim + gtrash        │  ← 拦截 rm,进回收站
├─────────────────────────────────────┤
│  第 2 层:safe-rm                   │  ← 保护 /、/etc 等系统路径
├─────────────────────────────────────┤
│  第 3 层:OpenCode permission       │  ← 工具级权限控制
├─────────────────────────────────────┤
│  第 4 层:Git 版本控制               │  ← 最后防线,代码可恢复
├─────────────────────────────────────┤
│  第 5 层:定期备份                   │  ← 终极保障
└─────────────────────────────────────┘

我们的方案覆盖第 1 层,是最重要的一层。


参考链接

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐