日期:2014-05-16  浏览次数:20694 次

linux恢复意外删除的文件

author:skate
time:2013/10/12

 

linux恢复意外删除的文件

 

当进程打开某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。在这种情况可以通过lsof来恢复这些文件。

在/proc目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数与lsof相关的信息都存储于以进程的PID命名的目录中,即/proc/12中包含的是PID为12的进程的信息。每个进程目录中存在着各种文件,它们可以使应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。lsof程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。

下面举例说明

我/tmp目录下创建了脚本文件,时刻在后台运行,但是tmp目下会被系统定时删除的,但犯懒不想重写脚本,想把原来的找回,具体步骤如下。

 

1.查看已经被删除的文件diamon.sh,已经不存在了

[root@centos5 ~]# ll /tmp/
total 28
-rw-r--r-- 1 root  root   402 Sep 26 14:19 load_tab.sh
srwxrwxrwx 1 mysql mysql    0 Sep 16 15:20 mysql.sock
drwx------ 2 root  root  4096 Oct 12 15:44 ssh-hiPBw10887
drwx------ 2 root  root  4096 Oct 10 16:12 ssh-lUXbjf6337

 

2. 使用lsof来查看当前哪个进程正在打开文件”/tmp/diamon.sh“
[root@centos5 ~]# lsof | grep diamon
sh         8455      root  255r      REG              253,0        173               764298 /tmp/diamon.sh (deleted)
[root@centos5 ~]#

 

从上面的输出可以看到,进程8455正在以只读的方式打开这个文件,打开的文件描述符为255,同时文件/tmp/diamon.sh被标记删除。然后我查看文件" /proc/8455/fd/255"

 

[root@centos5 ~]# more /proc/8455/fd/255
#variables
dir=/tmp

while (true)
do
v_num=`ps -ef | grep load_tab | grep -v grep | wc -l`
 
if [ $v_num -lt 4 ] ; then
  sh /tmp/load_tab.sh > /dev/null 2>&1 &
fi
done
[root@centos5 ~]#

 

3. 已经找到已经被删除的文件了吗然后利用I/O重定向将其恢复到指定文件中,如下

[root@centos5 ~]# cat /proc/8455/fd/255 > /tmp/diamon.sh

 

检查文件已经被恢复了
[root@centos5 ~]# ll /tmp
total 36
-rw-r--r-- 1 root  root   173 Oct 12 16:53 diamon.sh
-rw-r--r-- 1 root  root   402 Sep 26 14:19 load_test10.sh
srwxrwxrwx 1 mysql mysql    0 Sep 16 15:20 mysql.sock
drwx------ 2 root  root  4096 Oct 12 15:44 ssh-hiPBw10887
drwx------ 2 root  root  4096 Oct 10 16:12 ssh-lUXbjf6337
[root@centos5 ~]#

 

查看恢复的文件内容是否正常
[root@centos5 ~]#
[root@centos5 ~]# more /tmp/diamon.sh
#variables
dir=/tmp

while (true)
do
v_num=`ps -ef | grep load_test | grep -v grep | wc -l`
 
if [ $v_num -lt 4 ] ; then
  sh /tmp/load_test10.sh > /dev/null 2>&1 &
fi
done
[root@centos5 ~]#

至此linux恢复删除文件成功结束


总结:
A.在文件被删除时,不要慌,尽可能保存现场
B.对于某些数据库文件被误删除很有效

 

 

---end----