首页 > Sysadmin > 正文

Linux 误删文件恢复:先止损再动手

huyuanwen 2026-10-30 Sysadmin

rm 没有回收站,但误删后并非立刻没救——只要分区还在、数据没被覆盖,就有恢复窗口 [1]。

先止损:卸载或只读挂载

文件被删后,内核只是把 inode 标记为可复用,数据块还在磁盘上。继续写入会产生新文件,覆盖旧数据。所以第一步是把该分区设为只读或卸载:

lsblk
umount /dev/sdb1
mount -o remount,ro /dev/sdb1

如果根分区被误删,umount 可能做不到——此时先别往该目录写新文件,尽快断电进 Live CD 处理 [2]。

进程还开着:从 /proc 直接捞回

如果某个进程还持有着被删文件的文件描述符,即使 ls 已经看不到它,也能从 /proc/<PID>/fd/ 恢复。WSL2 Ubuntu 24.04 实测:tail -f 打开的文件被 rm 后,/proc/PID/fd/3 仍指向原路径 (deleted),cat 出来内容完整。

lsof | grep deleted
ls -l /proc/<PID>/fd
cat /proc/<PID>/fd/<FD> > /path/to/recovered

实测记录:echo "secret data 12345" > /tmp/keep.txt,tail -f /tmp/keep.txt &,rm /tmp/keep.txt,cat /proc/<PID>/fd/3 正确输出 secret data 12345。这条方法只适合“文件被删但进程未关”的场景,关掉进程就没了 [2]。

ext3/ext4 专用:extundelete 实战

extundelete 通过文件系统的日志和旧 inode 恢复 ext3/ext4 上刚删的文件。要求:目标分区必须处于卸载状态 [3];如果 journal 已重播,恢复成功率下降。官方手册建议先 e2fsck -f 再恢复,避免读取到不一致的元数据 [3]。

apt-get install extundelete
extundelete --restore-file secret.txt /dev/sdb1
extundelete --restore-directory docs /dev/sdb1

注意:extundelete 对 XFS、Btrfs、ZFS 无效;只认 ext3/ext4 [3]。

全盘/分区扫描:testdisk 与 photorec

当 inode 已被覆盖或文件系统不是 ext3/4 时,需要按签名扫描。testdisk 既能修分区表也能捞文件,photorec 则按文件头签名做 carve,忽略目录结构 [4]。

testdisk /dev/sdb
photorec /dev/sdb

photorec 恢复的文件名会丢失,需要事后按大小/日期人工筛选;如果磁盘被新数据覆盖过,签名也可能被毁 [4]。

debugfs 查看删除 inode

如果只是误删且分区没卸载太久,debugfs 可以直接查看删除 inode 并导出 [5]。

debugfs -R "lsdel" /dev/sdb1
debugfs -R "cat <1234>" /dev/sdb1

lsdel 列出已删除但尚未被重用的 inode;cat <inode> 按 inode 号读取内容。这个方法对 journal 已重播的系统基本无效 [5]。

回滚、排错速查与局限

  • 没有通用的“撤销 rm”。恢复前最好把整盘做镜像(ddrescue),再在镜像上操作。
  • lsof | grep deleted 没结果 = 没有进程还持有该文件,句柄恢复不适用。
  • extundelete 报 Operation not permitted:常见原因是分区已挂载,或 root 权限不够。
  • photorec 扫描很慢,且恢复文件无原名,适合最后一步。

四个常见问题:误删后第一时间该做什么——立刻停止向该分区写入,能卸载就卸载;关闭终端后还能恢复吗——lsof 恢复依赖进程存活,关终端后失效;extundelete 支持 XFS 吗——不支持,XFS 用 xfs_undelete 或 testdisk;rm -rf 删了整个目录能恢复吗——extundelete --restore-directory 可以尝试,但子文件越多越慢。

状态:草稿待审。已实测:lsof 从 /proc/PID/fd 恢复被删文件;其余工具仅文档核查,尚未在 WSL 中完整恢复流程。


参考资料

文中主要命令已在 WSL Ubuntu(24.04)实测,个别条目(未装工具/安装类命令)仅核对官方文档,未实际执行。