dd를 사용하여 특정 시작과 끝이 있는 디스크의 세 파티션을 복사하려면 어떻게 해야 합니까?

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

dd이 명령을 사용하여 디스크의 처음 세 파티션을 이미지에 복사하고 싶습니다 . 그래서 외장 하드 드라이브를 마운트하고 해당 폴더로 이동하여 다음을 입력했습니다.

# dd count=$((132552703-2048)) if=/dev/sda of=./newImage.image

하지만 이 명령은 모든 sda 디스크를 sda3 파티션의 끝 부분이 아닌 외부 하드 드라이브에 복사합니다.

ddsda1의 시작 부분에서 시작하여 sda3의 끝 부분에서 끝나는 이미지를 생성하는 방법은 무엇입니까 ?

답변1

먼저 방법은 다음과 같습니다.


  1. 먼저 해라거의이전과 마찬가지로 빼기를 하지 않고 숫자에 1을 더합니다.

    dd  count=132552704 </dev/sda >img
    
  2. sed다음 으로 삭제하려는 파티션을 필터링하는 프로세스에서 파티션 테이블을 인쇄합니다 .

    • sed당신을 연 d두 번째 명령에 elete 명령을 쓸 것입니다fdiskimgsda4 이상의 각 파티션에 대한 파일.

      fdisk -l img | sed -e'/sda4 /,$id' -e'g;$aw' | fdisk img
      
  3. 아니오 3. 이제 끝났습니다.


둘째, 그 이유는 다음과 같습니다.


  • 부분적으로 성공했습니다...

    • 나는 당신의 주문을 거의 확신합니다거의효과가 있지만 생각보다 낫다고 확신합니다.

    • 네가 그렇게 말할 때면 좋겠다모든 sda를 복사fdisk -l이미지에 모든 파티션이 포함되어 있는 것으로 나타나기 때문이라고 생각합니다 . 그러나 dd귀하의 질문에 있는 명령 에 따르면 제공된 /dev/sda섹터 크기는 상당히 표준적인 512바이트입니다.(따라서 dd의 기본 블록 크기와 동일)/dev/sda그런 다음 바이트 0부터 마지막 ​​2k 섹터를 제외한 모든 섹터를 복사해야 합니다 /dev/sda3.

  • 학과에 대해서...

    • 아래에서 fdisk출력 보고서를 볼 수 있습니다.단위. 각 사이즈는 이렇습니다부서보고서는 fdisk말했다. 디스크부서 가능한4096바이트 - 최근에 제작되어 처리된 디스크인 경우고급 형식섹터 크기 - 그렇지 않으면 표준 논리적 512바이트 섹터 크기로 분할되지 않은 디스크를 찾기가 어렵습니다.

    • 그게 다야fdiskman그 페이지설명하다:

    • -u,--units[=unit]

      • 파티션 테이블을 나열할 때 크기를 표시하세요.부서또는실린더.기본 디스플레이 크기는 다음과 같습니다.부서. 이전 버전과의 호환성을 위해 이 옵션을 대신 사용할 수 있습니다.단위매개변수 - 그런 다음 기본값을 사용합니다. 선택적 단위 매개변수는 다음과 함께 사용할 수 없습니다.-u옵션은 공백으로 구성되며 올바른 형식은 다음과 같습니다.-u=cylinders.
    • 가지다더 많은 관련 내용을 보려면 여기를 클릭하세요.

  • 그리고 더 자세한 내용은 dd...

    • dd 할 수 없다 자동으로 데이터 손실. 실제로 짧은 읽기가 발생 dd하면지정됨~이 되다매우이것에 대해 말해보세요:

    • 부분 입력 청크는 read()입력 청크 크기보다 작은 입력 청크를 반환합니다. 부분 출력 블록은 출력 블록 크기에 지정된 것보다 적은 바이트로 작성된 출력 블록입니다.

    • ...있을 때마지막 하나잘린 블록, 잘린 블록의 개수를 표준 오류에 기록해야 합니다...

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

  • 입력/출력 차단...

    • 하지만 어쨌든 그건 사실이야할 수 없다블록 장치 I/O에서 발생합니다. 이것이 블록 장치가 블록 장치인 이유입니다. 추가 레이어가 있습니다.(때로는 여러 개)(문자 장치가 아닌) 블록 장치에 대한 버퍼 보호. POSIX가 블록 장치에 파일이 존재하도록 보장하는 것은 이러한 구별입니다 lseek(). 이는 I/O 차단의 매우 기본적인 원칙입니다.
  • 요약하다...

    • 그래서 당신은 복사했습니다모두지정한 지점까지 장치를 사용하지만 문제는첫 번째2,000개 섹터에 /dev/sda해당 항목이 포함됩니다.모두파티션 테이블을 사용하면 해당 파티션 테이블을 이미지에 복사할 수 있으므로 fdisk -l이미지가 보고할 수 있습니다.모두partitions /dev/sda, 해당 파티션의 데이터가 실제로 이미지 파일에 있는지 여부에 관계없이. 물론 cat원하는 경우 별도의 데이터 파티션을 별도의 이미지 파일로 분리할 수 있습니다. 하지만 이 경우 파티션 테이블이 완전히 손실됩니다. 실제로 해야 할 일은 복제되지 않은 파티션을 삭제하고 복제되었는지 확인하는 것뿐입니다.모두당신이하는 것.

셋째, 제가 아는 방법은 다음과 같습니다.


  • 이렇게 하면 4G가 생성됩니다../img파일이 NUL로 가득 차 있습니다.

    </dev/zero >./img \
    dd ibs=8k obs=8kx1b count=1kx1b 
    

    524288+0 records in
    1024+0 records out
    4294967296 bytes (4.3 GB) copied, 3.53287 s, 1.2 GB/s
    
  • 이렇게 하면 파티션이 분할됩니다../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
    
  • 이제 우리는 그것을 볼 수 있습니다.

    fdisk -l ./img
    

    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
    
  • 또한 세 개의 파티션에 실제 파일 시스템과 파일을 배치할 것입니다.

    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'
    
  • 이것은 모든 끝 위치의 바이트 오프셋입니다.

    grep -Ebao '(my[^0-9]*|PART)[123]' <./img
    

    2826272:PART1
    2830336:my part# is 1
    904606240:PART2
    904624640:my part# is 2
    917656608:PART3
    917660672:my part# is 3
    

fdisk하지만 파티션을 포맷하기 전에 파일 시스템이 파티션 크기를 기꺼이 보고한다는 사실을 알고 계셨습니까 ? 이는 파티션 테이블이 디스크의 맨 위에 있기 때문입니다. 이는 단지 레이아웃일 뿐이며 그 이상은 아닙니다. 보고가 발생하기 위해 실제로 파티션이 존재할 필요는 없습니다. 그것들은 처음 1M 내에서만 논리적으로 매핑됩니다 ./img. 보다:

  • 처음 두 개의 파티션만 삭제해 보겠습니다 ./img.

    <./img >./img2 dd count=1779583
    

    1779583+0 records in
    1779583+0 records out
    911146496 bytes (911 MB) copied, 1.84985 s, 493 MB/s
    
  • 또 가자 grep...

    grep -Ebao '(my[^0-9]*|PART)[123]' <./img2
    

    2826272:PART1
    2830336:my part# is 1
    904606240:PART2
    904624640:my part# is 2
    
  • 그리고 fdisk보고서를 받아..

    fdisk -l ./img2
    

    Disk ./img2: 869 MiB, 911146496 bytes, 1779583 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: 0xcbcab4d8
    
    Device     Boot   Start     End Sectors   Size Id Type
    ./img2p1           2048 1766655 1764608 861.6M 27 Hidden NTFS WinRE
    ./img2p2        1766784 1779583   12800   6.3M  7 HPFS/NTFS/exFAT
    ./img2p3        1779584 8284543 6504960   3.1G  7 HPFS/NTFS/exFAT
    

이제 이것이 궁금합니다. fdisk여전히 디스크의 4G까지 확장되는 세 번째 파티션이 있다고 믿는 것 같습니다. 또한 크기도 869M에 불과하다고 믿는 것 같습니다!

  • 파티션 테이블에서 세 번째 파티션을 삭제해야 할 수도 있습니다.

    printf %s\\n d 3 w |
    fdisk ./img2 >/dev/null
    
  • 이제 복사한 파티션을 마운트할 수 있는지, 파일이 그대로 유지되는지 살펴보겠습니다.

    sudo sh -c ' trap "$1" 0
        cd /tmp; mkdir -p mnt
        for p in "$(losetup --show -Pf "$0")p"*
        do    mount "$p" mnt
              grep . /dev/null ./mnt/*
              umount mnt
        done' "$PWD/img2" 'losetup -D'
    

    ./mnt/part1:my part# is 1
    ./mnt/part2:my part# is 2
    

분명히 이것이 불가능하지는 않습니다.

답변2

dd는 1개의 입력을 1개의 출력으로 직접 전달하기 때문에 불가능합니다. 백업이 아닌 3개의 파티션을 하나로 병합하고 dd는 동일한 복사본에서만 작동하기 때문에 복구가 손상될 수 있습니다.

귀하의 대답은 다음과 같습니다:

dd if=/dev/sda1 of=~/hdadisk1.img; 
dd if=/dev/sda2 of=~/hdadisk2.img
dd if=/dev/sda3 of=~/hdadisk3.img 

(필요한 경우 스크립트에서) 마지막으로 hdadisk{1,3,3}.img를 사용하여 이미지를 생성할 수 있지만 백업 목적으로 이러한 이미지를 파티션에 보관하는 것이 더 좋습니다.

답변3

dd count=$((132552703-2048))입력 시작 부분부터 132552703-2048 512바이트 블록을 복사합니다. 블록 크기는 fdisk1kB = 1024바이트입니다. 따라서 세 가지 문제에 직면하게 됩니다.

  • 지정하는 크기는 원하는 크기의 절반입니다.
  • 오프셋에서 복사를 시작하고 싶다고 표시하지 않았습니다.
  • 빼기에 울타리 오류가 있습니다. 마지막 블록이 누락되었습니다. 블록 수는 (끝 블록 오프셋) - (시작 블록 오프셋) + 1입니다.

그래서 당신은 사용할 수 있습니다

dd bs=1k skip=2048 count=$((132552703-2048+1)) if=/dev/sda of=./newImage.image

내 생각엔 이게 효과가 있을 것 같아 -dd데이터가 자동으로 손실될 수 있습니다., 하지만 블록 장치의 1kB 블록이나 Linux의 일반 파일은 괜찮을 것이라고 생각합니다. 하지만아주 느린.

단일 파티션을 복사하는 가장 간단한 방법은 직접 복사하는 것입니다.

cat /dev/sda1 >sda1.image
cat /dev/sda2 >sda2.image
cat /dev/sda3 >sda3.image

파티션을 별도의 파일로 복사하는 것이 더 좋습니다. 그렇지 않으면 파일 시작 부분에 없는 파티션은 사용하기 어려워집니다. 동일한 파일에 세 개의 파티션을 갖고 싶다면 다음과 같이 연결하면 됩니다.

cat /dev/sda1 /dev/sda2 /dev/sda3 >newImage.image

답변4

빠르고 쉬운 대답은 다음과 같습니다.

dd skip=2048 count=132552703 status=progress if=/dev/sda of=./newImage.image

기본적으로 fdisk -l은 파티션 크기를 섹터당 512바이트로 반환합니다.

fdisk 출력에 다음과 같은 내용이 표시되는지 확인할 수 있습니다.

Disk /dev/sda: 256 GiB, 274877906944 bytes, 536870912 sectors
Disk model: Virtual Disk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

dd는 또한 "bs", "cbs", "ibs" 및 "obs" 스위치의 기본값으로 512바이트를 사용합니다.

  bs=BYTES        read and write up to BYTES bytes at a time (default: 512);
                  overrides ibs and obs
  cbs=BYTES       convert BYTES bytes at a time
  conv=CONVS      convert the file as per the comma separated symbol list
  count=N         copy only N input blocks
  ibs=BYTES       read up to BYTES bytes at a time (default: 512)
  if=FILE         read from FILE instead of stdin
  iflag=FLAGS     read as per the comma separated symbol list
  obs=BYTES       write BYTES bytes at a time (default: 512)
  of=FILE         write to FILE instead of stdout
  oflag=FLAGS     write as per the comma separated symbol list
  seek=N          skip N obs-sized blocks at start of output
  skip=N          skip N ibs-sized blocks at start of input
  status=LEVEL    The LEVEL of information to print to stderr;
                  'none' suppresses everything but error messages,
                  'noxfer' suppresses the final transfer statistics,
                  'progress' shows periodic transfer statistics

다음과 같이 dd 자체를 사용하여 블록 파일을 생성할 수 있는지 확인하세요.

dd if=/dev/urandom of=테스트 횟수=1

파일 크기는 512바이트여야 합니다.

따라서 파티션 또는 파티션 그룹의 이미지를 생성하려면 fdisk 출력에서 ​​파티션 또는 첫 번째 파티션의 시작 부분에 있는 섹터 수를 가져와서 이를 dd 매개변수의 값으로 사용하기만 하면 됩니다. "skip", 그런 다음 파티션 끝이나 마지막 파티션의 섹터 수를 지정하고 dd 매개변수 "count"의 값으로 설정합니다.

fdisk와 dd 사이에 블록 크기 차이가 있는 경우 "bs" 매개변수를 사용하여 항상 dd에 블록 크기를 지정하여 fdisk 출력이 dd가 사용할 블록 크기와 일치하는지 확인할 수 있습니다.

관련 정보