这是我第一次使用 dd 命令。我执行:
dd if=/dev/sdb2 of=/mnt/sdc1/Hdd1.img bs=512 conv=noerror,sync
Run Code Online (Sandbox Code Playgroud)
其中 sdb 是损坏的硬盘(大小:500 GB)。我将分区 sdb2 复制到映像中。我已经完成了 6(!!) 天。img 大小约为 640 GB 并且仍在计数(即:它还没有完成......)。6 天它正在打印复制的数据详细信息(它复制到哪个字节)并且它没有停止。
正常吗?img 大小怎么可能大于整个损坏的硬盘大小?什么时候完成?
通过一次复制 512 个字节,您将进行大量的读取和写入。实际上,如果你算一算,大约有一万亿。您还要求同步 [编辑:这不是oflag=sync
所以下一个语句无效],这意味着等待每次写入实际写入磁盘之前,该写入可以返回。假设您的磁盘速度非常快,因此每次写入需要 2 毫秒。
500GB / 512 字节 * 2ms = 22.6 天。
哇,数万亿毫秒加起来很快,不是吗?
[编辑:虽然这当然是一个有趣的数学,但它不准确,因为oflag=sync
没有使用。延迟更有可能是由于重复读取坏扇区和相关超时造成的。下面的 dd_rescue 方法应该会有所帮助。使用具有更大块大小的普通 dd 可能会有所帮助,但作用不大,因为它无法适应其读取大小并且不会跳过大量损坏。]
如果您使用更大的块大小和/或跳过同步,它将运行得更快:
# dd if=/dev/sdb2 of=/sdb2-image.img bs=1024k
Run Code Online (Sandbox Code Playgroud)
如果您担心 sdb2 映像读取的读取错误,请使用带有 -A 选项的 dd_rescue 来写出一个零块,而不是跳过该写入。当某些文件系统结构从一开始就出现在与最初不同的偏移量时,完全跳过有错误的块可能会导致问题。最好有一些意外的零。例如:
# dd_rescue -A /dev/sdb2 /sdb2-image.img
Run Code Online (Sandbox Code Playgroud)
这将开始一次读取大块数据,只有在开始遇到错误时才会减少它。
编辑:直接回答这个问题,正如迈克尔约翰逊所建议的那样,当使用conv=noerror,sync
ondd
或-A
on 时dd_rescue
,您的图像最终将与您的来源完全相同。这是因为每次读取都会生成相同大小的写入。某些版本dd
可能会在设备末尾运行很长时间,因为它们会根据您的conv=noerror
请求忽略文件结尾“错误” 。我不认为 Linux 会这样做,但是如果您的图像似乎比源文件大,则需要注意。