如何使用dd复制具有特定开头和结尾的磁盘的三个分区?

Raf*_*rsk 4 shell partition dd

使用fdisk -l命令我得到以下答案:

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    28266495    14132224   27  Hidden NTFS WinRE
/dev/sda2        28268544    28473343      102400    7  HPFS/NTFS/exFAT
/dev/sda3        28473344   132552703    52039680    7  HPFS/NTFS/exFAT
/dev/sda4   *   132556798   625141759   246292481    5  Extended
/dev/sda5       193996800   198092799     2048000   82  Linux swap / Solaris
/dev/sda6       234960896   625141759   195090432    7  HPFS/NTFS/exFAT
/dev/sda7       198094848   234950316    18427734+  83  Linux
/dev/sda8       132556800   183756018    25599609+  83  Linux
Run Code Online (Sandbox Code Playgroud)

我想使用该dd命令将磁盘的前三个分区复制到映像中。所以我安装了一个外部硬盘驱动器,进入它的文件夹并输入:

# dd count=$((132552703-2048)) if=/dev/sda of=./newImage.image
Run Code Online (Sandbox Code Playgroud)

但是此命令将所有 sda 磁盘复制到我的外部硬盘驱动器,而不是仅复制到 sda3 分区的末尾。

如何使用dd来创建从 sda1 开始到 sda3 结束的图像?

mik*_*erv 5

首先,方法如下:


  1. 首先几乎像以前一样做,但不要减法 - 并在计数中加一。

    dd  count=132552704 </dev/sda >img
    
    Run Code Online (Sandbox Code Playgroud)
  2. 接下来在sed可以筛选出您要删除的分区表的过程中打印分区表。

    • sed将向d秒写入elete 命令,该命令fdiskimg为 sda4 及以后的每个分区打开您的文件。

      fdisk -l img | sed -e'/sda4 /,$id' -e'g;$aw' | fdisk img
      
      Run Code Online (Sandbox Code Playgroud)
  3. 没有 3。你完成了。


其次,原因如下:


  • 部分成功...

    • 我很确定你的命令几乎有效,但我敢打赌它比你想象的更好。

    • 我希望当您说它复制了所有 sda 时,您相信这是因为fdisk -l该图像的一个指示所有分区都包含在其中。dd但是,根据您问题中的命令,提供/dev/sda的扇区大小是相当标准的 512 字节(因此与dd的默认块大小相同),那么您应该将所有内容从/dev/sda仅字节 0 复制到除最后 2k 扇区之外的所有扇区的/dev/sda3

  • 关于行业...

    • 您可以在下面看到fdisk有关Units的输出报告的位置。这是每一个的大小部门认为fdisk报告上。磁盘扇区 可能是 4096 字节 - 如果它是最近制造的磁盘并处理高级格式扇区大小 - 否则很难找到未按标准逻辑 512 字节扇区大小分区的磁盘。

    • 这是怎样fdiskman所说的那样:

    • -u, --units[=unit]

      • 列出分区表时,以扇区柱面为单位显示大小。默认是以扇区为单位显示大小。为了向后兼容,可以使用不带unit参数的选项- 然后使用默认值。请注意,可选的单元参数不能与-u选项用空格分隔,正确的形式是例如-u=cylinders
    • 这里有更多内容

  • 还有一些关于dd...

    • dd 不能 默默丢失数据。事实上,如果发生短读,dd指定非常直言不讳:

    • 部分输入块是read()返回小于输入块大小的块。部分输出块是用比输出块大小指定的更少字节写入的块...

    • ...当至少有一个截断块时,应将截断块的数量写入标准错误...

    • "%u truncated %s\n", <number of truncated blocks>,"record[s]"

  • 块输入/输出...

    • 但无论如何,这实际上不会发生在块设备 i/o 上。这就是使块设备成为块设备的原因 -与字符设备相反,块设备有一个额外的层(有时是几个)缓冲保护。正是这种区别使 POSIX 能够保证lseek()块设备上存在的文件——这是阻塞 i/o 的一个非常基本的原则。
  • 总结...

    • 因此,您已将所有设备复制到您指定的位置,但问题是,2k 个扇区/dev/sda将包含其整个分区表,因此您会将所述分区表复制到您的映像中,因此fdisk -l的图像将报告 的所有分区/dev/sda,无论这些分区的数据是否实际驻留在该图像文件中。当然,cat如果您愿意,您可以将单独的数据分区单独放入单独的图像文件中 - 但在这种情况下,您会完全丢失分区表。你真正需要做的就是删除你没有复制的分区,并确保你复制了所有你所做的。

第三,这就是我所知道的:


  • 这将创建一个./img充满 NUL的 4G文件。

    </dev/zero >./img \
    dd ibs=8k obs=8kx1b count=1kx1b 
    
    Run Code Online (Sandbox Code Playgroud)
    524288+0 records in
    1024+0 records out
    4294967296 bytes (4.3 GB) copied, 3.53287 s, 1.2 GB/s
    
    Run Code Online (Sandbox Code Playgroud)
  • 这将分区./img以匹配您的磁盘至前三个分区,但比例为 1/16:

    (set "$((p=0))" 28266495     27 \
          28268544  28473343  2\\n7 \
          28473344 132552703  3\\n7
    while   [ "$#" -ge "$((p+=1))" ]
    do      printf "n\np\n$p\n%.0d\n%d\nt\n%b\n" \
                   "$(($1/16))" "$(($2/16))" "$3"
            shift 3
    done;   echo w
    )| fdisk ./img >/dev/null
    
    Run Code Online (Sandbox Code Playgroud)
  • 所以现在我们可以看看它。

    fdisk -l ./img
    
    Run Code Online (Sandbox Code Playgroud)
    Disk ./img: 4 GiB, 4294967296 bytes, 8388608 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x5659b81c
    
    Device     Boot   Start     End Sectors   Size Id Type
    ./img1             2048 1766655 1764608 861.6M 27 Hidden NTFS WinRE
    ./img2          1766784 1779583   12800   6.3M  7 HPFS/NTFS/exFAT
    ./img3          1779584 8284543 6504960   3.1G  7 HPFS/NTFS/exFAT
    
    Run Code Online (Sandbox Code Playgroud)
  • 我还将在三个分区上放置一些实际的文件系统和文件。

    sudo sh -c ' trap "$1" 0
        cd /tmp; mkdir -p mnt
        for p in "$(losetup --show -Pf "$0")p"*
        do    mkfs.vfat "$p"
              mount "$p" mnt
              echo  "my part# is ${p##*p}" \
                     >./mnt/"part${p##*p}"
              sync; umount mnt
        done' "$PWD/img" 'losetup -D'
    
    Run Code Online (Sandbox Code Playgroud)
  • 这是所有结束的字节偏移量......

    grep -Ebao '(my[^0-9]*|PART)[123]' <./img
    
    Run Code Online (Sandbox Code Playgroud)
    2826272:PART1
    2830336:my part# is 1
    904606240:PART2
    904624640:my part# is 2
    917656608:PART3
    917660672:my part# is 3
    
    Run Code Online (Sandbox Code Playgroud)

但是您是否注意到fdisk在我们使用文件系统格式化分区之前报告分区的大小非常高兴?这是因为分区表位于磁盘的最前端——它只是一个布局,仅此而已。没有一个分区需要实际存在才能报告。它们仅在./img. 手表:

现在很好奇。fdisk似乎仍然相信有一个磁盘的第三个分区可以扩展到 4G,它似乎也相信它的大小只有 869M!

显然这不是不可能的。