覆盖的文件可以恢复吗?


42

我不是在谈论恢复 已删除的文件,而是覆盖文件。即通过以下方法:

# move
mv new_file old_file

# copy
cp new_file old_file

# edit
vi existing_file
> D
> i new_content
> :x

如果在Linux机器上未安装任何特殊程序的情况下执行了以上三个操作中的任何一个,是否可以检索任何内容?


4
您的意思是除了备份?
2014年

@jasonwryan,是的,当然。
2014年

2
我只想指出,您的第一个示例(mv)与old_filedelete 相似,而不是覆盖它,因此在这种情况下,适用于恢复已删除文件(而不是覆盖文件)的方法(如果有)。您的其他两个示例确实确实覆盖了一个现有的old_fileexisting_file
Celada 2014年

您提供的所有三个示例都是通过删除所有原始文件的数据块并写入新分配的块来实现的,恢复该数据的过程与恢复已删除文件的过程相同。如果原始文件非常短(ext4上少于60个字节),则可能是一个例外,后两个示例可能会使先前的数据无法恢复。
Mark Plotnick 2014年

1
根据Celada的评论,@ MarkPlotnick mv是不同的。
2014年

Answers:


60

答案是“可能是,但这取决于文件系统的类型和时间。”

除偶然的情况外,这三个示例均不会覆盖old_file或existing_file的物理数据块。

  • mv new_file old_file。这将取消链接old_file。如果还有其他指向old_file的硬链接,则这些剩余链接中的块将保持不变。否则,通常将这些块(取决于文件系统类型)放置在空闲列表中。然后,如果mv需要复制(而不是仅移动目录条目),则将新块分配为mv写操作。

    这些新分配的块可能与刚刚释放的相同或不同。在UFS之类的文件系统上,如果可能,在与创建文件所在目录相同的圆柱组中分配块。因此,有可能重新使用目录中的文件并在该目录中创建文件(并覆盖)一些刚刚释放的块。这就是为什么对不小心删除文件的人的标准建议是在有人尝试恢复文件之前,不要将任何新数据写入其目录树中的文件(最好不要写入整个文件系统)。

  • cp new_file old_file将执行以下操作(您可以strace用来查看系统调用):

    打开(“旧文件”,O_WRONLY | O_TRUNC)= 4

    O_TRUNC标志将导致所有数据块被释放,就像mv上面一样。并且如上所述,它们通常将添加到空闲列表,并且可能会也可能不会被cp命令执行的后续写入重用。

  • vi existing_file。如果vivim,则该:x命令将执行以下操作:

    unlink(“ existing_file〜”)= -1 ENOENT(无此文件或目录)
    重命名(“ existing_file”,“ existing_file〜”)= 0
    打开(“ existing_file”,O_WRONLY | O_CREAT | O_TRUNC,0664)= 3

    因此,它甚至都不会删除旧数据。数据保存在备份文件中。

    在FreeBSD viopen("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664),dos的语义与cp上述相同。


您无需特殊程序即可恢复部分或全部数据。您需要的是grepdd,并且可以访问原始设备。

对于小型文本文件,最简单的方法是在链接到问题的@Steven Dgrep答案中使用单个命令:

grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1

但是对于可能在多个不连续块中的较大文件,我可以这样做:

grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file

这将为您提供匹配行的字节偏移量。遵循以下一系列dd命令,从

dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)

您还希望阅读该块前后的一些块。在UFS上,文件块通常为8KB,通常分配得相当连续,单个文件的块与来自其他文件或可用空间的8KB块交替插入。UFS上文件的尾部最多包含7个1KB的片段,这些片段可能是连续的,也可能不是连续的。

当然,在压缩或加密数据的文件系统上,恢复可能不是那么简单。


Unix中实际上很少有实用程序会覆盖现有文件的数据块。我想到的是dd conv=notrunc。另一个是shred


3
感谢您解释这三种不同操作的内部机制。这真的很有用!
2014年

btrfs对已删除的文件具有相当的弹性。它倾向于以循环方式使用块,因此,如果设备上有足够的空间,则文件不会长时间被覆盖。看到这里
pqnet

如何获得前面的文本块,跳过会做什么?
unixit 2015年

@Islam当给dd skip=参数时,它将跳过该数目的块,而不是从输入的开头读取。默认情况下,块为512字节,但可以使用bs=参数进行更改。
Mark Plotnick

1
@Islam为了获得前面的文本块,我建议给出一个skip=少1块(512字节)的值。在我的示例中,$(expr 13813610612 / 512 - 1)。如果仍然不能满足您的要求,请在减去16或32的同时重试,这将减少8192和16384字节的区域;文件通常以8192字节的块分配。如果要恢复较大的文件,请尝试增加计数以节省时间。我通常使用count=16并在像emacs这样的编辑器中查看结果,它不介意某些数据不是文本。
Mark Plotnick

6

我要说不(带有一个巨大的星号)。

考虑一下如何将数据放置在磁盘上。您有包含数据并指向下一个块(如果有)的块。

覆盖数据时,您将更改块内容(如果要扩展文件,则所有结尾标记都将更改)。因此,任何内容将无法恢复(请参见下文)。

如果缩短文件,那么您将丢失旧的块,它们将很快被回收。如果您是一名程序员,请考虑一个链表,其中您“丢失”了清单的一半而没有进行自由/删除操作。该数据仍然存在,但是很幸运找到它。

可能有趣的事情是碎片。

当磁盘上有“不连续”数据的“空洞”时,就会发生碎片。这可能是由于修改文件导致扩展或缩短文件而导致的,这些文件不再适合磁盘上的原始位置。

如果文件超过其原始大小(此时需要移动),则可以根据您的文件系统将整个文件复制到新位置,在该位置旧数据仍会存在(但标记为空闲)或者,您只需更改旧的结尾指针并将其指向新位置(这将导致颠簸)。

长话短说,您的数据可能会丢失(没有经过在显微镜下查看数据的极端取证过程);但是,仍有可能仍然存在。


1
你的回答使假设基于块的非写入时复制文件系统,比如ext4xfs正在使用中。实际上,使用诸如zfsand 这样的写入文件系统时,btrfs永远不会 “更改块内容”;这些文件系统始终使用全新的块来包含新数据。同样,基于日志的文件系统jffs2也总是将新数据写入新位置(不是“块”,这些文件系统不是基于块的)。话虽如此,这并不意味着在回收空间之前很容易找到旧数据所在的位置并轻松进行处理。所以你的答案,这是否定的,仍然是正确的
切拉达

@Celada谢谢!我发现这非常有用。我没有时间研究btrfs或zfs的工作原理,但是我知道它们存在。
SailorCire

2

确保在/ var / tmp或更大的地方有足够的磁盘空间。

尝试

 grep -i -a -B100 -A100 'a string unique to your file' /dev/sda1 |
 strings > /var/tmp/my-recovered-file

/ dev / sda1是系统上的磁盘。

然后在my-recovered-file中搜索您的字符串。

可能大部分都在那儿,如果找到它,请检查缺少的行距,方括号,sysmbols等。

使用文件中的搜索词,该搜索词很不合理,或者使用字符串,这会减少文件中的数据量。如果您搜索诸如“ echo”之类的单词,您将获得大量的字符串,因为系统将包含许多带有单词echo的文件。


0

我已经用12个小时的测试数据覆盖了文本文件(VQ1.txt):列表显示VQ1.txt〜包含我的“丢失”数据!

$ cat VQ1.txt~  
Start time at: Thu Apr  2 18:07:23 PDT 2015
User, KW: 12hrFA_OEM_HelloVoiceQ
Test Case: 
Detection:  1, 1, 04-03 01:07:00.673 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  2, 1, 04-03 01:09:04.813 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  3, 1, 04-03 04:09:26.023 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  4, 1, 04-03 04:11:29.893 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  5, 1, 04-03 07:12:27.013 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  6, 1, 04-03 07:14:30.803 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  7, 1, 04-03 08:37:13.113 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  8, 1, 04-03 10:21:23.533 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  9, 1, 04-03 10:23:27.733 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  10, 1, 04-03 13:23:47.893 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  11, 1, 04-03 13:25:52.203 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1

12hrFA_OEM_HelloVoiceQ,  
KW detect count: 11

4
难道这不是某些文本编辑器的功能,而不是一般而言的Unix吗?我不知道以这种方式保存旧版本文件的文件系统。
乔伊

0

TL; DR-如果正在运行的进程仍将覆盖的文件保持打开状态,则此博客文章可能会节省您的培根:

https://www.linux.com/news/bring-back-deleted-files-lsof/

在其中,它讨论了已删除的文件,但是即使有被rsync覆盖的文件,我也很幸运。我说的是60 GB的文件被4 MB的文件覆盖,并且能够恢复原始文件,因为幸运的是,我没有停止正在使文件保持打开状态的运行过程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.