[关闭]
@breakerthb 2017-06-19T07:43:26.000000Z 字数 3289 阅读 1477

dd

Linux


dd的作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。

1. 查看帮助

$ dd --help

或是

$ info dd

查看当前版本

$ dd --version

输入或输出

$ dd if=[STDIN] of=[STDOUT]

2. 语法:

dd [选项]

if = 输入文件(或设备名称)。
of = 输出文件(或设备名称)。
ibs = bytes 一次读取bytes字节,即读入缓冲区的字节数。
skip = blocks 跳过读入缓冲区开头的ibs*blocks块。
obs = bytes 一次写入bytes字节,即写入缓冲区的字节数。
bs = bytes 同时设置读/写缓冲区的字节数(等于设置ibs和obs)。
cbs = byte 一次转换bytes字节。
count=blocks 只拷贝输入的blocks块。
conv = ASCII 把EBCDIC码转换为ASCIl码。
conv = ebcdic 把ASCIl码转换为EBCDIC码。
conv = ibm 把ASCIl码转换为alternate EBCDIC码。
conv = block 把变动位转换成固定字符。
conv = ublock 把固定位转换成变动位。
conv = ucase 把字母由小写转换为大写。
conv = lcase 把字母由大写转换为小写。
conv = notrunc 不截短输出文件。
conv = swab 交换每一对输入字节。
conv = noerror 出错时不停止处理。
conv = sync 把每个输入记录的大小都调到ibs的大小(用NUL填充)。

例如

强迫输入或输出的Size为多少Bytes

$ dd -ibs=[BYTE] -obs=[SIZE]

强迫一次只做多少个 Bytes

cbs=BYTES

跳过一段以后才输出

seek=BLOCKS

跳过一段以后才输入

skip=BLOCKS

3. 生成指定大小的文件

我们在测试或调试的时候,有时候会需要生成某个size的文件。

3.1 Demo 1 : 生成固定大小的文件

生成一个大小为5G的文件,内容不做要求。命令如下:

$ dd if=/dev/zero of=tmp.5G bs=1G count=5

解释一下这里用到的参数

if=FILE      : 指定输入文件,若不指定则从标注输入读取。这里指定为/dev/zero是Linux的一个伪文件,它可以产生连续不断的null流(二进制的0)
of=FILE      : 指定输出文件,若不指定则输出到标准输出
bs=BYTES     : 每次读写的字节数,可以使用单位K、M、G等等。另外输入输出可以分别用ibs、obs指定,若使用bs,则表示是ibs和obs都是用该参数
count=BLOCKS : 读取的block数,block的大小由ibs指定(只针对输入参数)

这样上面生成5G文件的命令就很好理解了,即从/dev/zero每次读取1G数据,读5次,写入tmp.5G这个文件。

注意

/dev/null, 外号叫无底洞,可以向它输出任何数据,它通吃
/dev/zero, 是一个输入设备,可以用它来初始化文件,得到的永远是0

3.2 文件拼接

将file.in的前1M追加到file.out的末尾。命令如下:

$ file_out_size=`du -b file.out | awk '{print $1}'`
	$ dd if=./file.in ibs=1M count=1 of=./file.out seek=1 obs=$file_out_size

这里ibs和obs设置为了不同的值,和前面的命令相比,只多了一个seek参数

seek=BLOCKS : 在拷贝数据之前,从输出文件开头跳过BLOCKS个block,block的大小由obs指定

命令的意思就是从file.in读取1个1M的数据块写入file.out,不过写入位置并不在file.out的开头,而是在1 * $file_out_size字节偏移处(也就是文件末尾)

在此基础上再增加一个要求,将file.in的第3M追加到file.out的末尾

$ file_out_size=`du -b file.out | awk '{print $1}'`
	$ dd if=./file.in skip=2 ibs=1M count=1 of=./file.out seek=1 obs=$file_out_size

这里多了一个参数skip

skip=BLOCKS : 拷贝数据前,从输入文件跳过BLOCKS个block,block的大小由ibs指定。这个参数和seek是对应的

上面命令的意思就是,从文件file.in开始跳过2*1M,拷贝1*1M数据,写入文件file.out的1*$file_out_size偏移处

这样基本的参数都介绍全了,无非就是设置输入输出文件以及各自的偏移,设置读写数据块大小和读取数据块个数,下面总结一下

3.3 用指定字符初始化文件

指定某个字符,创建一个全是这个字符的指定大小的文件。比如创建一个文件,大小为123456字节,每个字节都是字符A。

这问题看似没什么意义,但有时候确实需要用到。比如我通过/dev/null创建了一个1G的文件,但是出于测试需求我想修改中间100M数据,这时我需要创建一个100M的文件,将该文件写入到那个1G文件的指定位置,而这个100M的文件是不能从/dev/null创建的,否则达不到修改的目的,这时候就需要这样的功能了

#!/bin/bash
if [ $# -ne 3 ];then
		echo "usage : $0 character out_file file_size(Byte)"
    exit 1
fi

echo "$1" | grep -q "^[a-zA-Z]$"
if [ $? -ne 0 ];then
    echo "arg1 must be character"
    exit 1
fi

character=$1
	out_file=$2
target_size=$3

# echo输出默认是带'\n'字符的,所以需要通过dd指定输入字节数
echo "$character" | dd of=$out_file ibs=1 count=1
while true
do
    cur_size=`du -b $out_file | awk '{print $1}'`
    if [ $cur_size -ge $target_size ];then
        break
    fi
    remain_size=$((target_size-$cur_size))
    if [ $remain_size -ge $cur_size ];then
        input_size=$cur_size
		else
			input_size=$remain_size
    fi
    dd if=$out_file ibs=$input_size count=1 of=$out_file seek=1 obs=$cur_size || exit 1
done

有了这些技巧,在对文件内容无要求的前提下,你就可以任意创建指定大小的文件,任意修改文件指定字节数,这会让某些测试场合变得非常方便

4. 制作系统安装U盘

dd命令做usb启动盘十分方便,只须:

$ sudo dd if=xxx.iso of=/dev/sdb bs=2M

用以上命令前必须卸载u盘,sdb是你的u盘,bs=1M是块的大小,后面的数值大,写的速度相对块一点,但也不是无限的,我一般选2M,注意,执行命令后很块完成,但u盘还在闪,等不闪了,安全移除。

PS

$ ps -ef | grep dd  //查看 dd 进程id号,其实上边命令加&后,己经显示了。
	$ kill -USR1  id  //查看 dd 完成进度
100118036480 bytes (100 GB) copied, 1346.94 seconds, 74.3 MB/s

如果想时时查看进度,可以用下面语句:

$ watch -n 1 kill -USR1 3730  // 每2秒查看一次进度
	$ while kill -USR1 3730;do sleep 2;done;  //每2秒查看一次进度

这种是通过发送USR1信号的方法,去产生一个标准的IO错误,来达到显示当前COPY进度与COPY速度的目的。

5. 磁盘对拷

$ dd if=/dev/hdb of=/dev/hdc

5. 刻录光碟

$ dd if=/dev/cdrom of=cdrom.iso

其中if后面是光驱的挂载点,of后面是要刻录的内容。

然后给系统这个指令就可以烧了:

$ cdrecord -v cdrom.iso
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注