最近《软件开发与设计实践》的课程快要到结束啦,于是打算抓着这最后几天的时间再来优化一下代码吧。测试了一会,发现没什么大问题了。突然发现工程目录下多了几个碍眼的文件夹,我整整齐齐的代码怎么能被几个文件夹影响到呢,看我来个"rm",就像下面那样。
sudo rm ***
命令打完后,想到代码目录如此整洁,我不禁露出充实而欣慰的微笑。出于习惯,我打下了一个"ls"用来查看目录内容。风吹着窗帘嗒嗒的响,我渐渐发现事情没那么简单。立马查看历史记录,发现了绝望的一幕。
那个pm就是整个核心代码的目录,然而不知发了什么神经的我把它给删了。
太阳穴隐隐有些发麻。突然想起关于"rm"命令的种种趣闻, 总有人会用
sudo rm -rf *
来调侃,每次看到只当成玩笑,可是没想到自己也会有这种脑子短路的操作。
大脑在快速查找有关误删除操作的知识。删除操作只是清空了inode里的内容,实际上数据存储在block块内,如果block块的内容没有被覆盖,理论上还是有可能恢复的。现在我需要一个强大的恢复工具,于是我打开了浏览器。实际上这是一个非常错误的操作,由于误删的文件与当前的登录用户位于同一个分区中,这个时候应该尽快取消挂载目标分区,因为如果对这个分区的文件进行写操作有可能会覆盖误删文件的block块内的数据,那就几乎很难恢复了。
后来又恰好发现,当时我正好开了一个进程使用vim对其中一个误删的文件进行操作。由于vim编辑文本时是将内容加载到内存的,所以当时有两个选择,一是将文件写回到硬盘里,那么至少可以保留一个文件,但是缺点是,如果把它写回原路径,如前面所说,会有非常大的可能覆盖其他文件的block块,导致其他文件无法恢复。二是将其直接丢弃,换取恢复其他文件的希望。
但是我没得选。因为太贪心了,想着有没有可能我用vim打开了多个文件,于是切换了vim的缓冲区。但是因为不了解vim的缓冲区不会一直保留在内存里,换句话说就是被动做了第二个选择。其实这个局面最好的解决办法是将内存写入到其他分区,这样既可以保留一个文件,也不会覆盖block块。
在对着屏幕发呆了10分钟后(减少对目标分区的写操作),只能把桌面环境关闭,进入控制台,取消挂载目标分区。
刚开始使用的恢复工具是extundelete,尝试了好几次,每次都提示我找不到可恢复文件。一度陷入绝望,想到好几个月来的付出就这样没了,甚至在距离答辩的最后这几天能不能再写出来都说不准,还会挂科,就觉得风好大,眼睛都进石头了。
后来又在某些个角落看到还有一个工具foremost。下载,执行
foremost -t cpp /dev/sda7
"-t" 指定文件类型,就是cpp,"/dev/sda7"就是目标分区。
命令执行了有好几分钟。几分钟挺长的,我已经把这几天的残酷生活都在脑子里演绎了几遍。
执行完成了,看看输出,生成了一个文本文件"audit.txt"和一个文件夹"cpp"
文本文件里列出了cpp文件夹下面的文件。
cpp文件夹下有大概8万个后缀为cpp的文件,一共1.5G,而且命名没有规律。后来我猜测是以inode号命名的。问题是这是啥?只能猜测是从inode号恢复出来的文件。于是试试用误删文件的一些特征函数名对这些文件进行匹配,看到结果如下。
与误删文件部分内容大致吻合。剩下的就是耐心的写脚本匹配,然后打开所有可能的文件一个个核实了。
说起来容易,实际上没有一个文件是完整恢复的,能有一个大片的连续片段的也算比较好了。最终有一半的文件是可以恢复出大块连续片段的,一小部分是只能找到一些旧版本的片段,有几个文件是完全恢复不了的。
自此,我懂得了备份的重要性。最后还是要补代码丫。。。