如何创建一个与USB存储设备完全相同的镜像?

我有一个USB闪存盘,由于某种原因无法读取。为了存储目的,我想制作一个镜像,以便稍后尝试从镜像中恢复数据。

我应该如何创建一个与原USB闪存盘完全相同的镜像呢?


使用dd时我得到的错误是:

oshirowanen@desktop:~$ sudo dd if=/dev/sdd of=/USB_image
[sudo] password for oshirowanen: 
dd: reading `/dev/sdd': Input/output error
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.00783 s, 0.0 kB/s
oshirowanen@desktop:~$ 

你使用哪个十六进制编辑器? - AJMansfield
当您无法从指向USB闪存的设备/dev/sdx读取时,这是一个严重的问题,我认为普通用户没有可用的工具可以解决。请参考此链接获取更多详细信息:https://askubuntu.com/questions/144852/cant-format-my-usb-drive-i-have-already-tried-with-mkdosfs-and-gparted/933035#933035;不要立即放弃,根据可能使读取正常工作的事项列表尝试一下。也许您可以拆开USB闪存并找到一张仍然可以使用的微型SD卡,根据@ubfan1(在链接的答案中)的评论所说。 - sudodus
你有两种选择来处理你的问题:第一种简单的方法是运行sudo su,然后以root身份运行你的dd命令;第二种更高级的版本是运行带有状态和sudo bash -c 'dd status=progress if=/dev/sd* | gzip > ~/Backup-USB.img.gz'的dd命令。 - WiKrIe
5个回答

dd它!

用法类似于sudo dd if=/dev/sdb of=~/USB_image,其中/dev/sdb是您的USB驱动器,如sudo fdisk -l所列,并且~/USB_image是将进行复制的映像文件的路径(创建映像文件的路径)。

要将映像恢复到另一个USB驱动器,只需颠倒过程:sudo dd if=~/USB_image of=/dev/sdb将把~/USB_image恢复到设备sdb。只需确保新的USB驱动器与原始驱动器一样大或更大。

您还可以将刚刚创建的映像文件挂载到路径中,而无需首先将其恢复到另一个USB驱动器,使用mount ~/USB_image /mnt/USB_image -o loop


如果fdisk -l无法看到USB驱动器怎么办?然而,我可以从磁盘工具程序中看到它作为/dev/sdd,但是当我尝试使用您的命令时,似乎失败了。 - oshirowanen
失败有什么错? - Bruno Pereira
将错误添加到原始问题中,因为它对于一个评论来说太长了。 - oshirowanen
看起来你的USB驱动器坏了... dd命令可以制作一个原始副本,包括驱动器中的任何内容,我认为这是你在尝试救援这种情况下的最后选择。 - Bruno Pereira
1如果fdisk不显示设备,请使用dmesg来查看设备插入时发生的情况。dmesg是内核交互的列表,所以基本上,如果硬件在您的计算机上做了什么,dmesg中会有相应的消息。 - j0h
这是一个很好的描述,适用于功能硬件。我给它点了个踩,因为这个回答忽略了故障硬件,而原帖中明确提到了(IO错误)。 - j0h
@j0h 当Bruno回答这个问题时,问题还没有提到任何关于I/O错误的内容。原帖在这个回答之后才添加了这个问题。 - Wayne Conrad
@WayneConrad,我总是假设存在磁盘错误,并进行检查。有一些方法可以确保每次都获得良好的结果。“它可能有效,有时候”并不是一个好的答案。 - j0h
注意:在 macOS 上,of=~/USB_image 部分将无法工作。您必须使用 of=$HOME/USB_image - serghei
只是一个警告,因为默认情况下,dd命令不提供进度条...16GB的存储器在USB 1.0端口上需要几个小时:X ...在USB 2.0端口上则需要10分钟。 - Alex
3@Alex 在Ubuntu上使用status='progress'dd命令,或者找出你的dd命令的PID并发送SIGUSR1信号。不过其他实现方式我就不确定了。 - Sergiy Kolodyazhnyy

使用ddrescue。它会在错误后继续进行,而dd则会失败。
此外,ddrescue已经包含在软件库中。在13.04版本上,我输入sudo apt-get install gddrescue来安装。
使用sudo fdisk -ldmesg来确定设备位置,例如:/dev/sdb,然后运行类似以下命令的命令:
ddrescue /dev/sdb /home/user/desktop/bkp.img

有很多选项可以使用ddrescue,你可能想要阅读一下man页面。另外,我不确定为什么你的硬件会出现问题,并且导致dd崩溃。一个坏块可能会导致dd停止工作,但间歇性的电源故障也可能是原因。通过dmesg命令,你可能会了解更多关于可能发生的硬件故障。

确保设备没有挂载!在进行数据恢复、镜像等操作时,这可能会引起问题。

数据恢复中有很多事情可能会出错。如果你遇到问题,请回复。一旦你有了镜像文件,testdisk是一个很好的用于数据恢复的工具。

只是为了澄清,这是一个USB硬盘还是USB(固态存储)设备?

I/O错误通常表明硬件故障而不是文件系统损坏。

另外,尝试获取设备的SMART数据分析,如果可用的话。这可能告诉你一些信息,比如设备是否过热、长时间开机、有坏扇区、承受了超过X个G的冲击等。


USB存储设备,没有SMART数据可供分析...我还认为你需要在ddrescue中使用sudo,*如果简单地失败,dd是不太正确的,因为你可以配置dd忽略读取错误。当你能够读取到丢失的数据扇区时,testdisk非常棒**,而驱动器已经死亡时则不行。 - Bruno Pereira

是根的符号,所以不需要sudo。如果是$,那么就需要。

- j0h
我还想指出,如果ddrescue甚至dd失败了,但你能够生成一个镜像,你仍然可以尝试对该镜像进行数据恢复。 - j0h
我建议使用gddrescue而不是ddrescue,因为gddrescue更新且能够完成ddrescue所做的工作。 - Bruno Pereira
1我都不知道,兄弟,看看我的帖子。gddrescue是软件包,而ddrescue是命令。 - j0h

你可以使用dd命令来创建一个USB闪存驱动器(或其他设备)的镜像。
例如:
dd if=<usb device> of=usb.img

你可以在 dd 命令中添加更多参数来优化命令(例如 bs)。

正如之前的评论所提到的,dd是最佳选择。不过,你可能希望它在错误发生时继续执行,这样你可以这样开始:
dd if=<usb device> of=<new file on disk with enough space> bs=<should match your blocksize> conv=noerror,sync 

重要的部分是最后一部分:conv=sync告诉dd用零填充所有那些只能读取部分的块,所以生成的映像可能会多出一些零,但在结构上与有故障的磁盘相等,减去了其读取错误。conv=noerror处理了这些读取错误,告诉dd继续下一个块。在此时,块大小很重要,如果它大于跳过错误所需的大小,将丢失可读数据。
块大小应始终为二的倍数-如果不确定,512k应该适用。
然后我建议:
  • 将未修改的映像存储到安全的位置
  • 对磁盘映像进行fsck检查
  • 挂载磁盘映像
  • 检查文件-现在可以无问题地读取它们,但某些文件可能丢失或被截断
  • 如果设备根本无法读取,你可能就没办法了。另外,如果设备恰好包含一些专有软件,当访问前几个块时可能设置为返回读取错误。
(部分引用自2010年撰写的一篇文章)
如果您不需要保持原汁原味,您可以尝试一些旨在简化过程的工具,例如ddrescue(软件包gddrescue)及其伴侣ddrescueview(sourceforge),以可视化错误。

关于你的问题的后半部分“在使用dd命令时出现的错误”,我可以看到几种可能性。
1. 请注意你输入的命令与被接受的答案之间的差异;你忘记在`/USB_image`前面加上一个`~`。换句话说,你试图将输出定向到文件系统的根目录而不是你的主目录。
2. `/dev/sdd`可能不是正确的驱动器。运行`sudo fdisk -l`命令,并将驱动器的大小与已知的USB闪存盘大小进行比较。例如,我知道这是我的USB闪存盘,因为它接近16GB:`磁盘/dev/sdf: 15.8 GB, 15805186048 字节`。