Linux 的 dd 命令
dd
这个命令一直没有弄明白缩写的含义,这个命令应该归到Linux炫技里面,因为我也是很晚才用到,不过有些功能还可以尝试一下。
官方含义为:
dd
- convert and copy a file
从官方含义来看,是不是定义为
cc
比较合适,^_^
dd
命令用于复制文件,转换或者格式化文件。
dd
命令功能很强大的,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果。
命令格式
命令比较简单:
1 | $ dd 选项 |
对于刚开始而言,仅仅下面几个掌握下面几个参数就完全够用了。
- of=FILE, 将输出定位到FILE,而不是默认的stdout
- bs=BYTES,每次读取的字节数,默认为512字节
- count=N, 拷贝N个输入块
- if=FILE, 从FILE输入,而不是默认的stdin
考虑替换cp
命令
既然命令第一个说明就是拷贝文件,那么正常情况下基本是可以替换cp的,不过前提是有参数指定,比如:
1 |
|
为什么dd
这么慢,很简单,在不指定bs的情况下,默认为512字节,dd
就会根据512来切分,时间都浪费在了这个上面。
所以简单地加上这个参数,迅速提升效率
1 | $ time dd if=a of=b bs=2M |
测试硬盘速度
我最常使用的dd命令的用例是,测试硬盘的读写速度,比如很简单地写入1GB、10GB来看一下。
1 | $ dd if=/dev/zero of=tmp bs=1M count=1000 |
然后根据这些参数,可以简单写一个脚本来评估系统的整体读写速率了。
当然dd
系统管理员用的最多的应该是系统备份和克隆了,暂且不表。
#######TODO
backup an entire copy of a hard disk to another hard disk
1 | # dd if=/dev/sda of=/dev/sdb conv=sync,noerror |
cbs=BYTES
convert BYTES bytes at a time
conv=CONVS
convert the file as per the comma separated symbol list
ibs=BYTES
read up to BYTES bytes at a time (default: 512)
iflag=FLAGS
read as per the comma separated symbol list
obs=BYTES
write BYTES bytes at a time (default: 512)
oflag=FLAGS
write as per the comma separated symbol list
seek=N skip N obs-sized blocks at start of output
skip=N skip N ibs-sized blocks at start of input
status=LEVEL
The LEVEL of information to print to stderr; 'none' suppresses everything but error messages, 'noxfer'
suppresses the final transfer statistics, 'progress' shows periodic transfer statistics
N and BYTES may be followed by the following multiplicative suffixes: 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, and so on for T, P, E, Z, Y.
Each CONV symbol may be:
ascii from EBCDIC to ASCII
ebcdic from ASCII to EBCDIC
ibm from ASCII to alternate EBCDIC
block pad newline-terminated records with spaces to cbs-size
unblock
replace trailing spaces in cbs-size records with newline
lcase change upper case to lower case
ucase change lower case to upper case
sparse try to seek rather than write the output for NUL input blocks
swab swap every pair of input bytes
sync pad every input block with NULs to ibs-size; when used with block or unblock, pad with spaces rather
than NULs
excl fail if the output file already exists
nocreat
do not create the output file
notrunc
do not truncate the output file
noerror
continue after read errors
fdatasync
physically write output file data before finishing
fsync likewise, but also write metadata
Each FLAG symbol may be:
append append mode (makes sense only for output; conv=notrunc suggested)
direct use direct I/O for data
directory
fail unless a directory
dsync use synchronized I/O for data
sync likewise, but also for metadata
fullblock
accumulate full blocks of input (iflag only)
nonblock
use non-blocking I/O
noatime
do not update access time
nocache
Request to drop cache. See also oflag=sync
noctty do not assign controlling terminal from file
nofollow
do not follow symlinks
count_bytes
treat 'count=N' as a byte count (iflag only)
skip_bytes
treat 'skip=N' as a byte count (iflag only)
seek_bytes
treat 'seek=N' as a byte count (oflag only)
Sending a USR1 signal to a running 'dd' process makes it print I/O statistics to standard error and then re‐
sume copying.
使用dd命令克隆整个系统
进入Linux操作系统,打开命令行,执行如下命令:
1 | sudo fdisk -u -l |
可以查看所有磁盘上的所有分区的尺寸和布局情况。
-u,让start和end中数字的单位是512字节,也就是一个sector扇区的大小。
具体步骤
找一个U盘,安装UbuntuLive Cd系统。
U盘启动,进入盘上的Ubuntu系统,打开命令行,执行:
1 | sudo fdisk -u -l /dev/sda |
查看硬件的分区情况。
然后执行:
1 | dd bs=512 count=[fdisk命令中最大的end数+1] if=/dev/sda of=/ghost.img |
这样,就可以把我需要的分区数据全部copy到ghost.img文件中。镜像制作完成了!
然后,我们就可以把U盘插到其他系统上,用U盘启动,进入UbuntuLiveCD,打开命令行,执行如下命令:
1 | dd if=/ghost.img of=/dev/sda |
完成后,拔掉U盘,启动计算机,就可以看到我们的Linux系统已经安装完毕了!
注意:不要直接在计算机上用本地磁盘启动系统后执行dd命令生成本地磁盘的镜像。而应该使用livecd启动计算机。因此计算机运行时会对系统盘产生大量写操作。 直接对运行中的系统盘生成的镜像,在恢复到其他硬盘上时,很可能会无法启动!
一样适用于非Linux操作系统, 在linux上用dd命令实现系统镜像备份和恢复,是不是很简单呢?
对于Windows系统,甚至Mac等等任意系统,其实都可以用dd命令实现系统镜像的备份和恢复。
因为,Linux的fdisk命令能够识别任意系统下的分区格式。fdisk并不关系分区上的文件系统,甚至有无文件系统都不关心。fdisk总是可以报告分区占用了哪些扇区。
dd命令也不关心磁盘的文件系统格式,它只是简单地按照要求从指定的位置,复制多少字节数据而已。
dd命令实现镜像备份和恢复,比Ghost软件简单和强大多了。使用ghost软件,依然需要用户进行复杂而危险的磁盘分区操作。
而使用fdisk和dd这两条命令,一切都免了!
压缩和解压缩
可能我们需要备份的分区很大,使用dd命令生成的镜像文件也就很大。存储和传输这些镜像不太方便。 我们也可以使用压缩程序压缩生成的镜像文件。 这里,我选择使用gzip程序,配合dd命令一起使用。
gzip参数:
- -c 表示输出到stdout
- -d 表示解压缩
- -1 表示最快压缩
- -9 表示最好压缩
默认使用的是-6压缩级别。
要使用 dd 和 gzip 生成压缩的镜像文件,可以执行命令:
1 | dd bs=512 count=[fdisk命令中最大的end数+1] if=/dev/sda | gzip -6 > /ghost.img.gz |
还原时,可以执行下列命令: # gzip -dc /ghost.img.gz.gz | dd of=/dev/sda
提醒:
如果你把镜像恢复到另一台计算机上,你可能会发现你的网卡是eth1,而不是eth0。这是因为
/etc/udev/rules.d/70-persistent-net.rules 文件把你做镜像的计算机的网卡作为eth0登记了。
如果你的网络脚本对eth0进行了处理,而没有对eth1进行处理,那么不修改网络脚本,你可能就无法上网了。
也许你会希望在做镜像之前,先删除 /etc/udev/rules.d/70-persistent-net.rules 文件。这样你恢复镜像时,网卡的名字就是eth0。 就不会造成你在恢复后的计算机上无法上网的问题了。