Linux下,有时候我们可能会误删除一些文件,此时除了慌张,有什么可以补救的措施?
删除文件的恢复可以分为两种情况,一种是删除以后在进程中仍存在删除信息,另一种是删除以后进程都找不到。
对于前者,可用lsof指令尝试着恢复,对于后者,就需要借助第三方工具了,今天我们测试下前者。
lsof(list open files)是一个列出当前系统打开文件的工具。在Linux环境下,任何事物都以文件的形式存在,例如,普通的文件、目录、网络文件系统的文件、字符设备文件、(函数)共享库、管道,命名管道、符号链接、底层的socket字流,网络socket,unix域名socket等。
因此,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。像传输控制协议(TCP)和用户数据报协议(UDP)套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错都是很有帮助的。
当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,他依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,他仍然可以向打开该文件时提供给他的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。
在/proc目录下,包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数和lsof相关的信息都存储于以进程的PID命名的目录中,例如/proc/1234中包含的是PID为1234的进程的信息。每个进程目录中存在着各种文件,他们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。
lsof程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。就是说我们通过访问进程的文件描述符可以找到该文件的相关信息。当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的内容。
首先,打开一个会话,执行cat追加文件,但是不退出,相当于进程一直占用该文件,
[oracle@app ~]$ echo "hello deleted" > test.txt
[oracle@app ~]$ cat >> test.txt
I'm trying deleting it.
此时打开另外一个会话,删除该文件,
[oracle@app ~]$ rm -rf test.txt
当前场景下,如果想要恢复这个文件,可以执行如下的指令,搜索“deleted"的文件,可以看到存在一条记录,我们能知道这个进程的PID是13213,FD是1,
[oracle@app ~]$ lsof | grep deleted
cat 13213 oracle 1w REG 253,8 38 1358 /home/oracle/test.txt (deleted)
我们进入/proc/PID(13213)/fd(1)/,看到1指向的就是这个被删除的文件,
[oracle@app ~]$ cd /proc/13213/fd/
[oracle@app fd]$ ls -rlth
total 0
lrwx------ 1 oracle dba 64 Jan 21 21:46 2 -> /dev/pts/0
l-wx------ 1 oracle dba 64 Jan 21 21:46 1 -> /home/oracle/test.txt (deleted)
lrwx------ 1 oracle dba 64 Jan 21 21:46 0 -> /dev/pts/0
可以看到文件的内容,
[oracle@app fd]$ cat 1
hello deleted
I'm trying deleting it.
此时想要恢复文件只需要将其复制到指定路径,
[oracle@app fd]$ cp 1 /home/oracle/test.txt
用lsof恢复文件还是很简单的,但是前提是使用这个文件的进程必须存在,如果上述操作中,关闭cat指令,/proc中就找不到这个PID了。
参考,
http://www.21yunwei.com/archives/6030
https://www.cnblogs.com/shengulong/p/11605479.html