大家都知道在 Windows 系统下都会有一个回收站,当我们在 Windows 下误删除一个文件时,可以在回收站里进行还原即可。但是 Linux 它不像 Windows 一样有回收站,当误删除文件时当然也不是简单的还原就可以。那么 Linux 下万一不小心删除了重要文件,还有机会挽救吗?答案是当然可以啦,本文就教大家怎么在 Linux 系统中恢复误删除的文件。
Linux 中还原删除文件可以分成两种情况:
-
删除以后在进程中存在删除信息,这种情况恢复起来也是相对容易的; -
删除以后进程中没有删除信息,即连进程都找不到,这种情况也可以进行恢复,但是需要借助于工具来进行还原。
以下对于上述提到的两种情况会分别进行介绍:
一、误删除文件进程还在的情况
这种一般都是有活动的进程存在持续的标准输入输出,可以理解为当文件被删除后,进程号(PID)依旧存在。这也就是有些服务器删除一些文件但是磁盘不释放的原因。此处需要介绍一个 Linux 命令 lsof
,lsof
(list open files)是一个列出当前系统打开文件的工具。实际上这个命令并不能直接用来恢复文件,不过它可以列出被各种进程打开的文件信息。配合其他命令,从 /proc 目录下的信息中恢复“文件已删除,但进程仍保持打开该文件的状态”的文件。
/proc 目录是挂载的是在内存中所映射的一块区域,当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。因此,当我们对文件进行读取或写入时(即有进程正使用文件时),哪怕硬盘中的该文件已删除,还可以从内存中的信息恢复文件。
**注意:**必须以 root 用户的权限运行, 因为 lsof
需要访问核心内存和各种文件。
只能恢复“文件已删除,但进程仍保持打开该文件的状态”的文件。如果误删了目录,目录中的其他文件未被进程打开,没有进行使用的文件将无法使用此方法恢复。
说了这么多,我们来实际模拟一下删除文件并恢复的整个过程:
1)创建一个测试目录,然后随便拷贝一个文件到该目录下:
$ mkdir /test
$ cp /etc/passwd /test/
2)此时在另一终端对这个测试文件做 cat
追加操作,并在当前终端中删除该文件(模拟环境应该先 cat
追加再删除):
3)使用 lsof
查看删除的文件进程是否还存在
很幸运这种情况下进程还存在,那么现在我们来进行恢复操作。在此之前,先简单介绍下 lsof
这个命令的输出信息:
COMMAND 进程的PID(进程标识符)
USER 进程所有者
FD 用来识别该文件(文件描述符)
DEVICE 指定磁盘的名称
SIZE 文件的大小
NODE 索引节点(文件在磁盘上的标识)
NAME 打开文件的确切名称
4)恢复操作
首先切换到删除文件对应的 PID 目录,并且执行查看这个目录下具体信息:
$ cd /proc/1820/fd/
从上图可以看出,1 对应指向的文件是损坏的需要进行恢复,那么:
$ cp 1 /test/passwd_bak
通过对比不难看出,我们通过切换到 /proc 下,删除文件对应的进程的 PID 下的文件描述符中的目录中;将对应的内容重定向或 cp
到其他文件中,便可完成恢复操作。
二、误删除的文件进程已经不存在,借助于工具还原
第二种情况我们需要借助于工具进行恢复。extundelete 是一个文件恢复工具,它支持 ext3、ext4 双格式分区恢复。在使用前,要将要恢复的分区卸载或挂载为只读,防止数据被覆盖使用。
原理:使用存储在分区日志中的信息,尝试恢复已从 ext3 或 ext4 的分区中删除的文件。
关于 extundelete 的安装,首先下载安装包并进行解压:
$ wget http://downloads.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
$ tar -jxvf extundelete-0.2.4.tar.bz2
切换到对应目录中,进行编译安装:
$ cd extundelete-0.2.4/
$ ./configure
对于编译过程中遇到的报错,大多是因为缺少依赖,所以需要先安装依赖关系,安装完成之后重新 configure
:
$ yum install gcc-c++ e2fsprogs-devel e2fsprogs* -y
$ ./configure
当出现上面红框中圈出来的字眼表示安装成功
$ make && make install
到此,extundelete 已经安装完成,根据上面的提示,会在当前目录创建一个 src 目录,切换进去可以看到一个绿色的 extundelete ,表示可执行,此时可以使用 -v
选项来查看版本:
$ extundelete -v
extundelete version 0.2.4
libext2fs version 1.42.9
Processor is little endian.
至此,安装已经完成!接下来需要模拟一下误删除的环境,这里不再具体演示误删除环境的创建过程,直接演示一下环境搭建的结果:
$ tree
.
|-- lost+found
|-- mysql-community-server-8.0.22-1.el8.x86_64.rpm
|-- packages
| |-- my.cnf
| -- mysql-8.0.22-winx64.zip
|-- passwd
-- shadow
之后在对需要恢复文件的分区解除挂载:
$ df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 486M 0 486M 0% /dev
tmpfs tmpfs 496M 24K 496M 1% /dev/shm
tmpfs tmpfs 496M 692K 495M 1% /run
tmpfs tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/vda1 ext3 20G 4.4G 15G 24% /
tmpfs tmpfs 100M 0 100M 0% /run/user/0
tmpfs tmpfs 100M 0 100M 0% /run/user/1001
/dev/vdb1 ext4 9.8G 281M 9.0G 3% /deletedate
$ umount /deletedate
环境部署完成,接下来我们来进行恢复操作的演示,首先查看可以恢复的数据:
$ extundelete /dev/vdb1 --inode 2
跟上面部署环境时 tree
结果对比,扫描出来的文件是一致的,既然已经扫描出了对应的文件,那么该如何恢复呢?
-
恢复单个目录,需要指定恢复的目录名,如果是空目录,则不会恢复
$ extundelete /dev/vdb1 --restore-directory packages
-
恢复单个文件,需要指定具体的文件名
$ extundelete /dev/vdb1 --restore-file shadow
-
恢复全部删除的文件,无需指定文件名或目录名,恢复全部删除的数据
$ extundelete /dev/vdb1 --restore-all
当执行恢复文件的命令后,会在执行命令的当前的目录下生成 RECOVERED_FILES 目录,恢复的文件都会放入此目录中。如未生成目录,即为失败。
无论在哪个系统中,删除文件都是必须谨慎的操作。因为如果不小心删除了重要文件,就会导致个人或公司出现重大的损失。虽然有软件可以对误删的数据进行恢复,但是完全恢复数据的概率并不是百分百的。因此,使用 rm
命令删除文件的时候,一定要小心;重要的数据一定要有备份;并且恢复删除的数据前,删除文件的目录内不能往进存放新东西,否则覆盖掉的信息无法找回。