linux下利用grep和dd命令恢复被mv命令覆盖的文件内容

查看原文,移步个人博客地址:http://shengfu.sinaapp.com/?p=683

事件起因

把之前基于linux c写的一个纯真ip查询的server代码优化、规整了下之后,想重命名一下,然后就执行了下面两行命令:

1

2

mv http.c xip.c

mv http.sh xip.c

其实我的本意是想这样:

1

2

mv http.c xip.c

mv http.sh xip.sh

事件影响 

.c文件是核心代码,.sh文件是编译c文件的几行gcc命令,上面mv命令误操作的结果就是完全覆盖了.c文件,意味这两天白忙活了。

 

事件处理

虽然代码核心的东西都在脑子里面,重新写大半天时间也差不多能搞定了,但是还是希望能够有办法恢复数据,花点时间要是能找到办法,以后有更重要的数据也能用的上。

首先想到的是用ext3grep工具恢复数据,结果centos系统直接yum是找不到包的,源码包地址在http://code.google.com/p/ext3grep/上,打开结果是404页面,用个工具也真够费劲的,另外对这个工具也不是太熟悉,暂且放弃吧。

后来通过google在这篇文章:http://unix.stackexchange.com/questions/149342/can-overwritten-files-be-recovered发现了grep和dd这条线索,这两个命令经常使用,但是真还不知道能拿来恢复数据。

 

 

恢复过程

1、确认代码所在的目录处于磁盘的哪个分区

1

2

3

4

5

6

7

8

9

10

11

12

[qidasheng@master ~]$ pwd

/home/qidasheng

[qidasheng@master ~]$ df -h

Filesystem                    Size  Used Avail Use% Mounted on

/dev/mapper/vg_qidasheng8-lv_root   50G   26G   21G  56% /

tmpfs                         7.8G   76K  7.8G   1% /dev/shm

/dev/sda1                     485M   66M  394M  15% /boot

/dev/mapper/vg_qidasheng8-data0    197G  128G   60G  69% /data0

/dev/mapper/vg_qidasheng8-data1    197G   17G  171G   9% /data1

/dev/mapper/vg_qidasheng8-data2    148G  1.6G  139G   2% /data2

/dev/mapper/vg_qidasheng8-home      64G   20G   42G  32% /home

cm_processes                  7.8G  300K  7.8G   1% /var/run/cloudera-scm-agent/process

通过上面的命令确定了代码在home目录,home目录是挂在/dev/mapper/vg_qidasheng8-home 下的。

 

2、使用grep命令在磁盘上通过被误删代码中的比较有代表性的关键字符串查找文件所在偏移位置,返回的部分内容如下,内容前面都有一个数字串,记录这个数字串

1

2

3

4

5

6

7

8

9

10

11

[root@master ~]# grep -a -b '/home/qishengfu/QQWry.Dat'  /dev/mapper/vg_qidasheng8-home

2851521881:    wry_file=fopen("/home/qishengfu/QQWry.Dat","r");

2851534169:    wry_file=fopen("/home/qishengfu/QQWry.Dat","r");

.

 

[root@master ~]# grep -a -b 'cJSON_AddStringToObject(fmt,"province"'  /dev/mapper/vg_qidasheng8-home

1862223382: cJSON_AddStringToObject(fmt,"province", trim_str(tmp[0]));

1876743751: cJSON_AddStringToObject(fmt,"province", trim_str(tmp[0]));

 

[root@master ~]# grep -a -b 'cJSON_AddStringToObject(fmt,"desc"'  /dev/mapper/vg_qidasheng8-home

1889870235: cJSON_AddStringToObject(fmt,"desc", ip_key[1]);

 

3、通过dd命令利用2中获取的的偏移信息直接从磁盘读取内容

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

[root@master ~]# dd if=/dev/mapper/vg_qidasheng8-home count=1 skip=$(expr 1876743751 / 512)

       tmp[0] = malloc(len0);

                 tmp[1] = malloc(len1);

                 strncpy(tmp[0], ip_key[0], len0);

                 strncpy(tmp[1], pos + len, len1);

cJSON_AddStringToObject(fmt,"province", trim_str(tmp[0]));

cJSON_AddStringToObject(fmt,"city", trim_str(tmp[1]));

} else {

cJSON_AddStringToObject(fmt,"country", ip_key[0]);

}

}

        if (count >=1 && ip_key[1] != NULL) {

cJSON_AddStringToObject(fmt,"place", ip_key[1]);

}

 

        if (count >=2 && ip_key[2] != NULL) {

 

注意事项:

1、 从上面数据可以看出,count=1的情况下读取的只是部分代码片段,可以把count值调大读取前后更大范围的数据;

2、第2步中获取的偏移信息不一定就是被覆盖的文件的偏移,有可能是历次代码编辑中数据的偏移,所以可以把上面获取到的偏移记录位置的数据都读取出来,然后人工核对选择最接近的数据进行汇总,就能恢复得到最近的数据啦。

 

参数解释

grep中几个参数的解释

-a用来把二进制文件当文本文件处理,-b用来保证显示查找出的结果的偏移位置

1

2

3

4

5

       -a, --text

              Process a binary file as if it were text; this is equivalent to the --binary-files=text option.      

       -b, --byte-offset

              Print  the  0-based  byte  offset  within  the  input file before each line of output.  If -o (--only-matching) is specified, print the offset of the

              matching part itself.

 

dd中使用的几个参数的解释

count指明读取多少个数据块,if指定读取源,skip指定跳过多少个块(后面除以512是因为,skip是跳过ibs-sized blocks,而ibs默认大小为512)

1

2

3

4

5

6

7

8

9

10

      count=BLOCKS

              copy only BLOCKS input blocks

       ibs=BYTES

              read BYTES bytes at a time (default: 512)

 

       if=FILE

              read from FILE instead of stdin

 

       skip=BLOCKS

              skip BLOCKS ibs-sized blocks at start of input

 

 

失而复得的心情比天上掉馅饼还好!


你可能感兴趣的:(linux下利用grep和dd命令恢复被mv命令覆盖的文件内容)