Dd (Unix)

dd 是一個 Unix 和類 Unix 系統上的命令，主要功能為轉換和複製檔案。

在 Unix 上，硬體的裝置驅動（如硬碟）和特殊裝置檔案（如 /dev/zero 和 /dev/random）就像普通檔案一樣，出現在檔案系統中；只要在各自的驅動程式中實現了對應的功能，dd 也可以讀取自和 / 或寫入到這些檔案。這樣，dd 也可以用在備份硬體的引導扇區、取得一定數量的隨機資料等任務中。dd 程式也可以在複製時處理資料，例如轉換位元組序、或在 ASCII 與 EBCDIC 編碼間互換。

dd 的名字可能來源於 IBM 的工作控制語言（JCL）中的 DD 語句，意為 “Data Description”（資料描述）的縮寫。該命令的語句與 JCL 中的相似，而與其他 Unix 命令較不同，因此這可能是個玩笑。另一種解釋是 “cc”（根據命令自身的描述，為 “convert and copy”（轉換和複製））已經被 C 語言編譯器（C compiler）所佔。

dd 命令由單一 UNIX 規範的一部分，IEEE 標準 1003.1-2008 所規定。

用法

dd 的命令列語句與其他的 Unix 程式不同，因為它的命令列選項格式為選項 = 值，而不是更標準的 -- 選項 值或 - 選項 = 值。dd 預設從標準輸入中讀取，並寫入到標準輸出中，但可以用選項 if（input file，輸入檔案）和 of（output file，輸出檔案）改變。

由於作業系統的不同，用法會有出入。另外，dd 的一些特定功能取決於計算機系統的能力，例如直接訪問記憶體。向執行中的 dd 程序傳送 SIGINFO 訊號（Linux 上為 USR1）可以使它將 I/O 統計資訊列印到標準錯誤一次，然後繼續複製（注意在 OS X 上，訊號可能導致程序終止）。dd 可以從鍵盤中讀取標準輸入。到達檔案結尾時，dd 將會退出。訊號和 EOF 是由軟體決定。例如，移植到 Windows 的 Unix 工具使用不同的 EOF：Cygwin 使用 （通常的 Unix EOF），而 MKS 工具箱使用（通常的 Windows EOF）。

正如 Unix 哲學一樣，dd 只做好一件事（並被認為做得 “好”）。與複雜的和高度抽象的實用程式不同，除了為不同的選項做底層決定，dd 沒有其它的演算法。一般在每一次執行時，會改變 dd 的選項以分步處理一個計算機問題。

輸出訊息

Linux 上 GNU coreutils 提供的變種沒有描述執行結束時，dd 輸出到標準輸出訊息的格式。然而，其他的實現描述了它，例如 BSD 上的。

“記錄讀入” 和 “記錄寫出” 行顯示了已完整傳輸的塊數 + 不完整的塊數，例如物理介質以不完整的塊結尾，或是一個物理錯誤使得一個完整的塊無法被讀取。

塊大小

塊是衡量一次讀取、寫入和轉換位元組的單位。命令列選項可以為輸入 / 讀取（ibs）和輸出 / 寫入（obs）指定一個不同的塊大小，儘管塊大小（bs）選項會覆蓋 ibs 和 obs 選項。輸入和輸出的預設塊大小為 512 位元組（傳統的磁碟塊及 POSIX 規定的 “塊” 大小）複製的 count 選項、讀取的 skip 選項和寫入的 seek 選項都是以塊為單位。轉換操作也受 “轉換塊大小”（cbs）影響。

在 dd 的一些用途中，塊大小可能會影響表現。例如，當轉換硬碟中資料時，較小的塊大小通常會導致更多的位元組被轉換。發出許多小塊的讀取是一種開銷的浪費，且可能會對執行效能有負面影響。較大的塊大小可能會提高複製速度。但是，由於要複製的位元組量是由 bs×count 給出的，因此不可能在一次 dd 命令中複製素數個位元組，除非使用兩個糟糕選項之一：bs=N count=1（消耗記憶體）或 bs=1 count=N（大量讀請求開銷）。替代程式（見下文）允許指定位元組，而不是塊。在用作網路傳輸時，根據使用的網路協議，塊大小可能會與包大小衝突。

提供給塊大小的值會被解釋成十進位制整數，也可以加入字尾指定倍數。字尾 w 表示 2 倍，b 表示 512 倍，k 表示 1024 倍，M 表示 1024 × 1024 倍，G 表示 1024 × 1024 × 1024 倍，等等。另外，在塊大小和計數引數中，一些實現也可以使用 x 表示乘運算。

例如，塊大小 bs=2x80x18b 表示 2 × 80 × 18 × 512 = 1474560 位元組，也就是一張 1440 KiB 軟盤的確切大小。

用途

dd 命令可用於各種用途。

4.1 資料轉換

dd 可以在檔案、裝置、分割槽和卷之間複製資料。資料可以從其中任何地方輸入或輸出；但輸出到分割槽時有重要差異。此外在傳輸過程中，資料可以用 conv 選項修改以適應介質。

如果最後一個塊有意外長度，試圖使用 cp 複製整個磁碟可能會忽略掉它；然而 dd 卻可能成功。源和目標磁碟應該具有相同的大小。

noerror 選項意味著如果發生錯誤，程式也將繼續執行。sync 選項表示填充每個塊到指定位元組。

4.2 備份和恢復主引導記錄

可以修復主引導記錄。主引導記錄可以轉移到檔案，或從中轉移出來。

要複製軟盤的前兩個扇區：

dd if=/dev/fd0 of=MBRboot.img bs=512 count=2

要建立整個 x86 主引導記錄的映象（包括 MS-DOS 分割槽表和 MBR 魔法位元組）：

dd if=/dev/sda of=MBR.img bs=512 count=1

要建立僅含主引導記錄引導程式碼的映象（不包括分割槽表和開機所需的魔法位元組）：

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

4.3 資料修改

dd 可以原地修改資料。

用空位元組覆蓋檔案的前 512 個位元組：

dd if=/dev/zero of=path/to/file bs=512 count=1 conv=notrunc

轉換選項 notrunc 意味著不縮減輸出檔案，也就是說，如果輸出檔案已經存在，只改變指定的位元組，然後退出，並保留輸出檔案的剩餘部分。沒有這個選項，dd 將建立一個 512 位元組長的檔案。

在不同的分割槽中複製磁碟分割槽到磁碟映像檔案中：

dd if=/dev/sdb2 of=partition.image bs=4096 conv=noerror

4.4 磁碟擦除

出於安全方面的考慮，有時需要擦除丟棄的磁碟。

檢查驅動器上是否有資料，並將其輸出到標準輸出：

dd if=/dev/sda

用零擦除磁碟：

dd if=/dev/zero of=/dev/sda bs=4k

相較於上面資料修改的例子，不需要使用轉換選項 notrunc，因為當 dd 的輸出檔案為塊裝置時，它沒有效果。

bs=4k 選項使 dd 一次讀取或寫入 4 千位元組。在現代系統中，由於傳輸容量（如 RAID 系統），一個更大的塊大小可能更有利。注意用隨機資料填充磁碟總是比用零慢的多，因為隨機資料必須先由 CPU 和 / 或 HWRNG 生成，且不同的設計有不同的效能特點。（後面 PRNG 的 /dev/urandom 可能比 libc 中的要慢。）在大多數較現代的磁碟中，用零擦除會使其中的資料永久丟失。

用零擦除磁碟會使它的資料無法被軟體恢復。然而資料仍可能用特殊的實驗室技術恢復。

shred 程式提供了完成相同任務的替代方法，最後，目前許多 Linux 發行版還提供了一個精心製作的工具 wipe（做得 “好”，如上面的 Unix 哲學），提供了更多方法擦除。

4.5 資料恢復

1984 年，GNU dd 開啟了開源軟體（OSS）恢復資料、檔案、驅動器和分割槽的歷史。dd 程序一次處理一個塊，它的演算法只是在使用者介面顯示執行狀態。1999 年 10 月，一個 C 語言的程式 ddrescue 釋出了。它的演算法一次能處理兩個塊。但改進 ddrescue 的資料恢復演算法、2003 年的 shell 指令碼 ddrhelp 作者現在推薦 GNU ddrescue。它是一個釋出於 2004 年的 C++ 程式，與大多數的 Linux 發行版一起發行。在開源軟體中，GNU ddrescue 有最先進的塊大小變換演算法。（ddrescue 和 ddrescue 儘管名字相近，但卻是不同的程式。因為如此，區分更為明確的備用名稱也有使用；使用的名稱有 “addrescue”（freecode.com），“gddrescue”（Debian 包名）和 “gnu_ddrescue”（openSUSE 包名）。）

GNU ddrescue 既穩定又安全。

另一個開源程式 savehd7 使用更復雜的演算法，但它需要安裝自己的語言直譯器。

4.6 驅動器效能基準測試

對驅動器進行基準測試（通常是單執行緒），使用 1024 位元組塊分析連續系統讀取和寫入的效能：

dd if=/dev/zero bs=1024 count=1000000 of=file_1GB

dd if=file_1GB of=/dev/null bs=1024

4.7 用隨機資料生成檔案

使用核心隨機數驅動，用 100 個隨機位元組生成檔案：

dd if=/dev/urandom of=myrandom bs=100 count=1

4.8 將檔案轉換為大寫

將檔案轉換為大寫：

dd if=filename of=filename1 conv=ucase

4.9 建立任意大小的空檔案

建立 1GiB 的稀疏檔案，或增加現有檔案的大小：

dd if=/dev/zero of=mytestfile.out bs=1 count=0 seek=1G

（更先進的工具是 GNU coreutils 中的 fallocate 或 truncate。）

侷限

希捷的文件警告說，“一些依賴底層硬碟訪問的硬碟工具（如 DD）可能不支援 48 位邏輯區塊地址（LBA），除非進行升級”。使用超過 128 GiB 的 ATA 硬碟時需要 48 位 LBA。然而在 Linux 中，dd 使用核心讀取或寫入原始裝置檔案。2003 年釋出的 2.4.23 版本核心已經實現了對 48 位 LBA 的支援。

有人開玩笑說，dd 意為 “destroy disk”（破壞硬碟）或 “delete data”（刪除資料），因為在對硬碟進行底層操作時，類似顛倒輸入和輸出檔案的一個小錯誤都可能造成部分或全部硬碟資料的丟失。

dcfldd

dcfldd 是 dd 的一個分支，由前美國國防部計算機取證實驗室僱員尼克・哈勃（Nick Harbour）開發的增強版本。與 dd 相比，dcfldd 允許一個以上的輸出檔案，同時支援多種校驗計算方法，還提供了驗證模式以匹配檔案，並能顯示操作進度百分比。