rip2的graveyard墓地机制深度解析:被删除的文件为何还能起死回生
【免费下载链接】rip2A safe and ergonomic alternative to rm项目地址: https://gitcode.com/gh_mirrors/ri/rip2
rip2是一个用 Rust 编写的rm安全替代工具,其核心正是 graveyard(墓地)机制:用rip删除的文件不会立刻消失,而是被"埋葬"到一个专属的 graveyard 目录里,误删后随时可以起死回生,把数据完整找回来。这篇文章带你深入源码,彻底搞懂这套墓地机制如何运转。
为什么被删除的文件还能恢复?
传统rm会直接抹掉文件的目录项,数据基本找不回来。rip2 的策略是**"移动"而不是"删除"**,整个流程分四步:
- 创建一个全局的 graveyard 目录,权限默认
0700(仅当前用户可读写) - 在 graveyard 内部镜像文件的绝对路径,作为它的"坟墓"
- 在删除日志
.record中记录"原路径 → 坟墓路径" - 想恢复时执行
rip -u,文件被"挖掘"回原处
位置解析逻辑实现在src/lib.rs的get_graveyard函数中,目录创建、埋葬与恢复的主流程也都在这里。
如何找到graveyard的位置
graveyard 的位置按优先级从高到低有四种确定方式:
| 优先级 | 方式 | 结果 |
|---|---|---|
| 1 | rip --graveyard <路径>参数 | 指定的自定义路径 |
| 2 | 环境变量RIP_GRAVEYARD | 环境变量指向的路径 |
| 3 | 环境变量XDG_DATA_HOME | $XDG_DATA_HOME/graveyard |
| 4 | 默认值 | $TMPDIR/graveyard-$USER(通常为/tmp/graveyard-你的用户名) |
随时可以用子命令查看当前 graveyard 的位置:
rip graveyard # 打印 graveyard 根路径 rip graveyard -s # 打印当前目录对应的 graveyard 子目录💡 官方建议:如果你的系统/tmp是内存文件系统(如 Arch Linux),删除大文件会快速吃满内存,此时可通过RIP_GRAVEYARD把 graveyard 移到磁盘上。
"埋葬"一个文件的完整流程
当你执行rip file.txt dir1时,源码(src/lib.rs的bury_target函数)会依次完成:
① 路径规范化—— 用dunce::canonicalize把目标解析成绝对路径;
② 规划坟墓——build_graveyard_dest函数把文件逐级映射进 graveyard(跳过根目录/),同时规划好每一级目录的权限;
③ 冲突处理—— 如果同名文件已被删过一次,src/util.rs中的rename_grave会自动改名为编号备份file1~1、file1~2……保证任何数据都不被覆盖;
④ 执行移动—— 优先尝试内核级rename(同分区下极快、零拷贝),跨分区失败时自动降级为"复制 + 删原件",并完整保留目录权限、符号链接、FIFO 等特殊文件类型;
⑤ 写入日志—— 成功后向 graveyard 顶层的.record文件追加一行时间戳 × 原路径 × 坟墓路径。
安全细节:对超过 500MB 的大文件,复制前会先询问"是否改为直接永久删除",防止撑爆
/tmp。
文件恢复指南:三种方式一键找回
恢复最近删除的文件
rip -u # Returned /tmp/graveyard-jack/home/jack/file1 to /home/jack/file1不带参数时,rip2 通过src/record.rs中的Record::get_last_bury读取日志的最后一行并恢复它;指向已不存在坟墓的过期条目会被自动清理。
恢复指定文件
直接给-u传坟墓路径即可:
rip -u /tmp/graveyard-jack/home/jack/file1先用"降灵会"查看,再批量恢复
séance(降灵会)模式先列出当前目录下所有被删文件,再决定恢复哪些:
rip -s # 打印 deletion_time + 路径 的清单 rip -su # 把清单里的文件全部恢复如何永久删除被删除的文件
两种彻底删除的途径:
- 整片墓地清空:
rip -d(decompose)会提示 "Really unlink the entire graveyard?",确认后连 graveyard 一起删除,加-f可跳过确认; - 删除单个已入墓文件:对已经在 graveyard 里的文件再次执行
rip,会提示 "Permanently unlink it?",这是针对单个文件的"真删除"入口。
让墓地机制保持安全的设计细节
- 🔒并发安全:
.record日志默认使用 fs4 排他文件锁(Record<FILE_LOCK>结构,非 Windows 平台默认开启),防止多个终端窗口同时读写日志 - ✅永不覆盖:同名冲突一律走编号备份,数据零丢失
- 📦大文件保护:500MB 阈值触发询问,避免内存型
/tmp被打满 - 🔄幂等性:删除 → 恢复 可安全重复执行,始终回到初始状态
- 🔐权限还原:埋葬与恢复都会记录并在完成后重放原始目录权限
核心源码分布:src/lib.rs(埋葬/恢复主流程)、src/record.rs(删除日志与文件锁)、src/util.rs(编号重命名与格式化)、src/args.rs(命令行参数),端到端测试见tests/integration_tests.rs。
rip2安装与上手体验
brew install rip2 # Homebrew(macOS / Linux) cargo install --locked rip2 # 或直接用 Rust 工具链安装装上后只需记住三句话:rip代替rm删除、rip -u反悔、rip -d清场。从此误删不再是灾难。
【免费下载链接】rip2A safe and ergonomic alternative to rm项目地址: https://gitcode.com/gh_mirrors/ri/rip2
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考