Linux入门之磁盘管理(5)dd命令使用
在Linux中,经常需要一些数据读写等测试,还有文件以及其它数据的备份迁移,一般使用cp命令可以解决一部分,但是其无法进行控制数据的流向及动作,这时就可以使用dd命令,来进行灵活的数据流操作。
dd 命令用法:
dd if=/PATH/FROM/SRC of=/PATH/TO/DEST
#解析:if表示inputfile,表示从if所指的文件读取数据流,然后输出到of所指的文件
详细解析:
bs=# :block size,复制单元大小,默认不指定为byte,可以指定M
count=#: #进行#次bs指定大小复制
if=file: #写到所命令的文件而不是到标准输入
bs=size: #指定块大小,同时代表输入和输出设备
ibs=szie: #一次读指定 size大小的byte
obs=size: #一次写size个byte
cbs=size: #一次转化size个byte
skip=block: #if从开头跳过指定块数的ibs
seek=block: #of从开头跳过指定块数的块
count=n: #拷贝次数,及拷贝多少次块记录
conv=conversion[,conversion...] 用指定的参数转换文件。
转换参数:
ascii #将EBCDIC编码转换为ASCII
ebcidc #将ASCII编码转化为EBCDIC
block #转换为长度为cbs的记录,不足部分用空格填充
unblock #替代cbs长度的每一行尾的空格为新行。
lcase #把大小字符转换为小写字符
ucase #把小写字符转换为大写字符
swab #交换输入的每对字节
noerror #出错时不停止
notrunc #不截断输出文件
sync #把每个输入块填充到ibs个字节,不足部分用空(NULL)字符补齐
数据转化举例:
改变指定位数据
#这里生成2个文件,分别存放1到9的数字以及a到z的字母 [root@mzf ~]# echo {1..9} | tr -d ‘[:space:]‘ | tee f1 123456789 [root@mzf ~]# echo {a..z} | tr -d ‘[:space:]‘ | tee f2 abcdefghijklmnopqrstuvwxyz
如何将f2文件中的cdef转换为 f1文件中的6789?
#使用dd命令指定跳过多少个bs指定的单位:字节,注意需要不截断 [root@mzf ~]# dd if=f1 of=f2 skip=5 seek=2 bs=1 conv=notrunc 4+0 records in 4+0 records out 4 bytes (4 B) copied, 0.000138904 s, 28.8 kB/s [root@mzf ~]# cat f2 ab6789ghijklmnopqrstuvwxyz
解析:为什么需要不截断呢?如果不截断,f1从第6个字节数据位置进行写入,而f2在第2个字节后的5个字节被转换后,后面的数据也被删除掉,这就是截断:
[root@mzf ~]# dd if=f1 of=f2 skip=5 seek=2 bs=1 4+0 records in 4+0 records out 4 bytes (4 B) copied, 0.000145405 s, 27.5 kB/s [root@mzf ~]# cat f2 ab6789
大小写转换:
#再次生成一个f3文件来保存a-z小写字母 [root@mzf ~]# echo {a..z} | sed ‘s/[[:space:]]//g‘ | tee f3 abcdefghijklmnopqrstuvwxyz #将f3中小写字母全部转换为大写字母 [root@mzf ~]# dd if=f3 of=f4 conv=ucase 0+1 records in 0+1 records out 27 bytes (27 B) copied, 0.000122919 s, 220 kB/s
[root@mzf ~]# cat f4 ABCDEFGHIJKLMNOPQRSTUVWXYZ #再将f3中的大小字母全部转换为小写字母 [root@mzf ~]# dd if=f4 of=f5 conv=lcase 0+1 records in 0+1 records out 27 bytes (27 B) copied, 0.000287493 s, 93.9 kB/s [root@mzf ~]# cat f5 abcdefghijklmnopqrstuvwxyz
#不用写入新文件直接转换文件中数据别不修改源文件 [root@mzf ~]# cat f3 abcdefghijklmnopqrstuvwxyz [root@mzf ~]# dd if=f3 conv=ucase 2> /dev/null ABCDEFGHIJKLMNOPQRSTUVWXYZ [root@mzf ~]# cat f3 abcdefghijklmnopqrstuvwxyz #直接操作源文件数据进行转换 [root@mzf ~]# echo `dd if=f3 conv=ucase 2> /dev/null` > f3
注意:这里想要直接操作源文件,if=f3 of=f3是万万不行的。
操作磁盘数据
备份mbr:
#查看/dev/sda下的分区 [root@mzf ~]# fdisk -l /dev/sda | grep ‘^/dev‘ /dev/sda1 * 1 26 204800 83 Linux /dev/sda2 26 1332 10485760 83 Linux /dev/sda3 1332 1593 2097152 82 Linux swap / Solaris /dev/sda4 1593 2611 8182784 5 Extended /dev/sda5 1593 1854 2103487+ 83 Linux /dev/sda6 855 2116 2104483+ 83 Linux
#将/dev/sda下的mbr信息配分到文件中 [root@mzf ~]# dd if=/dev/sda of=/backup/mbr.bak bs=512 count=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.000292654 s, 1.7 MB/s
#将/dev/sda下的mbr复制给其它空硬盘 [root@mzf ~]# dd if=/backup/mbr.bak of=/dev/sdc bs=512 count=1 2> /dev/null [root@mzf ~]# fdisk -l /dev/sdc | grep ‘^/dev‘ Warning: invalid flag 0x0000 of partition table 5 will be corrected by w(rite) /dev/sdc1 * 1 26 204800 83 Linux /dev/sdc2 26 1332 10485760 83 Linux /dev/sdc3 1332 1593 2097152 82 Linux swap / Solaris /dev/sdc4 1593 2611 8182784 5 Extended
解析:这里分区表的信息为什么少了两个分区,这是因为,4号为扩展分区,扩展分区中会分配每个逻辑分区特定的lbr,因此无法从各个逻辑分区中直接拷贝其数据
只破坏硬盘的bootloader
[root@mzf ~]# dd if=/dev/zero of=/dev/sdc bs=446 count=1 conv=notrunc 1+0 records in 1+0 records out 446 bytes (446 B) copied, 0.0717781 s, 6.2 kB/s
#这里使用十六进制查看,前面446字节全被写入0,但是后面的分区信息以及55aa标示任然保留,当然,/dev/sdc并不是系统盘,bootloader是用于引导系统的,这里不影响存数据。
[root@mzf ~]# hexdump -C -n 512 /dev/sdc 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 20 |............... | 000001c0 21 00 83 9f 06 19 00 08 00 00 00 40 06 00 00 9f |!..........@....| 000001d0 07 19 83 fe ff ff 00 48 06 00 00 00 40 01 00 fe |.......H....@...| 000001e0 ff ff 82 fe ff ff 00 48 46 01 00 00 40 00 00 fe |.......HF...@...| 000001f0 ff ff 05 fe ff ff 00 48 86 01 00 b8 f9 00 55 aa |.......H......U.| 00000200 [root@mzf ~]# fdisk -l /dev/sdc 2> /dev/null | grep ‘^/dev‘ /dev/sdc1 * 1 26 204800 83 Linux /dev/sdc2 26 1332 10485760 83 Linux /dev/sdc3 1332 1593 2097152 82 Linux swap / Solaris /dev/sdc4 1593 2611 8182784 5 Extended
小问题:
有二进制文件fileA,size>2K。现在想从第64个字节位置开始读取,需要读取的大小是128Byts。又有fileB, 想把上面读取到的128Bytes写到第32个字节开始的位置,替换128Bytes,请问如何实现?
[root@mzf ~]#dd if=fileA of=fileB bs=128 skip=63 seek=31 count=1 conv=notrunc [root@mzf ~]#dd if=fileA of=fileB bs=1 skip=63 seek=31 count=128 conv=notrunc
磁盘数据备份:
提示:dd在对于不同的数据对象操作时,数据流可能会有所不同,比如,如果是对于一个文本文件,那么输出的流就很简单,就是一种字符流,当然内部是将字节流转换为字符流的过程,因此,在操作存文本数据时,dd命令输出的数据还是可以文本查看工具进行查看的,但是,如果操作的并非一个纯文本文件,比如说是某种设备上的数据,那么把一种设备对象当一个文件流来操作,就是直接操作数据最底层的二进制数据了。
#将本地的/dev/sdx整块磁盘备份到/dev/sdy dd if=/dev/sdx of=/dev/sdy #将/dev/sdx全盘数据备份到指定路径的image文件 dd if=/dev/sdx of=/path/to/image #备份/dev/sdx全盘数据,并利用gzip工具进行压缩,保存到指定路径 dd if=/dev/sdx | gzip > /path/to/image.gz
磁盘数据还原:
#将备份文件恢复到指定盘 dd if=/path/to/image of=/dev/sdx #解压备份文件恢复到指定盘 gzip -dc /path/to/image.gz | dd of=/dev/sdx
解析:这里的所有操作都是控制一种数据的流向,本质上原理是一样的。
其它数据拷贝:
#拷贝内存资料到硬盘 dd if=/dev/mem of=/root/mem.bin bs=1024 #从光盘拷贝数据制作为iso镜像文件 dd if=/dev/cdrom of=/root/cd.iso #销毁磁盘数据 dd if=/dev/urandom of=/dev/sda1
说明:利用数据数将磁盘填充满,用于销毁磁盘中数据,使其无法再恢复
测试最最快数据的bs大小输出
[root@mzf ~]# dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file 1000000+0 records in 1000000+0 records out 1024000000 bytes (1.0 GB) copied, 26.9279 s, 38.0 MB/s [root@mzf ~]# dd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file 500000+0 records in 500000+0 records out 1024000000 bytes (1.0 GB) copied, 19.0141 s, 53.9 MB/s [root@mzf ~]# dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 17.6197 s, 58.1 MB/s
说明:这里说明,如果写入一个G数据,使用bs=4096是最好的
测试磁盘的读写速度
[root@mzf ~]# dd if=/root/1Gb.file bs=64k | dd of=/dev/null 2000000+0 records in 2000000+0 records out 1024000000 bytes (1.0 GB) copied, 12.2354 s, 83.7 MB/s 15625+0 records in 15625+0 records out 1024000000 bytes (1.0 GB) copied, 12.2365 s, 83.7 MB/s
读数据:12.2365 s
[root@mzf ~]# dd if=/dev/zero of=/root/1Gb.file bs=1024 count=1000000 1000000+0 records in 1000000+0 records out 1024000000 bytes (1.0 GB) copied, 12.0643 s, 84.9 MB/s
写数据:12.0642s
修复硬盘:
dd if=/dev/sda of=/dev/sda #此操作只适用于硬盘设备文件,如果为文件则数据完全消失
当硬盘较长时间(比如1,2年)放置不使用后,磁盘上会产生消磁点。当磁头读到这些区域时会遇到困难,并可能导致I/O错误。当这种情况影响到硬盘的第一个扇区时,可能导致硬盘报废。上边的命令有可能使这些数据起死回生。且这个过程是安全,高效的。
本文出自 “神剑特兰克斯” 博客,请务必保留此出处http://mengzhaofu.blog.51cto.com/10085198/1844489
原文地址:http://mengzhaofu.blog.51cto.com/10085198/1844489