dd 命令介绍

Linux dd 命令用于读取、转换并输出数据。

dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。

dd 命令使用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。可以用于测试磁盘命令、数据备份或恢复等。

参数说明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if=文件名:      输入文件名,默认为标准输入。即指定源文件。
of=文件名:      输出文件名,默认为标准输出。即指定目的文件。
ibs=bytes:     一次读入bytes个字节,即指定一个块大小为bytes个字节。
obs=bytes:     一次输出bytes个字节,即指定一个块大小为bytes个字节。
bs=bytes:      同时设置读入/输出的块大小为bytes个字节。
cbs=bytes:     一次转换bytes个字节,即指定转换缓冲区大小。
skip=blocks:   从输入文件开头跳过blocks个块后再开始复制。
seek=blocks:   从输出文件开头跳过blocks个块后再开始复制。
count=blocks:  仅拷贝blocks个块,块大小等于ibs指定的字节数。
conv=<关键字>:  关键字可以有以下11种:
conversion:    用指定的参数转换文件。
    ascii:         转换ebcdic为ascii
    ebcdic:        转换ascii为ebcdic
    ibm:           转换ascii为alternate ebcdic
    block:         把每一行转换为长度为cbs,不足部分用空格填充
    unblock:       使每一行的长度都为cbs,不足部分用空格填充
    lcase:         把大写字符转换为小写字符
    ucase:         把小写字符转换为大写字符
    swab:          交换输入的每对字节
    noerror:       出错时不停止
    notrunc:       不截短输出文件
    sync:          将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。
--help:        显示帮助信息
--version:     显示版本信息

指定数字的地方若以下列字符结尾乘以相应的数字: 
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.

使用实例

1. 在Linux 下制作启动盘,可使用如下命令:
1
dd if=boot.img of=/dev/fd0 bs=1440k 
2. 将testfile文件中的所有英文字母转换为大写,然后转成为testfile_1文件,在命令提示符中使用如下命令:
1
dd if=testfile_2 of=testfile_1 conv=ucase 

其中testfile_2 的内容为:

1
2
3
4
5
$ cat testfile_2 #testfile_2的内容  
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 

转换完成后,testfile_1 的内容如下:

1
2
3
4
5
6
7
8
$ dd if=testfile_2 of=testfile_1 conv=ucase #使用dd 命令,大小写转换记录了0+1 的读入  
记录了0+1 的写出  
95字节(95 B)已复制,0.000131446 秒,723 KB/s  
cmd@hdd-desktop:~$ cat testfile_1 #查看转换后的testfile_1文件内容  
HELLO LINUX!  
LINUX IS A FREE UNIX-TYPE OPTERATING SYSTEM.  
THIS IS A LINUX TESTFILE!  
LINUX TEST #testfile_2中的所有字符都变成了大写字母 
3. 由标准输入设备读入字符串,并将字符串转换成大写后,再输出到标准输出设备,使用的命令为:
1
dd conv=ucase 

输入以上命令后按回车键,输入字符串,再按回车键,按组合键 Ctrl+D 退出,出现以下结果:

1
2
3
4
5
6
$ dd conv=ucase 
Hello Linux! #输入字符串后按回车键  
HELLO LINUX! #按组合键Ctrl+D退出,转换成大写结果  
记录了0+1 的读入  
记录了0+1 的写出  
13字节(13 B)已复制,12.1558 秒,0.0 KB/s
4. 备份 /dev/hdb 全盘数据,并利用 gzip 工具进行压缩,保存到指定路径
1
dd if=/dev/hdb | gzip > /root/image.gz
5. 将压缩的备份文件恢复到指定盘
1
gzip -dc /root/image.gz | dd of=/dev/hdb
6. 备份磁盘开始的 512 个字节大小的 MBR 信息到指定文件
1
2
3
4
dd if=/dev/hda of=/root/image count=1 bs=512
// count=1 指仅拷贝一个块
// bs=512  指块大小为 512 个字节
恢复:dd if=/root/image of=/dev/hda
7. 备份软盘
1
dd if=/dev/fd0 of=disk.img count=1 bs=1440k (即块大小为1.44M)
8. 从文件开头先跳过 skipbs 大小的内容,复制 countbs 大小的内容过来用 grep 查询
1
dd if=filename bs=1024 skip=3600 count=1200 | grep '****'
9. 生成一个1000M的test文件,文件内容为全0(因从/dev/zero中读取,/dev/zero为0源)
1
dd if=/dev/zero of=test bs=1M count=1000

但是这样为实际写入硬盘,文件产生速度取决于硬盘读写速度,如果欲产生超大文件,速度很慢。

在某种场景下,我们只想让文件系统认为存在一个超大文件在此,但是并不实际写入硬盘。

10. 生成一个100G的test文件,但是并不实际占用block,因此创建速度与内存速度相当
1
dd if=/dev/zero of=test bs=1M count=0 seek=100000

seek 的作用是跳过输出文件中指定大小的部分,这就达到了创建大文件,但是并不实际写入的目的。

当然,因为不实际写入硬盘,所以你在容量只有 10G 的硬盘上创建 100G 的此类文件都是可以的。