dd命令详解

dd 命令解析

dd 是 Linux/Unix 下的一个非常有用的命令,作用是将指定大小的输入文件(或设备文件)按 block 为单位拷贝到指定的输出文件(或设备文件)中,并在拷贝的同时进行指定的转换。 当不指定转换 conv 选项的时候,使用指定的输入和输出块大小来复制文件(默认是从标准输入到标准输出)。

dd 每次从输入文件或设备文件读取指定大小的一个块(默认是 512 字节),如果使用 bs=bytes 选项,将把全部读到的数据写到独立的输出块,这个输出块的长度和读到的数据完全一样,除非指定使用 sync 选项转换。 其他情况下,输入的时候每次读一个块,然后处理,并将输出结果收集起来,最后写到指定大小的数据块中去,最终的输出块可能会比指定的大小短一些。<!-- more -->

dd 命令 manual

dd 命令主要选项
if=FILE
指定输入文件的名称,缺省为标准输入。
of=FILE
指定输出文件的名称,缺省是标准输出。
bs=BYTES
指定输入输出块的大小,取代 ibs 和 obs 标志,由 bs 标志指定的块大小值必须始终是使用的媒介物理块大小的整数倍。
cbs=BYTES
指定由可变长度到固定长度和从固定长度到可变长度的转换块大小。
conv=CONVERSION[,CONVERSION]...
指定一个或多个转换选项。多个转换之间用逗号隔开。
count=BLOCKS
仅复制由 BLOCKS 变量指定的输入块的数量。
ibs=BYTES
指定输入块的大小;缺省为 512 字节。
obs=BYTES
指定输出块的大小;缺省为 512 字节。
seek=BLOCKS
在复制之前,从输出文件开头跳过 BLOCKS 值的块大小, 每块大小为 obs-byte 字节。
skip= BLOCKS
在开始复制之前跳过指定的 BLOCKS 值的输入块,每块大小为 ibs-byte 字节。
数字值选项 BLOCKS 和 BYTES 后面可以跟一个乘数:c =1, w =2, b =512, kB =1000, K =1024, MB =1000*1000, M =1024*1024, xM =M, GB =1000*1000*1000, G =1024*1024*1024 等等,同理可得 T, P, E, Z, Y。
常用 CONV 转换参数介绍
block
将变长记录转换到固定长度,长度由转换块大小(cbs)决定。对于换行用空格代替,必要时使用空格填充。
unblock
将固定长度的块转化为可变长度。长度由转换块大小(cbs)决定。该选项与 block 选项冲突。
lcase
将所有大写字符转换为小写字符。
nocreat
不创建输出文件;输出文件必须已经存在。
excl
如果输出文件已经存在则操作失败,该选项与 nocreat 选项冲突。
notrunc
不截取输出文件。
ucase
把所有小写字符转换为大写字符。
swab
交换每对输入字节。对于 GNU dd,如果读入的最后的字节数是奇数,则只是简单的复制到输出(因为没有能跟它交换的字节)。
noerror
发生错误时也不停止进程,继续进行。
sync
使用 zero 字节将每个输入块填充到 ibs 值指定的长度。如果指定 block 或者 unblock 选项,则以空格补齐。
fdatasync
在复制结束之前,同步输出数据。改选项将会做物理写入操作。
fsync
在复制结束之前,同步输出数据和元数据。改选项将会做物理写入操作。

dd 命令实例

数据备份与恢复
整盘数据备份与恢复
备份 :
1. 将本地的 /dev/sdx 整盘备份到 /dev/sdy;
 dd if=/dev/sdx of=/dev/sdy 

2. 将 /dev/sdx 全盘数据备份到指定路径的 image 文件;
 dd if=/dev/sdx of=/path/image 

3. 备份 /dev/sdx 全盘数据,并利用 gzip 工具进行压缩,保存到指定路径。
 dd if=/dev/sdx | gzip >/path/image.gz 

恢复 :
1. 将备份文件恢复到指定盘;
 dd if=/path/image of=/dev/sdx 

2. 将压缩的备份文件恢复到指定盘。
 gzip -dc /path/image.gz | dd of=/dev/sdx
备份MBR
备份:
备份磁盘开始的 512Byte 大小的 MBR 信息到指定文件;
 dd if=/dev/sdx of=/path/file count=1 bs=512 

恢复:
将备份的 MBR 信息写到磁盘开始部分。
 dd if=/path/file of=/dev/sdx
备份软盘
1. 将软驱数据备份到当前目录的 disk.img 文件;
 dd if=/dev/fd0 of=disk.img count=1 bs=1440k 

2. 要使用 36 个 512 字节块来有效的实现向软盘的传输;
 dd if=filename of=/dev/fd0 bs=36b conv=sync 

该命令将 Filename参数的值一次一个柱面地写入到软盘设备。当从磁盘读入或者当文档的大小不是软盘块大小的整数倍时,需要 conv=sync 参数。
3. 将块大小为 720 字节的输入文件复制到软盘当中,请输入:
 dd if=testfile of=/dev/fd0 bs=720b conv=sync
如果输入文件大于输出设备的物理大小,则 dd 命令将会提示您使用另外一个设备。
拷贝内存资料到硬盘
将内存里的数据拷贝到 root 目录下的 mem.bin 文件。
 dd if=/dev/mem of=/root/mem.bin bs=1024 

从光盘拷贝iso镜像
拷贝光盘数据到 root 文件夹下,并保存为 cdrom.iso 文件。
 dd if=/dev/cdrom of=/root/cdrom.iso
创建 Swap 分区文件
1. 创建一个足够大的文件(此处以 256M 为例),数据必须是连续的;
 dd if=/dev/zero of=/swapfile bs=1024 count=262144 

2. 使用 mkswap 制作 swap;
 mkswap /swapfile 

3. 启用这个 swap 文 件;
 swapon /swapfile 

4. 设置每次开机的时候自动加载 swap 文 件 , 修改 /etc/fstab 文件。
 /swapfile swap swap defaults 0 0
销毁磁盘数据
利用随机的数据填充硬盘:
 dd if=/dev/urandom of=/dev/hda1
该方法可以用来销毁数据。执行此操作以后,/dev/hda1 将无法挂载,创建和拷贝操作。

磁盘管理
确定系统最佳的block 大小
通过比较 dd 指令输出中所显示的命令执行时间,即可确定系统最佳的 block 大小。
 dd if=/dev/zero bs=1024 count=1000000 of=/root/testfile
 dd if=/dev/zero bs=2048 count=500000 of=/root/ testfile
 dd if=/dev/zero bs=4096 count=250000 of=/root/ testfile
 dd if=/dev/zero bs=8192 count=125000 of=/root/ testfile 

测试硬盘读写速度
通过两个命令输出的执行时间,可以计算出测试硬盘的读 / 写速度。
 dd if=/dev/zero of=/root/testfile bs=1024 count=1000000
 dd if=/root/testfile bs=64k | dd of=/dev/null

显示dd命令的进度:

dd if=/dev/zero of=/tmp/zero.img bs=10M count=100000
想要查看上面的dd命令的执行进度,可以使用下面四种方法:

如:每5秒输出dd的进度

方法一:

watch -n 5 pkill -USR1 ^dd$
方法二:

watch -n 5 killall -USR1 dd
方法三:

while killall -USR1 dd; do sleep 5; done
方法四:

while (ps auxww |grep " dd " |grep -v grep |awk '{print $2}' |while read pid; do kill -USR1 $pid; done) ; do sleep 5; done
上述四种方法中使用三个命令:pkill、killall、kill向dd命令发送SIGUSR1信息,dd命令进程接收到信号之后就打印出自己当前的进度。

方法五:
dd if=/dev/zero| pv | dd of=/tmp/zero.img bs=10M count=100000
使用pv显示dd进度

参考:1.  2.