dd命令

dd命令

dd是Linux/UNIX下的一個非常有用的命令,作用是用指定大小的塊拷貝一個文件,主要功能為轉換和複製文件。

用法


dd的命令行語句與其他的Unix程序不同,因為它的命令行選項格式為選項=值,而不是更標準的--選項值或-選項=值。dd默認從標準輸入中讀取,並寫入到標準輸出中,但可以用選項if(inputfile,輸入文件)和of(outputfile,輸出文件)改變。
由於操作系統的不同,用法會有出入。另外,dd的一些特定功能取決於計算機系統的能力,例如直接訪問內存。向運行中的dd進程發送SIGINFO信號(Linux上為USR1)可以使它將I/O統計信息列印到標準錯誤一次,然後繼續複製(注意在OSX上,信號可能導致進程終止)。dd可以從鍵盤中讀取標準輸入。到達文件結尾時,dd將會退出。信號和EOF是由軟體決定。例如,移植到Windows的Unix工具使用不同的EOF:Cygwin使用(通常的UnixEOF),而MKS工具箱使用(通常的WindowsEOF) 。
正如Unix哲學一樣,dd只做好一件事(並被認為做得“好”)。與複雜的和高度抽象的實用程序不同,除了為不同的選項做底層決定,dd沒有其它的演演算法。一般在每一次運行時,會改變dd的選項以分步處理一個計算機問題。

輸出消息


Linux上GNUcoreutils提供的變種沒有描述運行結束時,dd輸出到標準輸出消息的格式。然而,其他的實現描述了它,例如BSD上的。
“記錄讀入”和“記錄寫出”行顯示了已完整傳輸的塊數+不完整的塊數,例如物理介質以不完整的塊結尾,或是一個物理錯誤使得一個完整的塊無法被讀取。

塊大小


塊是衡量一次讀取、寫入和轉換位元組的單位。命令行選項可以為輸入/讀取(ibs)和輸出/寫入(obs)指定一個不同的塊大小,儘管塊大小(bs)選項會覆蓋ibs和obs選項。輸入和輸出的默認塊大小為512位元組(傳統的磁碟塊及POSIX規定的“塊”大小)複製的count選項、讀取的skip選項和寫入的seek選項都是以塊為單位。轉換操作也受“轉換塊大小”(cbs)影響。
在dd的一些用途中,塊大小可能會影響表現。例如,當轉換硬碟中數據時,較小的塊大小通常會導致更多的位元組被轉換。發出許多小塊的讀取是一種開銷的浪費,且可能會對執行性能有負面影響。較大的塊大小可能會提高複製速度。但是,由於要複製的位元組量是由bs×count給出的,因此不可能在一次dd命令中複製素數個位元組,除非使用兩個糟糕選項之一:bs=Ncount=1(消耗內存)或bs=1count=N(大量讀請求開銷)。替代程序(見下文)允許指定位元組,而不是塊。在用作網路傳輸時,根據使用的網路協議,塊大小可能會與包大小衝突。
提供給塊大小的值會被解釋成十進位整數,也可以加入後綴指定倍數。後綴w表示2倍,b表示512倍,k表示1024倍,M表示1024×1024倍,G表示1024×1024×1024倍,等等。另外,在塊大小和計數參數中,一些實現也可以使用x表示乘運算。
例如,塊大小bs=2x80x18b表示2×80×18×512=1474560位元組,也就是一張1440KiB軟盤的確切大小。

用途


dd命令可用於各種用途。

數據轉換

dd可以在文件、設備、分區和卷之間複製數據。數據可以從其中任何地方輸入或輸出;但輸出到分區時有重要差異。此外在傳輸過程中,數據可以用conv選項修改以適應介質。
如果最後一個塊有意外長度,試圖使用cp複製整個磁碟可能會忽略掉它;然而dd卻可能成功。源和目標磁碟應該具有相同的大小。
不同情況的dd格式
ddif=/dev/sr0of=myCD.isobs=2048conv=noerror,syncCD-ROM中創建ISO磁碟鏡像。
ddif=/dev/sda2of=/dev/sdb2bs=4096conv=noerror克隆一個分區到另一個。
ddif=/dev/ad0of=/dev/ad1bs=1Mconv=noerror克隆硬碟“ad0”到“ad1”。
noerror選項意味著如果發生錯誤,程序也將繼續運行。sync選項表示填充每個塊到指定位元組。
備份和恢復主引導記錄
可以修復主引導記錄。主引導記錄可以轉移到文件,或從中轉移出來。
要複製軟盤的前兩個扇區:
ddif=/dev/fd0of=MBRboot.imgbs=512count=2
要創建整個x86主引導記錄的鏡像(包括MS-DOS分區表和MBR魔法位元組):
ddif=/dev/sdaof=MBR.imgbs=512count=1
要創建僅含主引導記錄引導代碼的鏡像(不包括分區表和開機所需的魔法位元組):
ddif=/dev/sdaof=MBR_boot.imgbs=446count=1

數據修改

dd可以原地修改數據。
用空位元組覆蓋文件的前512個位元組:
ddif=/dev/zeroof=path/to/filebs=512count=1conv=notrunc
轉換選項notrunc意味著不縮減輸出文件,也就是說,如果輸出文件已經存在,只改變指定的位元組,然後退出,並保留輸出文件的剩餘部分。沒有這個選項,dd將創建一個512位元組長的文件。
在不同的分區中複製磁碟分區到磁碟映像文件中:
ddif=/dev/sdb2of=partition.imagebs=4096conv=noerror

磁碟擦除

主條目:數據擦除
出於安全方面的考慮,有時需要擦除丟棄的磁碟。
檢查驅動器上是否有數據,並將其輸出到標準輸出:
ddif=/dev/sda
用零擦除磁碟:
ddif=/dev/zeroof=/dev/sdabs=4k
相較於上面數據修改的例子,不需要使用轉換選項notrunc,因為當dd的輸出文件為塊設備時,它沒有效果。
bs=4k選項使dd一次讀取或寫入4千位元組。在現代系統中,由於傳輸容量(如RAID系統),一個更大的塊大小可能更有利。注意用隨機數據填充磁碟總是比用零慢的多,因為隨機數據必須先由CPU和/或HWRNG生成,且不同的設計有不同的性能特點。(後面PRNG的/dev/urandom可能比libc中的要慢。)在大多數較現代的磁碟中,用零擦除會使其中的數據永久丟失。
用零擦除磁碟會使它的數據無法被軟體恢復。然而數據仍可能用特殊的實驗室技術恢復。
shred程序提供了完成相同任務的替代方法,最後,當前許多Linux發行版還提供了一個精心製作的工具wipe(做得“好”,如上面的Unix哲學),提供了更多方法擦除。

數據恢復

1984年,GNUdd開啟了開源軟體(OSS)恢複數據、文件、驅動器和分區的歷史。dd進程一次處理一個塊,它的演演算法只是在用戶界面顯示運行狀態。1999年10月,一個C語言的程序dd_rescue發布了。它的演演算法一次能處理兩個塊。但改進dd_rescue的數據恢復演演算法、2003年的shell腳本dd_rhelp作者現在推薦GNUddrescue。它是一個發佈於2004年的C++程序,與大多數的Linux發行版一起發行。在開源軟體中,GNUddrescue有最先進的塊大小變換演演算法。(ddrescue和dd_rescue儘管名字相近,但卻是不同的程序。因為如此,區分更為明確的備用名稱也有使用;使用的名稱有“addrescue”(freecode.com),“gddrescue”(Debian包名)和“gnu_ddrescue”(openSUSE包名)。)
GNUddrescue既穩定又安全。
另一個開源程序savehd7使用更複雜的演演算法,但它需要安裝自己的語言解釋器。

性能基準測試

驅動器進行基準測試(通常是單線程),使用1024位元組塊分析連續系統讀取和寫入的性能:
ddif=/dev/zerobs=1024count=1000000of=file_1GBddif=file_1GBof=/dev/nullbs=1024
用隨機數據生成文件
使用內核隨機數驅動,用100個隨機位元組生成文件:
ddif=/dev/urandomof=myrandombs=100count=1

文件轉換大寫

將文件轉換為大寫:
ddif=filenameof=filename1conv=ucase

創建空文件

創建1GiB的稀疏文件,或增加現有文件的大小:
ddif=/dev/zeroof=mytestfile.outbs=1count=0seek=1G
(更先進的工具是GNUcoreutils中的fallocate或truncate。)

局限


希捷的文檔警告說,“一些依賴底層硬碟訪問的硬碟工具(如DD)可能不支持48位邏輯區塊地址(LBA),除非進行升級”。使用超過128GiB的ATA硬碟時需要48位LBA。然而在Linux中,dd使用內核讀取或寫入原始設備文件。2003年釋出的2.4.23版本內核已經實現了對48位LBA的支持。
有人開玩笑說,dd意為“destroydisk”(破壞硬碟)或“deletedata”(刪除數據),因為在對硬碟進行底層操作時,類似顛倒輸入和輸出文件的一個小錯誤都可能造成部分或全部硬碟數據的丟失。

dcfldd


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

應用實例


1.將本地的/dev/hdb整盤備份到/dev/hdd
ddif=/dev/hdbof=/dev/hdd
2.將/dev/hdb全盤數據備份到指定路徑的image文件
ddif=/dev/hdbof=/root/image
3.將備份文件恢復到指定盤
ddif=/root/imageof=/dev/hdb
4.備份/dev/hdb全盤數據,並利用gzip工具進行壓縮,保存到指定路徑
ddif=/dev/hdb|gzip>/root/image.gz
5.將壓縮的備份文件恢復到指定盤
gzip-dc/root/image.gz|ddof=/dev/hdb
6.備份磁碟開始的512個位元組大小的MBR信息到指定文件
ddif=/dev/hdaof=/root/imagecount=1bs=512
count=1指僅拷貝一個塊;bs=512指塊大小為512個位元組。
恢復:
ddif=/root/imageof=/dev/hda
7.備份軟盤
ddif=/dev/fd0of=disk.imgcount=1bs=1440k
(即塊大小為1.44M)
8.拷貝內存內容到硬碟
ddif=/dev/memof=/root/mem.binbs=1024
(指定塊大小為1k)
9.拷貝光碟內容到指定文件夾,並保存為cd.iso文件
ddif=/dev/cdrom(hdc)of=/root/cd.iso
10.增加swap分區文件大小
第一步:創建一個大小為256M的文件:
ddif=/dev/zeroof=/swapfilebs=1024count=262144
第二步:把這個文件變成swap文件:
mkswap/swapfile
第三步:啟用這個swap文件:
swapon/swapfile
第四步:編輯/etc/fstab文件,使在每次開機時自動載入swap文件:
/swapfileswapswapdefaults00
11.銷毀磁碟數據
ddif=/dev/urandomof=/dev/hda1
注意:利用隨機的數據填充硬碟,在某些必要的場合可以用來銷毀數據。
12.測試硬碟的讀寫速度
ddif=/dev/zerobs=1024count=1000000of=/root/1Gb.file
ddif=/root/1Gb.filebs=64k|ddof=/dev/null
通過以上兩個命令輸出的命令執行時間,可以計算出硬碟的讀、寫速度。
13.確定硬碟的最佳塊大小:
ddif=/dev/zerobs=1024count=1000000of=/root/1Gb.file
ddif=/dev/zerobs=2048count=500000of=/root/1Gb.file
ddif=/dev/zerobs=4096count=250000of=/root/1Gb.file
ddif=/dev/zerobs=8192count=125000of=/root/1Gb.file
通過比較以上命令輸出中所顯示的命令執行時間,即可確定系統最佳的塊大小。
14.修復硬碟
ddif=/dev/sdaof=/dev/sda
當硬碟較長時間(比如1,2年)放置不使用后,磁碟上會產生magneticfluxpoint。當磁頭讀到這些區域時會遇到困難,並可能導致I/O錯誤。當這種情況影響到硬碟的第一個扇區時,可能導致硬碟報廢。上邊的命令有可能使這些數據起死回生。且這個過程是安全,高效的。
15.dd命令做usb啟動盤
ddif=xxx.isoof=/dev/sdbbs=1M
root用戶或者sudo,用以上命令前必須卸載u盤,sdb是你的u盤,bs=1M是塊的大小,後面的數值大,寫的速度相對塊一點,但也不是無限的,我一般選2M,注意,執行命令后很塊完成,但u盤還在閃,等不閃了,安全移除。

命令的解釋


定義

dd是Linux/UNIX下的一個非常有用的命令,作用是用指定大小的塊拷貝一個文件,並在拷貝的同時進行指定的轉換。

參數

1.if=文件名:輸入文件名,預設為標準輸入。即指定源文件。
2.of=文件名:輸出文件名,預設為標準輸出。即指定目的文件。< of=output file >
3.ibs=bytes:一次讀入bytes個位元組,即指定一個塊大小為bytes個位元組。
obs=bytes:一次輸出bytes個位元組,即指定一個塊大小為bytes個位元組。
bs=bytes:同時設置讀入/輸出的塊大小為bytes個位元組。
4.cbs=bytes:一次轉換bytes個位元組,即指定轉換緩衝區大小。
5.skip=blocks:從輸入文件開頭跳過blocks個塊后再開始複製。
6.seek=blocks:從輸出文件開頭跳過blocks個塊后再開始複製。
注意:通常只用當輸出文件是磁碟或磁帶時才有效,即備份到磁碟或磁帶時才有效。
7.count=blocks:僅拷貝blocks個塊,塊大小等於ibs指定的位元組數。
8.conv=conversion:用指定的參數轉換文件。
ascii:轉換ebcdic為ascii
ebcdic:轉換ascii為ebcdic
ibm:轉換ascii為alternateebcdic
block:把每一行轉換為長度為cbs,不足部分用空格填充
unblock:使每一行的長度都為cbs,不足部分用空格填充
lcase:把大寫字元轉換為小寫字元
ucase:把小寫字元轉換為大寫字元
swab:交換輸入的每對位元組
noerror:出錯時不停止
notrunc:不截短輸出文件
sync:將每個輸入塊填充到ibs個位元組,不足部分用空(NUL)字元補齊。