假设我们有一个硬盘磁盘,其块编号为:0、1、2、3、4 等...
我假设该命令将从块 0 开始按顺序读取磁盘块(1、2、3、4……),对吗?
sudo dd if=/dev/nvme2n1 of=/dev/null bs=1M
如果我Ctrl+C该过程并再次运行此命令,是否仍会dd
从块 0 读取?
答案1
它从 0 开始,每次增加 1,直到到达末尾。
实际上,dd 不会决定顺序,而是内核决定。在复制过程中,dd 不会指定要读取哪些扇区,它只使用通用的“从中读取 X 个字节”当前位置“系统调用并依靠内核来跟踪“当前位置”的实际位置。
每当程序打开任何块设备时,位置总是从 0 开始,就像常规文件一样。当 dd 调用 read(1MB) 时,它会接收 1MB 的数据,并且位置会相应地增加 1MB。位置是针对每个“打开的文件”而不是每个设备进行跟踪的,因此当您再次运行 dd 时,它将再次从 0 开始。
请注意,这些操作是以字节为单位,而不是以磁盘扇区为单位的,并且“块”bs=
实际上并不是指磁盘块;它是“dd”一次要求读取的数据量。“dd”块大小应该为获得最佳性能,它是磁盘扇区大小的倍数,但从技术上来说并不要求匹配。
(换句话说,dd
其工作原理几乎与完全一样cat /dev/nvme0n1p1 > /dev/null
。与使用“cat”或“cp”执行相同操作相比,使用“dd”复制磁盘的唯一真正优势是,如果启用它,它具有进度显示。)
您可以使用类似skip=
(aka iseek=
) 的选项让“dd”跳过一定数量的块,即在输入文件中寻找特定位置(与seek=
/结合oseek=
用于输出),例如运行dd if=.. of=.. iseek=1G oseek=1G
将在 1GB 处恢复。(当输出是常规文件时,您还需要让oflag=append conv=notrunc
dd 附加到输出而不是截断。)
最好使用专门为增量复制设计的工具,例如救援。
ddrescue /dev/nvme0n1 /dev/null /tmp/ddrescue.status