dd 命令是一个功能强大的磁盘复制和转换工具,可以按块复制文件并进行数据转换。dd代表"数据复制器"(Data Duplicator),也被戏称为"磁盘破坏者"(Disk Destroyer),因为不当使用可能导致数据丢失。
dd命令非常强大且危险! 错误的参数可能导致整个磁盘数据被覆盖。在使用dd命令前,务必仔细检查输入和输出参数,并确保已备份重要数据。
dd [选项]
dd if=输入文件 of=输出文件 [bs=块大小] [count=块数] [skip=跳过块数] [seek=跳过块数] [conv=转换]
| 选项 | 说明 |
|---|---|
| if=文件 | 输入文件(input file),默认为标准输入 |
| of=文件 | 输出文件(output file),默认为标准输出 |
| bs=字节 | 同时设置输入和输出的块大小(block size) |
| ibs=字节 | 输入块大小(input block size) |
| obs=字节 | 输出块大小(output block size) |
| count=块数 | 只复制指定数量的块 |
| skip=块数 | 从输入文件开头跳过指定数量的块 |
| seek=块数 | 从输出文件开头跳过指定数量的块 |
| conv=转换 | 转换参数,多个用逗号分隔 |
| status=级别 | 显示进度信息:none, noxfer, progress |
| 转换参数 | 说明 |
|---|---|
| ascii | 将EBCDIC转换为ASCII |
| ebcdic | 将ASCII转换为EBCDIC |
| ibm | 将ASCII转换为alternate EBCDIC |
| block | 将换行符替换为指定长度的空格 |
| unblock | 将指定长度的空格替换为换行符 |
| lcase | 将大写字母转换为小写 |
| ucase | 将小写字母转换为大写 |
| sparse | 创建稀疏文件(节省空间) |
| swab | 交换每对字节 |
| sync | 将每个输入块填充到ibs大小 |
| excl | 如果输出文件已存在则失败 |
| nocreat | 不创建输出文件 |
| notrunc | 不截断输出文件 |
| noerror | 读取错误时继续处理 |
# 复制文件
dd if=source.txt of=destination.txt
# 复制文件并显示进度
dd if=source.txt of=destination.txt status=progress
# 指定块大小复制(4K块)
dd if=source.txt of=destination.txt bs=4k
# 1. 查看USB设备路径
sudo fdisk -l
# 通常USB设备是/dev/sdb或/dev/sdc,确认你的USB设备路径
# 2. 卸载USB设备(如果已挂载)
sudo umount /dev/sdb*
# 3. 写入ISO镜像到USB
sudo dd if=ubuntu-22.04.iso of=/dev/sdb bs=4M status=progress
# 4. 同步数据确保写入完成
sync
# 磁盘到磁盘克隆(源盘和目标盘大小应相同或目标更大)
sudo dd if=/dev/sda of=/dev/sdb bs=64K status=progress
# 磁盘到镜像文件备份
sudo dd if=/dev/sda of=/backup/disk.img bs=64K status=progress
# 压缩备份(节省空间)
sudo dd if=/dev/sda bs=64K | gzip > /backup/disk.img.gz
# 从镜像恢复磁盘
sudo dd if=/backup/disk.img of=/dev/sda bs=64K status=progress
# 解压缩恢复
gunzip -c /backup/disk.img.gz | sudo dd of=/dev/sda bs=64K
# 备份分区到文件
sudo dd if=/dev/sda1 of=/backup/sda1.img bs=4M status=progress
# 恢复分区
sudo dd if=/backup/sda1.img of=/dev/sda1 bs=4M status=progress
# 备份MBR(前512字节)
sudo dd if=/dev/sda of=/backup/mbr.bak bs=512 count=1
# 恢复MBR
sudo dd if=/backup/mbr.bak of=/dev/sda bs=512 count=1
# 备份分区表(MBR的前446字节是引导代码,接着64字节是分区表)
sudo dd if=/dev/sda of=/backup/partition-table.bak bs=1 count=64 skip=446
# 用零填充磁盘(快速擦除)
sudo dd if=/dev/zero of=/dev/sdb bs=1M status=progress
# 用随机数据填充磁盘(安全擦除)
sudo dd if=/dev/urandom of=/dev/sdb bs=1M status=progress
# 多次覆盖擦除(更安全)
for i in {1..3}; do
echo "第 $i 次覆盖..."
sudo dd if=/dev/urandom of=/dev/sdb bs=1M status=progress
done
# 擦除文件内容(不删除文件)
dd if=/dev/urandom of=secret-file.txt bs=1M count=10
# 然后删除文件
rm secret-file.txt
# 测试写入速度(1GB测试文件)
dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct
# 测试读取速度
dd if=testfile of=/dev/null bs=1G count=1 iflag=direct
# 测试同时读写
dd if=testfile of=testfile2 bs=1G count=1
# 使用不同块大小测试
for bs in 1k 4k 16k 64k 256k 1M 4M; do
echo "测试块大小: $bs"
dd if=/dev/zero of=testfile bs=$bs count=1000 2>&1 | grep -E "(copied|MB/s)"
rm testfile
done
# 转换文件大小写
dd if=input.txt of=uppercase.txt conv=ucase
dd if=input.txt of=lowercase.txt conv=lcase
# 创建稀疏文件(节省空间)
dd if=/dev/zero of=sparse-file.img bs=1 count=0 seek=1G
# 交换字节顺序
dd if=input.bin of=swapped.bin conv=swab
# 提取文件的部分内容
dd if=largefile.bin of=part.bin bs=1M skip=100 count=50 # 跳过前100MB,提取50MB
# 创建特定大小的文件
dd if=/dev/zero of=1gbfile.bin bs=1M count=1024 # 创建1GB文件
dd if=/dev/urandom of=random-100M.bin bs=1M count=100 # 创建100MB随机文件
#!/bin/bash
# 备份脚本示例
BACKUP_DIR="/backup"
DISK="/dev/sda"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$BACKUP_DIR/backup_$DATE.log"
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
backup_mbr() {
log_message "备份MBR..."
sudo dd if=$DISK of="$BACKUP_DIR/mbr_$DATE.bak" bs=512 count=1 2>> "$LOG_FILE"
if [ $? -eq 0 ]; then
log_message "MBR备份成功"
else
log_message "MBR备份失败"
return 1
fi
}
backup_partition() {
local partition=$1
log_message "备份分区 $partition..."
# 检查分区是否存在
if [ ! -b "$partition" ]; then
log_message "分区 $partition 不存在"
return 1
fi
local part_name=$(basename "$partition")
local backup_file="$BACKUP_DIR/${part_name}_$DATE.img"
# 开始备份
sudo dd if="$partition" of="$backup_file" bs=4M status=progress 2>&1 | tee -a "$LOG_FILE"
# 验证备份文件
if [ -f "$backup_file" ] && [ $(stat -c%s "$backup_file") -gt 0 ]; then
log_message "分区 $partition 备份成功: $backup_file"
# 压缩备份文件
log_message "压缩备份文件..."
gzip "$backup_file"
# 计算压缩率
original_size=$(stat -c%s "$backup_file.gz")
log_message "备份完成,文件大小: $(du -h "$backup_file.gz" | cut -f1)"
else
log_message "分区 $partition 备份失败"
return 1
fi
}
# 主程序
main() {
log_message "开始系统备份"
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 备份MBR
backup_mbr
# 备份关键分区
backup_partition "/dev/sda1" # 假设sda1是boot分区
backup_partition "/dev/sda2" # 假设sda2是root分区
log_message "系统备份完成"
echo "备份日志: $LOG_FILE"
}
main "$@"
dd命令自带的进度显示:
dd if=/dev/sda of=/dev/sdb bs=4M status=progress
通过管道使用pv显示进度:
sudo dd if=/dev/sda bs=4M | pv | sudo dd of=/dev/sdb bs=4M
在另一个终端查看进度:
# 运行dd命令
sudo dd if=/dev/sda of=/dev/sdb bs=4M &
# 查看dd进程ID
ps aux | grep dd
# 发送USR1信号查看进度
kill -USR1 进程ID
监控输出文件大小:
# 在一个终端运行dd
sudo dd if=/dev/sda of=disk.img bs=4M
# 在另一个终端监控文件大小
watch -n 1 'ls -lh disk.img'
问题描述:错误的设备路径可能导致重要数据被覆盖。
预防措施:
lsblk或fdisk -l确认设备路径oflag=sync确保数据完全写入# 正确做法:先检查设备
lsblk
sudo fdisk -l
# 确认无误后再执行
sudo dd if=ubuntu.iso of=/dev/sdb bs=4M status=progress
问题描述:dd命令默认不显示进度,长时间操作时无法了解进度。
解决方案:
status=progress参数# 方法1:使用status参数
dd if=/dev/sda of=/dev/sdb bs=4M status=progress
# 方法2:使用pv
sudo dd if=/dev/sda bs=4M | pv -s $(sudo blockdev --getsize64 /dev/sda) | sudo dd of=/dev/sdb bs=4M
# 方法3:发送信号(在另一个终端)
kill -USR1 $(pidof dd)
问题描述:创建镜像时目标磁盘空间不足。
解决方案:
df -hdd if=/dev/sda | gzip > backup.img.gzdd if=/dev/sda of=backup.img conv=sparsepartclone等工具# 压缩备份节省空间
sudo dd if=/dev/sda bs=4M | gzip -c > /backup/disk.img.gz
# 稀疏文件(仅限某些文件系统)
sudo dd if=/dev/sda of=/backup/disk.img conv=sparse
# 只备份使用的块(需要文件系统支持)
sudo partclone.ext4 -c -s /dev/sda1 -o /backup/sda1.partclone.img
sync命令确保数据写入conv=noerror忽略读取错误继续