這裡提供一些 Linux 下 dd 指令的教學與範例,您可以使用這個小工具進行各種資料的複製、備份與回復。

Linux 系統中的 dd 指令是一個多功能的小工具,可以用於各種的資料拷貝動作:

  • 備份與回復整顆硬碟的資料。
  • 備份與回復原始設備檔案,例如 MBR(master boot record)。
  • 轉換資料格式,例如 ASCII 轉換為 EBCDIC,大小寫轉換等。
  • 建立固定大小的檔案。

dd 的原意為 data duplicator,但由於 dd 屬於較低階的資料處理工具,通常都會以管理者(root)權限來執行,如果稍有不慎,也很容易造成嚴重的後果(例如整顆硬碟的資料不見等等),所以有些人也把 dd 取名為 data destroyer。


許多人在製作 Linux 的 USB 安裝隨身碟的時候,時常也會使用到 dd 指令,這部份的教學請參考 Linux 使用 dd 指令將 ISO 檔製作成 Live USB 隨身碟

基本使用方式

dd 常用的參數如下:

  • if=FILE:指定輸入檔案名稱(input file)為 FILE
  • of=FILE:指定輸出檔案名稱(output file)為 FILE
  • ibs=BYTES:指定輸入區塊大小(input block size),一次讀取 BYTES 位元組的資料,預設為 512 位元組。
  • obs=BYTES:指定輸出區塊大小(output block size),一次寫入 BYTES 位元組的資料,預設為 512 位元組。
  • bs=BYTES:指定 block size,一次讀取與寫入 BYTES 位元組的資料,此選項會覆蓋 ibsobs 的設定。
  • cbs=BYTES:一次轉換 BYTES 位元組的資料。
  • count=N:只處理 N 個輸入區塊,每個區塊的大小為 ibs
  • seek=N:在輸出時跳過輸出檔案的前 N 個區塊,每個區塊的大小為 obs
  • skip=N:在輸入時跳過輸入檔案的前 N 個區塊,每個區塊的大小為 ibs
  • conv=CONVS:指定資料的轉換選項,如果一次要指定多種轉換,則以逗點分隔。

以下是各種可用的轉換:

  • ascii:EBCDIC 轉 ASCII。
  • ebcdic:ASCII 轉 EBCDIC。
  • ibm:ASCII 轉 alternate EBCDIC。
  • block:將每一個區塊的資料結尾的換行字元替換為空白,並以空白將整個區塊補足 cbs 位元組。。
  • unblock:將每個區塊結尾的空白字元替換為換行字元。
  • lcase:將大寫字母轉換成小寫。
  • ucase:將小寫字母轉換成大寫。
  • swab:將每一對輸入的位元組交換。
  • sync:將每一個輸入的區塊以 NUL 補足至 ibs 位元組的大小,如果是在 block 或是 unblock 的轉換中,則以空白字元來補足。
  • nocreat:不要建立輸出檔案。
  • notrunc:不要將輸出檔案截短。
  • noerror:發生錯誤時還是繼續執行。
  • fdatasync:讓資料同步實體寫入硬碟,不要留在緩衝區中。
再次提醒您,若以管理者權限執行 dd 時,請再三確認您所執行的指令內容是否正確,執行錯誤的指令可能導致整個系統與資料的損毀!

備份整顆硬碟

/dev/sda 所有的資料寫入 /dev/sdb

sudo dd if=/dev/sda of=/dev/sdb

if 參數指定的是輸入檔案(input file),而 of 參數指定的是輸出檔案(output file),這行指令會將 /dev/sda 這顆硬碟的資料讀出來,然後寫進 /dev/sdb 這顆硬碟。

在整個過程中如果出現讀取錯誤的話,dd 就會停止執行,如果想要讓 dd 在出現讀取錯誤時還是繼續拷貝資料的話,就要加上 conv=noerror 參數,這個選項通常在備份資料時會使用到,另外加上 sync 可以讓 dd 以 synchronized I/O 的方式備份資料:

sudo dd if=/dev/sda of=/dev/sdb conv=noerror,sync

建立硬碟的備份影像檔

備份硬碟資料除了拿兩顆硬碟對拷之外,也可以直接將整顆硬碟的資料製作成影像檔,以這種方式備份資料會更有彈性:

sudo dd if=/dev/hda of=~/hdadisk.img

這行指令會將 /dev/sda 這顆硬碟的資料讀出來,儲存至 ~/hdadisk.img 這個影像檔中。

從備份影像檔回復硬碟資料

如果要以影像檔回復硬碟的資料,就執行:

sudo dd if=hdadisk.img of=/dev/hdb

這樣就會把 hdadisk.img 影像檔中的資料回復至 /dev/sdb 這顆硬碟(原本 /dev/sdb 硬碟中的所有資料會被覆蓋掉,請小心使用)。

備份磁碟分割區

如果只要備份單一個磁碟分割區,可以使用:

sudo dd if=/dev/hda1 of=~/partition1.img

兩個磁碟分割區對拷:

sudo dd if=/dev/sda1 of=/dev/sdb1 bs=4096 conv=noerror,sync

這樣會將 /dev/sda1 的資料同步至 /dev/sdb1,使用前請確認 /dev/sdb1 分割區大小至少要比 /dev/sda1 大。

備份 CD/DVD 光碟

將光碟片放進光碟機之後,就可以使用這樣的指令將光碟整個備份成 ISO 檔:

sudo dd if=/dev/cdrom of=tgsservice.iso bs=2048

如果您放進光碟片時,系統會自動掛載,那麼在使用 dd 備份之前,建議可以先將光碟卸載,避免不必要的光碟讀取動作。

壓縮資料

如果資料很大,可以配合 gzip 將資料壓縮起來,直接輸出成壓縮過的影像檔:

sudo dd if=/dev/sda | gzip > sdadisk.img.gz

而要從壓縮過的影像檔回復資料,可以使用:

sudo gzip -dc sdadisk.img.gz | dd of=/dev/sda

MBR 的備份與回復

備份 MBR(master boot record):

sudo dd if=/dev/sda of=mbr.img bs=446 count=1

回復 MBR:

sudo dd if=mbr.img of=/dev/sda

查看 MBR 內容:

sudo dd if=/dev/hda of=mbr.bin bs=512 count=1
od -xa mbr.bin

ASCII 與 EBCDIC 轉換

將 ASCII 轉換為 EBCDIC:

dd if=textfile.ascii of=textfile.ebcdic conv=ebcdic

將 EBCDIC 轉換為 ASCII:

dd if=textfile.ebcdic of=textfile.ascii conv=ascii

大小寫轉換

轉換為大寫:

dd if=file1 of=file2 conv=ucase

轉換為小寫:

dd if=file1 of=file2 conv=lcase

建立固定大小的檔案

建立一個 10MB 大小的檔案:

dd if=/dev/zero of=file1 bs=10485760 count=1

這裏的 block size 的計算方式為 10*1024*1024 = 10MB。

修改檔案內容

將檔案開頭的 512 bytes 改為 null:

dd if=/dev/zero of=file1 bs=512 count=1 conv=notrunc

這裡的 notrunc 參數代表不要將輸出檔案截短,只取代開頭的前 512 bytes,其餘內容不變。假設 file1 不存在,那麼這行指令就會建立一個 512 bytes 的 file1 檔案。

參考資料:The Geek StuffLinOxide