把以前基於linux c寫的一個純真ip查詢的server代碼優化、規整了下以後,想重命名一下,而後就執行了下面兩行命令:linux
1centos 2app |
mv http.c xip.c工具 mv http.sh xip.c優化 |
其實個人本意是想這樣:ui
1this 2google |
mv http.c xip.cspa mv http.sh xip.shunix |
事件影響
.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 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 下的。
二、使用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]); |
三、經過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) { |
注意事項:
一、 從上面數據能夠看出,count=1的狀況下讀取的只是部分代碼片斷,能夠把count值調大讀取先後更大範圍的數據;
二、第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 |
失而復得的心情比天上掉餡餅還好!