我正在将驱动器复制到文件,但低估了它占用的空间量。因此,我的目标驱动器上的空间不足,并且不想中止该进程(它已经在损坏的驱动器上运行了很长一段时间)。
我当然可以使用 CTRL-Z 暂停 dd,并且我想将目标驱动器替换为更大的驱动器,并将文件复制到更大的驱动器,然后恢复 dd。关于如何实现这一目标有什么想法吗?
dd if=/dev/sdc conv=sync,noerror bs=64M | gzip -c -9 > /media/extD/drive.img.gz
Run Code Online (Sandbox Code Playgroud)
编辑:对于那些提到 ddrescue 是一个更好使用的工具的人,你是对的。然而,无论出于什么原因,ddrescue 不断地呕吐并出错,而 dd 却只是毫无怨言地一路走来。
这是可能的,但有点痛苦。
首先,知道如果发送USR1dd信号,则打印其在副本中的当前位置(复制的字节)。所以找到的PID,使用任一或类似或的东西(不是POSIX,也不是在所有 unix-y 系统 IIRC 上)。ddpspidofpgrep
一个ps对我有用的命令(也在debianawk环境中使用 , ):
ps aux|awk '/dd/ {print $2}'|grep -v awk
Run Code Online (Sandbox Code Playgroud)
grep -v awk对于防止打印PID也是必要的awk。
PID为,发送USR1信号:dd
kill -USR1 [pid of dd]
Run Code Online (Sandbox Code Playgroud)
正在运行的控制台窗口dd将打印它复制了多少字节。你现在可以dd真正杀人了(ctrl+c,kill -9等等)。我不记得如果在POSIXdd中以这种方式终止,是否报告中止进度,因此首先发送USR1信号。
dd自从您停止它以来,现在可能已经复制了更多字节,因此运行:
head -c [number of bytes reported copied from dd] > \
/path/to/drive/you/are/moving/to/filename.bin
Run Code Online (Sandbox Code Playgroud)
将截断的副本放在目标磁盘上。您可能希望选择可被所需块大小整除的值,而不是精确的字节数,以在恢复复制时加快传输速度。只需记下您选择的任何内容,并确保您只是截断而不是放大图像。
将其复制到新驱动器后,运行:
dd if=/dev/sdc bs=64M skip=[truncated size divided by block size, e.g. 64000000] \
of=/path/to/part2
Run Code Online (Sandbox Code Playgroud)
如果较小的原始磁盘上有剩余图像空间,请删除在第 1 部分中复制到新磁盘的未截断图像以释放空间,然后将dd其输出到该磁盘。传输完成后,您可以运行
cat /path/to/part2 >> /path/to/part1
Run Code Online (Sandbox Code Playgroud)
将第 2 部分添加到第 1 部分的末尾,创建完整的磁盘映像!请注意,您将需要至少与第 1 部分所在的磁盘上相同的可用空间,以便将所有第 2 部分附加到其中。
如果您不介意完成整个传输,我会cat /dev/sdc | gzip -c - > /path/to/imagefile.img.gz创建一个 gzip 压缩存档。这可以用类似的东西写入硬盘分区zcat /path/to/imagefile.img.gz > /dev/sdX。
[从我的评论复制到答案中]
另外,我认为(但不记得了)如果未指定 of= , dd 会写入 stdout 。如果这是真的,您可以跳过将第 2 部分写入单独的文件并使用:
dd bs=64M skip=[skip-block-count] if=/dev/sdc >> /path/to/part1
Run Code Online (Sandbox Code Playgroud)
@MatijaNalis 正确地建议使用dd_rescue或ddrescue(完成相同任务的两个不同程序)来复制磁盘映像。如果您的分区/驱动器有错误的扇区或其他硬件故障,我会这样做。