dd,是 device driver 的縮寫,它可以稱得上是“Linux 世界中的搬運工”,它用來讀取設備、文件中的內容,並原封不動地復制到指定位置。
當我們用 dd 命令讀取 /dev/null 文件時,就可以創造出空洞文件,而如果你的磁盤足夠大,你甚至可以創造出一個宇宙黑洞呢!
備份磁盤並恢復
好記性不如爛筆頭,好硬盤不如常備份。硬盤的損壞雖然是個小概率事件,但是一旦發生卻會帶來災難性的后果。對重要數據進行備份,不僅是一個好習慣,更體現了對別人對自己負責的態度。
寫到這里,突然意識到我的硬盤里面存有很多珍貴的資料,一想到可能會因為磁盤故障而永遠失去它們,心里就不禁一顫,趕緊把數據備份提上日程吧!
之前看過一些介紹 dd 的文章,例子中基本都是使用 hda、hdb 這種 IDE 接口的硬盤,其實現在的主流硬盤已經是 SATA 接口的了,下面我要備份的硬盤是 dev/sda,它就是塊 SATA 盤。
[root@roclinux ~]# dd if=/dev/sda of=/root/sda.img
這個命令將 sda 盤備份到指定文件 /root/sda.img 中去,其中用到了如下兩個選項:
- if=文件名:指定輸入文件名或者設備名,如果省略“if=文件名”,則表示從標准輸入讀取。
- of=文件名:指定輸出文件名或者設備名,如果省略“of=文件名”,則表示寫到標准輸出。
通過上面的 dd 命令,我們得到了 sda.img 文件,它就是已經備份好了的磁盤映像文件,里面存儲着 /dev/sda 整塊硬盤的內容。
在未來的某天,假如 /dev/sda 硬盤真的出現了故障,我們就可以將曾經備份的 sda.img 復制到另一台電腦上,並將其恢復到指定的 sdb 盤中去。
[root@roclinux ~]# dd if=/root/sda.img of=/dev/sdb
如果能把目標硬盤直接連接到我們現在的電腦上,並讓系統識別到這塊新硬盤,例如識別成 /dev/sdc,那么我們可以直接使用 dd 命令將 sda 盤復制到 sdc 中去。這種用法既可以用來整盤備份,也可以用來快速復制系統環境。下面來看看具體的命令:
[root@roclinux ~]# dd if=/dev/sda of=/dev/sdc
對 dd 來說,所有設備和文件都一視同仁,所謂的“備份”和“恢復”,dd 都認為是一種內容的復制。dd 操作就是簡單的按字節復制。簡單、直觀,就是我對 dd 的最直接的感受。
備份時進行壓縮
數據沒有壓縮就進行整盤備份,勢必需要很大的備份空間,從而導致備份成本升高。這對於備份場景來說,是低效能的表現。
假如遇到磁盤空間不足,連備份操作都沒辦法圓滿完成:
#看, 報出了磁盤空間不足的警告
[root@roclinux ~]# dd if=/dev/sda of=/root/sda.img dd: writing to '/root/sda.img': No space left on device
其實我們在使用 dd 做備份時,可以使用 gzip 或者 bzip2 壓縮算法進行數據壓縮處理,這樣可以大大減少我們的磁盤空間用量,也就降低了備份成本。
下面就使用 gzip 壓縮算法配合 dd 命令來備份 /dev/sda 盤:
#沒有指定of則表示輸出到標准輸出
然后再將其恢復到 /dev/sdb 盤中去,方法如下:
#沒有指定if就表示從標准輸入讀取
[root@roclinux ~]# dd if=/dev/sda | gzip > /root/sda.img.gz
下面我們更換 bzip2 壓縮算法配合 dd 命令再來實現一遍上面示例的效果:
[root@roclinux ~]# dd if=/dev/sda | bzip2 > disk.img.bz2 [root@roclinux ~]# bzip2 -dc /root/sda.img.gz | dd of=/dev/sdc
分區、內存、軟盤一個都不能少
在上面的內容中,介紹的都是備份整盤的知識,那如果只是想備份某一個分區的數據,應該如何操作呢?
賣了一個關子,其實在 dd 命令看來,備份整盤和備份分區,在命令形式上並沒有區別,我們來看示例:
[root@roclinux ~]# dd if=/dev/sda2 of=/root/sda_part1.img
同理,將內存中的數據整體備份,照樣可以如法炮制:
[root@roclinux ~]# dd if=/dev/mem of=/root/mem.img
隨着科技的飛速發展,無論是台式機還是筆記本,都已經取消了軟驅和光驅設備,軟盤和光盤也已經接近滅絕的邊緣,很多九零后們應該都不知道軟驅為何物了吧。
所以接下來要介紹的軟盤、光盤備份法,權當是追憶過去吧,謹以此內容來懷念我們逝去的青春。
#備份軟盤 [root@roclinux ~]# dd if=/dev/fd0 of=/root/fd0.img count=1 bs=1440k #備份光盤 [root@roclinux ~]# dd if=/dev/cdrom of=/root/cd.img
對於 dd 命令來說,除了 if、of 兩個選項之外,還應該掌握下面這兩個重要選項:
- bs=N:設置單次讀入或單次輸出的數據塊(block)的大小為 N 個字節。當然也可以使用 ibs 和 obs 選項來分別設置。
- ibs=N:單次讀入的數據塊(block)的大小為 N 個字節,默認為 512 字節。
- obs=N:單次輸出的數據塊(block)的大小為 N 個字節,默認為 512 字節。
- count=N:表示總共要復制 N 個數據塊(block)。
所以這里備份的軟盤大小是 1440kB,可以看出這是一塊 3 寸盤,其大小為 1.44MB。為了追憶青春,我們再來一起看看軟盤的樣子。

備份磁盤的 MBR
MBR,是 Master Boot Record,即硬盤的主引導記錄,MBR 一旦損壞,分區表也就被破壞,數據大量丟失,系統就再也無法正常引導了,真是不堪設想啊!所以,對 MBR 的定期備份是十分必要的,在緊急關頭,把它比喻成一顆救死扶傷的速效救心丸,也絕不為過。
一塊磁盤的第一個扇區的 512 個字節所存儲的正是這塊磁盤的 MBR 信息,我們嘗試用 dd 命令備份 MBR:
[root@roclinux ~]# dd if=/dev/sda of=/root/sda_mbr.img count=1 bs=512
如果未來遇到分區表損壞的情況,我們用曾經備份的 MBR 信息寫回磁盤,就能起到立竿見影的效果。下面來一起看看如何將 MBR 寫回硬盤:
[root@roclinux ~]# dd if=/root/sda_mbr.img of=/dev/sda
方法是不是比你想象得要簡單,即使是面對 MBR 如此重要的敏感數據,dd 命令也是閑庭信步,信手拈來。
使用 /dev/zero 和 /dev/null 來測試磁盤
本段落開始前,我們要為大家介紹兩位新朋友:
- /dev/null,也叫空設備,小名“無底洞”。任何寫入它的數據都會被無情拋棄。
- /dev/zero,可以產生連續不斷的 null 的流(二進制的零流),用於向設備或文件寫入 null 數據,一般用它來對設備或文件進行初始化。
我們可以觀察下面兩個命令的執行時間,來計算出硬盤的讀、寫性能:
#向磁盤上寫一個大文件, 來看寫性能 [root@roclinux ~]# dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file #從磁盤上讀取一個大文件, 來看讀性能 [root@roclinux ~]# dd if=/root/1Gb.file bs=64k | dd of=/dev/null
上面命令生成了一個 1GB 的文件 1Gb.file,下面我們配合 time 命令,可以看出不同的塊大小數據的寫入時間,從而可以測算出到底塊大小為多少時可以實現最佳的寫入性能。
[root@roclinux ~]# time dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file [root@roclinux ~]# time dd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file [root@roclinux ~]# time dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file [root@roclinux ~]# time dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file
利用 /dev/urandom 進行格式化
除了 /dev/null 和 /dev/zero 之外,還有一個很重要的文件,即 /dev/urandom,它是“隨機數設備”,它的本領就是可以生成理論意義上的隨機數。
如果我們想清除硬盤里的某些機密數據,就可以使用 /dev/urandom 這個隨機數生成器來產生隨機數據,寫到磁盤上,以確保將磁盤原始數據完全覆蓋掉。
[root@roclinux ~]# dd if=/dev/urandom of=/dev/sda
好了,有關 dd 的故事就介紹到這里了。雖然我們不能創造出真正的宇宙黑洞,但學習了這么多的實用技能,也算不虛此行啦!
原文:http://c.biancheng.net/linux/dd.html