前段时间看到一个Linux删除文件后抢救恢复的方法,大概瞅了下,Linux删除了不像Windows一样有回收站,删除恢复很麻烦,像我之前执行删除都是检查又检查,现在有空了仔细查找了相关方法理论研究了下,给大家分享下。
一、先搞清楚 Linux 删除文件的底层原理
很多人以为 rm 一敲,文件就彻底没了。
但在 Linux 文件系统中,一个文件在某个目录下呈现的样子,实际上只不过是一个指向 inode 的链接。inode 包含了文件的所有属性(如权限、所有权)以及文件内容存储在磁盘上的数据块地址。
当你执行 rm 删除文件时,实际上是在移除指向其 inode 的链接,而不是删除 inode 本身。
关键点来了:其他进程(比如你正在运行tail -f 命令、或者 Nginx 服务等)可能仍然保留着对那个 inode 的访问。只有当这些进程全部处理完毕,并且目录中的所有链接都被移除后,inode 以及它所指向的数据块才会被系统释放,标记为“可写入”状态。
正是这种“延迟回收”机制,给了我们恢复的机会:如果某个进程仍持有该文件的打开状态,那么数据便仍然存在于磁盘的某个地方,尽管目录列表里已经看不到它了。
这正是 Linux 进程伪文件系统 —— /proc 目录发挥作用的地方。
二、核心方法:通过 /proc 抢救恢复
这个方法的原理是:Linux 的 /proc 目录下,每个进程都有一个以 PID 命名的子目录,其中的 fd 子目录存放着该进程打开的所有文件句柄。即使原文件已被删除,这里的文件描述符依然指向数据内容。这个方法不是新创的,我在网上能查到最早2006年发布的。不过我也没用过一次。
演示:用 tail -f 模拟进程占用并恢复文件
下面通过一个简单的实验,完整演示整个恢复流程。你只需要一台 Linux 机器,开两个终端即可。
在终端一中执行:
# 创建一个测试文件,写入一些内容echo ”这是重要数据,千万别丢” > /tmp/test.log# 用 tail -f 持续监控该文件(进程不会退出,会一直持有文件句柄)tail -f /tmp/test.log
此时 tail -f 进程会一直运行,持续持有 /tmp/test.log 的文件句柄。屏幕上会显示文件内容。
再复制会话打开终端二删除对应文件后执行:
输出类似:
tail 5678 root 3r REG 8,1 30 /tmp/test.log (deleted)
关键信息解读:
- (deleted):表示该文件已被删除,但进程还在占用
在终端二中执行恢复操作:
直接拷贝这个文件描述符即可恢复:
cp 3 /tmp/test.log.recovered
或者用 cat 重定向:
cat 3 > /tmp/test.log.recovered
为什么要加 .recovered 后缀?主要是为了做区分和对比,方便确认恢复是否成功。你也可以起任何名字,比如 /tmp/test.log.bak、/root/abc 都行,只要路径正确且有写入权限即可。恢复完成后建议先用 cat 查看内容确认无误,再考虑覆盖原文件。
三、最好的恢复是预防
通过 /proc 方法,是Linux下最“优雅”的在线恢复方式,尤其适用于日志、配置文件等被进程持续使用的场景。
但如果文件删除时没有进程在使用,那就无法通过上述方法恢复了。此时立即保护现场:将文件所在分区以只读(read-only)方式重新挂载,防止新数据写入覆盖掉空闲的数据块,依赖第三方专业工具扫描磁盘,或者从最近的备份中找回。
所以,与其寄希望于恢复,不如做好预防:
1.定时备份:重要数据定期异地备份,这是最硬的底牌。
参考链接
[1]https://www.linux.com/news/bring-back-deleted-files-lsof/
[2]https://unix.stackexchange.com/revisions/8bf63fe0-4a17-4b3e-8832-6252c01ceddf/view-source