dd 命令操作磁盘和复制 MBR
复制磁盘
shell
# if of 可是是磁盘,也可以是磁盘下的分区 需要统一、且注意大小
sudo dd if=/dev/sda of=/dev/sdb bs=4096 conv=sync,noerror status=progress
# 备份磁盘镜像、及恢复磁盘镜像
dd if=/dev/vdb1 of=/opt/backupsFile.img status=progress
dd if=/opt/backupsFile.img of=/dev/vdb1 status=progress
# 备份磁盘镜像并带压缩
dd if=/dev/vdb1 status=progress | gzip > /opt/backups.gz
gzip -dc /opt/backups.gz | dd of=/dev/vdb2 status=progress
# ---------------------------------------
dd if=/dev/sda | bzip2 > disk.img.bz2
bzip2 -dc /root/sda.img.gz | dd of=/dev/sdc
解释一下命令的参数:
- if:指定源系统的设备文件,这里是
/dev/sda
; - of:指定目标硬盘的设备文件,这里是
/dev/sdb
; - bs:指定每次复制的数据块大小,这里是4096字节。支持 KB,M, 如:64KB、1M;
- conv=sync,noerror:conv参数指定转换选项,sync选项表示在每次写入数据之后同步设备;
- count=1024 count 是读入次数,以 bs 的速率读取 count 次;
- skip 支持 Skip 跳过 N字节;
- status progress 输出进度信息;
如果使用 dd 没有status=progress
参数,且执行时间过程,可以使用另一条命令来让他输出中间过程:
shell
watch -n 5 killall -USR1 dd
磁盘存储数据的逻辑架构
制作U盘启动盘
shell
dd if=/***.iso of=/dev/xxx
# if后接镜像文件路径
# of后接写入U盘的路径
# 可以利用watch -n 5每5s发送信号触发dd命令打印进度
将上传的镜像文件上传在linux目录后,执行如下命令制作U盘启动盘
dd if=/home/ubuntu-23.10.1-desktop-amd64.iso of=/dev/sdb status=progress
操作 MBR
shell
sudo fdisk -l
#使用dd导出MBR到mbr.bin文件
sudo dd if=/dev/sda of=mbr.bin bs=512 count=1
#使用dd导出MBR并且使用xxd显示
sudo dd if=/dev/sda bs=512 count=1 | xxd
#使用dd导出MBR并且使用xxd显示分区信息
sudo dd if=/dev/sda bs=512 count=1 | xxd -s 446
sudo dd if=/dev/mmcblk1 of=mbr.bin bs=512 count=1
sudo dd if=/dev/mmcblk1 bs=512 count=1 | xxd
sudo dd if=/dev/mmcblk1 bs=512 count=1 | xxd -s 446
输出信息如下:
- 取得sda中的MBR中的分区信息,得出2个分区,第一个分区为活动分区(可以引导系统)
- #第一个分区信息存储在mbr的0x01be偏移
- #最后一个分区结束在mbr的0x01fe偏移
- #至于16个字节的具体含义,就参见下文
shell
sudo dd if=/dev/mmcblk1 bs=512 count=1 |xxd -s 446 -c 16 -g 1
备份和恢复磁盘
主引导记录(Master Boot Record,MBR),位于一个硬盘的0柱面、0盘面、1扇区,共512字节。具体划分依次为:引导代码区440字节、磁盘签名4字节、空白(Ox0000)2字节、MBR分区表(Disk Partition Table,DPT)64字节、结束标志(Ox55AA)2字节。其中的MBR分区表(DPT)区别于另一种“全局唯一标识分区表(GUID Partition Table,GPT)”。本文今天仅讨论MBR及DPT。
因为DPT是在MBR里的,而DPT存在MBR里的第446字节开始往后数64字节结束,66是因为我算上了结束标志;
- bs代表每次读1字节
- skip代表跳到第446字节开始读写
- count代表复制66次
备份与恢复MBR、分区表DPT: 以下命令均以sda号硬盘举例。
备份/恢复硬盘MBR(全部512字节):
shell
#备份
dd if=/dev/sda of=./mbr.bak bs=512 count=1
#恢复
dd if=./mbr.bak of=/dev/sda bs=512 count=1
# 仅备份/恢复硬盘的分区表DPT(后66字节):
#备份
dd if=/dev/sda of=./dpt.bak bs=1 skip=446 count=66
#恢复
dd if=./dpt.bak of=/dev/sda bs=1 seek=446 count=66
# 仅恢复硬盘MBR的引导代码部分(前446字节):
#恢复
dd if=./mbr.bak of=/dev/sda bs=446 count=1
磁盘测速
dd还有一个重要的用途就是测试磁盘的读写速率了,它可以测试大文件读写和碎文件读写的时长和速率;我们可以通过这个方式测试,并将一些读写快的磁盘留给重要的应用或者swap交换空间。
测试磁盘的写速度:
shell
timeout 120 dd if=/dev/zero of=/tmp/speed.dat bs=1M count=1000 oflag=direct
2097152000字节(2.1 GB,2.0 GiB)已复制,15 s,140 MB/s
记录了1000+0 的读入
记录了1000+0 的写出
2097152000字节(2.1 GB,2.0 GiB)已复制,15.0006 s,140 MB/s
(of文件只用于写,所以这个命令相当于测试磁盘的写能力;可以看出我的磁盘写的速度平均在140MB每秒)
测试磁盘的读速度:
shell
timeout 120 dd if=/tmp/speed.dat of=/dev/null bs=1M count=1000 status=progress
记录了1000+0 的读入
记录了1000+0 的写出
2097152000字节(2.1 GB,2.0 GiB)已复制,0.308627 s,6.8 GB/s
(可以看出我的磁盘读速度平均在6.8GB每秒)
说明:
- 想观察具体读写进度可在后面加上:status=progress;
- timeout 120代表命令执行120秒还未执行完则自动停止超时;
- 关于bs读写的字节数和count复制的次数可按照自己需求调整,从而测试读写速度;比如设置 bs=1K count=20000 代表测试碎文件的读写速度;
- 关于oflag选项请参数上面的参数详情;