dd 复制文件(可格式转换)

功能:复制一个文件,根据操作数转换和格式化。
把指定的输入文件拷贝到指定的输出文件中,并且在拷贝过程中可以进行格式转换。可以指定输入输出块的大小,可以利用原始的物理 I/O。系统默认使用标准输入文件和标准输出文件。在Linux中,stdout, stdin, stderr的中文名字分别是标准输出,标准输入和标准错误。由于dd命令允许二进制读写,所以特别适合在原始物理设备上进行输入/输出操作。
dd命令常用于备份数据文件数据格式化磁盘管理

语法:dd  [if=输入文件或设备名称]  [选项]    [of=输出文件或设备名称]  [选项]

 

选项 含义
bs=BYTES 一次读写bytes字节。同时设置读写块的大小为 bytes ,可代替 ibs 和 obs 。
cbs=BYTES 一次转换bytes字节。即转换缓冲区大小。
conv=CONVS 用指定的参数转换文件。参数可以是一个也可以是多个。多个转换之间用逗号隔开。
count=N 只复制N输入块。仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数。
ibs=BYTES 一次读取bytes字节。即一个块大小为 bytes 个字节。(默认512)
iflag=FLAGS 读取时数据模式参数。多个参数之间用逗号分隔
obs=BYTES 一次写入bytes字节。即一个块大小为 bytes 个字节。(默认512)
oflag=FLAGS 写入时数据模式参数。多个参数之间用逗号分隔
seek=N 跳过N obs-sized块,作为输出的开始。即从输出文件开头跳过 blocks 个块后再开始复制。
skip=N 跳过N ibs-sized块,作为输入的开始。即从输入文件开头跳过 blocks 个块后再开始复制
status=WHICH 抑制stderr输出。值noxfer抑制传输数据,值none抑制全部

 

N或者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

 

CONVS:
每个CONV可以下面的一种或者多种组合:
ascii:转化 EBCDIC 为 ASCII
ebcdic:转化 ASCII 为 EBCDIC
ibm:转化 ASCII 为 alternate EBCDIC
block:将变长记录转换到固定长度。把每一行转换为长度为cbs,不足部分用空格填充。
unblock:将固定长度的块转化为可变长度。每一行的长度为cbs。
lcase:把大写字符转换为小写字符
ucase:把小写字符转换为大写字符
sparse:尝试寻找而不是写零输入块的输出
swab:交换输入的每对字节
sync:将每个输入块填充到由 ibs 值指定的长度(用NUL填充)
excl:如果输出文件已经退出,则舍弃
nocreat:不创建输入文件
notrunc:不截断输出文件
noerror:读取数据发生错误后仍然继续
fdatasync:结束前将输出文件数据写入磁盘
fsync:类似上面,但是元数据也一同写入

 

FLAGS:
append:追加模式(仅对输出有意义;隐含了conv=notrunc)
direct:使用直接I/O 存取模式
directory:除非是目录,否则 directory 失败
dsync:使用同步I/O 存取模式
sync:与上者类似,但同时也对元数据生效
fullblock:为输入积累完整块(仅iflag)
nonblock:使用无阻塞I/O 存取模式
noatime:不更新存取时间
nocache:丢弃缓存数据
noctty:不根据文件指派控制终端
nofollow:不跟随链接文件

 

设备范围

  • 如果输入文件比输出设备的物理大小要大,dd 命令可以跨设备工作。
  • 在指定块大小时,要 bs 大小设定为设备物理大小的整数倍。若不是整数倍时,需要 conv=sync 参数。因为不正确的块大小将会导致数据的不一致或者重叠。
  • 在写的过程中如果输出设备已经写满,dd 命令提示输入下一个设备时,将发生跨范围操作。从输入设备读入时,如果数据已从设备中完全读取(即使设备没有到达结尾),dd 也将提示下一个设备。在这种情况下,需要按下‘n’退出。

 

注意事项:

dd 命令读取 InFile 参数或者标准输入,进行指定的转换,然后将转换后的结果复制到 OutFile 参数或者标准输出中。可以指定输入输出块的大小,以利用原始的物理 I/O。

  • 通常您只需对输出文件的写许可。但是,当输出文件是不能直接访问的设备并且使用了 seek 标志,您还需要对文件的读访问。
  • 在一个操作中读取或者写的数据的数量,用count参数来指定块的数量,并且无需和磁盘块的大小相等。块的大小有 bs、ibs 、obs来指定。转换完成后,dd 命令将报告完整和部分输入输出块的数量。
  • 由 bs、ibs 和 obs 标志指定的块大小值,必须始终是使用的介质物理块大小的整数倍。
  • conv如果指定了任何 block、unblock、ascii、ebcdic 或 ibm 转换,则使用 cbs 参数值。如果指定了 unblock 或者 ascii 参数,那么 dd 命令将会执行一个固定长度到可变长度的转换。否则它将执行从可变长度到固定长度的转换。cbs 参数决定了该固定长度。注意: 如果 cbs 参数指定的值小于最小输入块的值,则转换块将会被截短。
  • 由 conv=ascii 和 conv=ebcdic 标志关联的字符集映射是求补运算。这些标志在 ASCII 字符和大多数工作站和键控穿孔机上找到的 EBCDIC 字符子集间进行映射。
  • 只有当以 conv=ascii 或 conv=unblock 标志集转换时,dd 命令才会插入新行字符;只有当以 conv=ebcdic、 conv=ibm 或者 conv=block 标志集转换时,才能填充。
  • 当指定了 conv=sync 标志后,dd 命令用空值填充所有的部分输入块。这样,如果任何读取没有接收到一个完整的数据块(由标志 ibs 指定),则 dd 命令将在数据流中间插入空值。在从管道中读入时,这是经常发生的事情。
  • 如果 bs 标志由它自身指定而除了 sync、noerror 或者 notrunc 没有指定其它转换,那么从每个输入块得到的数据将会被作为一个单独的输出块写入;如果读入返回的值小于一个完整的块且没有指定 sync 标志,那么结果输出块将会和输入块的大小相同。如果没有指定 bs 标志或者指定了 sync、noerror 或 notrunc 之外的其它转换,那么输入将会被处理并收集到完整的输出块中,直到输入结束
  • 在将文件复制到磁带时,尽可能使用 backup、tar 或者 cpio 命令来取代 dd 命令。这些命令被设计用来和磁带设备一起使用。要获得更多的使用磁带设备的信息,请参阅 rmt 特殊文件。

实例

数据备份与恢复

整盘数据备份与恢复 
dd if=/dev/hdx of=/dev/hdy   将本地的/dev/hdx整盘备份到/dev/hdy 
 
dd if=/dev/hdx of=/path/to/image   将/dev/hdx全盘数据备份到指定路径的image文件 
dd if=/path/to/image of=/dev/hdx   把备份的image文件恢复 
 
dd if=/dev/hdx | gzip>/path/to/image.gz   备份/dev/hdx全盘数据,并利用gzip工具进行压缩,保存到指定路径 
gzip -dc /path/to/image.gz | dd of=/dev/hdx   将压缩的备份文件恢复到指定盘 
 
 
 
利用netcat远程备份 
dd if=/dev/hda bs=16065b | netcat < targethost-IP > 1234   在源主机上执行此命令备份/dev/hda 
netcat -l -p 1234 | dd of=/dev/hdc bs=16065b  在目的主机上执行此命令来接收数据并写入/dev/hdc 
 
以下两条指令是目的主机指令的变化分别采用bzip2 gzip对数据进行压缩,并将备份文件保存在当前目录: 
netcat -l -p 1234 | bzip2 > partition.img 
netcat -l -p 1234 | gzip > partition.img 
 
 
 
备份MBR 
 MBR,全称为 Master Boot Record,即硬盘的主引导记录 
dd if=/dev/hdx of=/path/to/image count=1 bs=512   备份磁盘开始的512Byte大小的MBR信息到指定文件 
dd if=/path/to/image of=/dev/hdx   将备份的MBR信息写到磁盘开始部分 
 
 
拷贝内存资料到硬盘 
将内存里的数据拷贝到root目录下的mem.bin文件: 
dd if=/dev/mem of=/root/mem.bin bs=1024 
 
 
从光盘拷贝iso镜像 
拷贝光盘数据到root文件夹下,并保存为cd.iso文件: 
dd if=/dev/cdrom of=/root/cd.iso 
 
 
制作优盘启动盘 
首先打开linux的安装光盘,将images目录下的diskboot.img文件复制到/root目录下,然后将优盘挂载到/dev/sdb,然后执行如下命令即可:
dd if=/root/diskboot.img of=/dev/sdb bs=125682176
 
 
销毁磁盘数据 
在某些必要的场合可以利用随机的数据填充硬盘,实现销毁数据。
dd if=/dev/urandom of=/dev/hda1   执行此操作以后,/dev/hda1将无法挂载,创建和拷贝操作无法执行。

 

切割、合并数据文件

要切割的大文件为DGJD,共98336321字节 
dd if=dgjd of=zz1 bs=1 count=20000000 
dd if=dgjd of=zz2 bs=1 count=20000000 skip=20000000 
dd if=dgjd of=zz3 bs=1 count=20000000 skip=40000000 
dd if=dgjd of=zz4 bs=1 count=20000000 skip=60000000 
dd if=dgjd of=zz5 bs=1 count=18336321 skip=80000000 
其中IF(INPUT FILENAME)是要切割的大文件名,OF(OUTPUTFILENAME)是切割后的子文件名,BS是指明以多少字节作为一个切割记录单位,COUNT是要切割的单位记录数,SKIP是说明切割时的起点,单位同样以BS设定值为准。
通过上述五条指令就将DGJD大文件切割成为4个2千万字节、1个18336321字节的子文件。要注意的是SKIP的值不能错。由此也不难看出,DD切割是“非损耗”式的切割,并且支持从任意位置开始的任意大小的切割。
    要将生成的ZZ1、ZZ2、ZZ3、ZZ4四个子文件组装为XDGJD  dd if=zz1 of=xdgjd bs=1 count=20000000  dd if=zz2 of=xdgjd bs=1 count=20000000 seek=20000000  dd if=zz3 of=xdgjd bs=1 count=20000000 seek=40000000  dd if=zz4 of=xdgjd bs=1 count=20000000 seek=60000000  dd if=zz5 of=xdgjd bs=1 count=18336321 seek=80000000  其中SKIP参数改为SEEK参数,指明组装的新大文件XDGJD每次的开始位置是从文件头开始多少字节。如果缺省,则组装从文件头开始,显然这不是我们每次都希望的,所以需用SEEK参数明确指出开始位置。
通过以上5个指令,即可将5个子文件重新组装为一个大文件。将切割后生成的子文件重新用FTP传送,结果有的能够顺利传送,有的仍然导致网络瘫痪,不怕,继续切割,切成每个一千万字节,再传,OK!成功传送!

 

数据转化

要将 ASCII 文本文件转化为 EBCDIC
text.ascii 文件转化为 EBCDIC 版本并存在 text.ebcdic 文件中。
  dd if=text.ascii of=text.ebcdic conv=ebcdic 如果您指定了 conv=ebcdic 参数,dd 命令将会将 ASCII ^(弯曲号)字符转换为未使用的 EBCDIC 字符(十六进制的 9A),将 ASCII ~(代字号)转换为 EBCDIC ^(NOT 符号)。    要将变长记录的 ASCII 文件 /etc/passwd 转换为一个固定长度为 132 字节的 EBCDIC 纪录  dd if=/etc/passwd cbs=132 conv=ebcdic of=/tmp/passwd.ebcdic    要将每个记录为 132 字节的 EBCDIC 文件转换为小写的、可变长度的 ASCII 行  dd if=/tmp/passwd.ebcdic cbs=132 conv=ascii of=/tmp/passwd.ascii    要将变长记录的 ASCII 文件/etc/passwd 转换为一个固定长度为 132 字节的 IBM 版本的 EBCDIC 文件  dd if=/etc/passwd cbs=132 conv=ibm of=/tmp/passwd.ibm    要从块大小为 1kB 的磁带中将块复制到块大小为 2kB 的磁带  dd if=/dev/rmt0 ibs=1024 obs=2048 of=/dev/rmt1

 

跨设备输出

要使用 36个 512 字节块来有效的实现向 3.5 英寸 1.4MB 软盘的传输: 
dd if=Filename of=/dev/rfd0 bs=36b conv=sync
该命令将 Filename 参数的值一次一个柱面的写入到软盘设备。当从磁盘读入或者当文档的大小不是软盘块大小的整数倍时需要 conv=sync 参数。
如果 dd 命令的输入是一个管道而不是一个文件,请勿尝试使用本方法,它将在大多数输入中填充入空格而不只是最后一个块。
    要将块从块大小为 720 字节的输入文件复制到 1.44MB 大小的软盘当中  dd if=testfile of=/dev/fd0 bs=720b conv=sync 要将块从块大小为 32k 字节的输入文件复制到磁带中  dd if=inputfile of=/dev/rmt0 bs=32k conv=sync    要将数据的块从磁带复制到当前目录中的文件中(块大小设置为 32k)  dd if=/dev/rmt0 of=outfile bs=32k conv=sync 要将块从块大小为 720 字节的输入文件复制到 1.44MB 大小的软盘当中  dd if=testfile of=/dev/fd0 bs=720b conv=sync span=yes 要将块从块大小为 32k 字节的输入文件复制到磁带中  dd if=inputfile of=/dev/rmt0 bs=32k conv=sync span=yes   要将块数据从块大小为 32k 的磁带复制到当前目录中的文件中  dd if=dev/rmt0 of=outfile bs=32k conv=sync span=yes       要将 dd 命令作为一个过滤器使用:  ls -l | dd conv=ucase   该命令将用大写字母显示当前目录的长列表    dd 和 cpio 命令在 12 型 9348 磁带单元上的性能可以通过修改缺省块大小来得到改善。要修改块大小,请按下面的方法使用 chdev 命令:  chdev -l Device_name -a block_size=32k

 

磁盘管理

增加swap分区文件大小 
第一步:创建一个大小为256M的文件 
# dd if=/dev/zero of=/swapfile bs=1024 count=262144 
第二步:把这个文件变成swap文件 
# mkswap /swapfile 
第三步:启用这个swap文件 
# swapon /swapfile 
第四步:编辑/etc/fstab文件,使在每次开机时自动加载swap文件
/swapfile swap swap default 0 0 
 
 
 
得到最恰当的block size 
通过比较dd指令输出中所显示的命令执行时间,即可确定系统最佳的block size大小: 
dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.filedd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file 
dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file 
dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file 
 
 
测试硬盘读写速度 
通过两个命令输出的执行时间,可以计算出测试硬盘的读/写速度: 
dd if=/root/1Gb.file bs=64k | dd of=/dev/null 
hdd if=/dev/zero of=/root/1Gb.file bs=1024 count=1000000 
 
 
修复硬盘 
当硬盘较长时间(比如一两年年)放置不使用后,磁盘上会产生magnetic flux point。当磁头读到这些区域时会遇到困难,并可能导致I/O错误。当这种情况影响到硬盘的第一个扇区时,可能导致硬盘报废。
下面的命令有可能使这些数据起死回生。且这个过程是安全,高效的。
  dd if=/dev/sda of=/dev/sda