当前位置:首页>Linux>每天学一个Linux命令系列(22):dd - 磁盘对拷、测速、造文件,全能工具

每天学一个Linux命令系列(22):dd - 磁盘对拷、测速、造文件,全能工具

  • 2026-09-13 13:12:52
每天学一个Linux命令系列(22):dd - 磁盘对拷、测速、造文件,全能工具
运
运维少年 · 科技观察

这个命令是干啥的

dd 的全称是 "data duplicator"。数据复制器。这名字听着很普通,但它能干的事情一点都不普通。

简单说,dd 就是在字节层面上复制数据。不像 cp 是按文件复制,dd 直接操作磁盘块,连文件系统都不用管。这意味着你可以:
- 把一个整块硬盘克隆到另一个硬盘
- 创建一个指定大小的空文件
- 测试磁盘读写速度
- 从损坏的磁盘里抢救数据

我第一次被 dd 震到是有次要快速创建一个 1GB 的交换文件。用 fallocate 当时不太熟,就用 dd 几秒钟搞定了。后来发现做磁盘对拷、做 U 盘启动盘都用得上。

dd 的语法风格在 Linux 命令里比较独特,参数用的是 选项=值 的格式:

dd if=输入文件 of=输出文件 bs=块大小 count=块数量 status=progress
  • ·if=:input file,数据来源
  • ·of=:output file,输出到哪
  • ·bs=:block size,每次读写多少字节
  • ·count=:读写多少个块

基本用法(3分钟上手)

创建指定大小的文件

# 创建一个 100MB 的空文件,内容全是 0
dd if=/dev/zero of=testfile bs=1M count=100
# 查看创建结果
ls -lh testfile
# 输出:-rw-r--r-- 1 root root 100M Mar 15 10:00 testfile

/dev/zero 是一个特殊的设备文件,读它会源源不断地输出 \0 字节(全是 0)。配合 bs 和 count 就能精确控制文件大小。

磁盘读写测速

# 测试磁盘写速度
dd if=/dev/zero of=/tmp/test bs=1M count=1000 conv=fdatasync

conv=fdatasync 确保数据真正写到磁盘上再出结果。不加这个参数,dd 报告的速度可能只是内存写入速度,比实际快很多。

# 测试磁盘读速度
dd if=/tmp/test of=/dev/null bs=1M count=1000

/dev/null 是黑洞设备,读出来的数据直接扔掉,纯粹测试读取性能。

制作 U 盘启动盘

# 把 ISO 镜像写入 U 盘(假设 U 盘是 /dev/sdb)
dd if=ubuntu-22.04.iso of=/dev/sdb bs=4M status=progress

一定要注意:of 指定的是磁盘设备(如 /dev/sdb),不是分区(如 /dev/sdb1)。写错了会把你系统盘干掉。我亲眼见过同事把 sdb 写成 sda,系统当场崩了。

显示进度

dd 默认是个闷葫芦,啥进度也不显示。大数据量的时候你会怀疑它是不是卡死了。

# status=progress 显示实时进度
dd if=/dev/sda of=/dev/sdb bs=4M status=progress

在较新的 Linux 上,status=progress 会显示当前速度、已传输数据量和剩余时间。

进阶骚操作

备份整个磁盘(磁盘对拷)

# 把 /dev/sda 完整克隆到 /dev/sdb(两台同型号同容量硬盘)
dd if=/dev/sda of=/dev/sdb bs=4M status=progress

这等于对拷整块盘,包括分区表、MBR、所有文件。插上 sdb 就能直接启动,跟 sda 一模一样。

但有个坑:sdb 的容量必须大于等于 sda。sdb 大一点没关系,小了就 GG。

创建交换文件

Linux 系统如果想增加交换空间,可以用 dd 创建交换文件:

# 创建 2GB 的交换文件
dd if=/dev/zero of=/swapfile bs=1M count=2048

# 设置正确权限
chmod 600 /swapfile

# 格式化成交换空间
mkswap /swapfile

# 启用交换文件
swapon /swapfile

查看效果:

# 查看交换空间状态
free -h
swapon --show

想让重启后自动生效,还要加一行到 /etc/fstab:

# 向 /etc/fstab 追加配置
echo '/swapfile none swap sw 0 0' >> /etc/fstab

磁盘性能基准测试

做运维的经常要评估新服务器的磁盘性能:

# 顺序写测试
dd if=/dev/zero of=/tmp/bench bs=1M count=2048 conv=fdatasync 2>&1

# 顺序读测试
dd if=/tmp/bench of=/dev/null bs=1M count=2048 2>&1
# 小文件块性能测试(4K 块大小,模拟小文件场景)
dd if=/dev/zero of=/tmp/bench4k bs=4K count=256000 conv=fdatasync 2>&1

块大小不同,测出来的速度差很多。大块(1M)测的是顺序吞吐,小块(4K)测的是 IOPS 能力。

用 dd 填充随机数据

# 用 /dev/urandom 创建随机内容的文件
dd if=/dev/urandom of=randomfile bs=1M count=10

这常用于测试、加密场景,或者把数据填成随机值再删除(安全擦除的粗糙版)。

# 安全擦除分区(写满随机数据,恢复难度极高)
dd if=/dev/urandom of=/dev/sdb1 bs=4M status=progress

dd 配合 gzip 做压缩备份

硬盘对拷时会复制空间和数据。可以用管道压缩节省空间:

# 把磁盘压缩成镜像文件
dd if=/dev/sda bs=4M | gzip > disk_backup.img.gz

# 恢复
gunzip -c disk_backup.img.gz | dd of=/dev/sda bs=4M

我有个 16GB 的 U 盘,实际数据只有 3GB 左右,压缩后镜像文件才 1.2GB。

dd 和数据恢复

# 跳过坏块(conv=noerror 遇到错误继续,sync 用 0 填充)
dd if=/dev/sda of=/dev/sdb bs=4K conv=noerror,sync status=progress

不加 conv=noerror,dd 读到坏块就停了,数据救不回来。

避坑指南

1. 永远确认 of= 的目标

dd 不问你"确认吗"。你说 of=/dev/sda,它直接给你抹盘。

# 写之前用 lsblk 确认设备名
lsblk

我建议你把这条命令记在脑子里,每次用 dd 写磁盘之前先跑一遍。

2. dd vs cp 对大文件的区别

场景ddcp
复制普通文件都可以,cp 更自然推荐
克隆整块磁盘dd 是唯一选择不行
创建特定大小的文件dd if=/dev/zero bs=1M count=100fallocate 更快
跨设备复制大文件两者差不多更直观
跳过坏块复制dd conv=noerror不行

对于普通文件的复制,cp 更安全也更直观。dd 的优势在操作设备和块级别的场景。

3. bs 大小影响性能

# bs 太小,大量 I/O 操作,慢
dd if=/dev/sda of=/dev/sdb bs=512

# bs 合适,平衡性能和内存
dd if=/dev/sda of=/dev/sdb bs=4M

4M 是大多数场景下的好选择。bs 设太大(比如 1G)也不会更快,反而占用内存。

4. 为什么 dd 卡住了那么久也不动

dd 默认静默执行,没有进度提示。大于 1GB 的操作建议都加上 status=progress。

想查看 dd 进度但不支持 status 参数的旧系统:

# 在另一个终端向 dd 进程发 USR1 信号,输出当前进度
kill -USR1 $(pgrep ^dd)

或者在执行前按 Ctrl+T(某些终端支持)。

5. 不要用 dd 创建有文件系统的文件

# 这是我用 dd 创建的空文件
dd if=/dev/zero of=document.txt bs=1K count=1

# 然后发现编辑器打开全是乱码
cat document.txt

因为 /dev/zero 输出的是空字节(\0),不是 ASCII 的空格。想创建空文本文件,用 touch 或者 echo "" > file。

实战场景(重点!结合真实运维场景)

场景一:云服务器创建交换文件

云服务器内存不够用,临时加交换空间:

# 检查当前内存和交换
free -h

# 当前内存是 2GB,想加 2GB 交换
dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress

# 设置权限(安全要求)
chmod 600 /swapfile

# 格式化
mkswap /swapfile

# 启用
swapon /swapfile

# 验证
free -h

我测试过,腾讯云 2C4G 的轻量服务器跑 Node 应用,内存吃紧的时候加上 2GB 交换,虽然慢了点,但至少不会 OOM 被杀。

场景二:给旧硬盘做安全销毁

离职交接或者淘汰服务器之前:

# 把整个磁盘写三遍随机数据
dd if=/dev/urandom of=/dev/sdb bs=4M status=progress
dd if=/dev/urandom of=/dev/sdb bs=4M status=progress
dd if=/dev/urandom of=/dev/sdb bs=4M status=progress

三遍随机覆盖之后,用专业恢复工具也基本读不出原始数据了。当然,这做法比较费时间,250GB 机械硬盘写一遍大概要几个小时。

场景三:制作树莓派系统卡

# 先把镜像解压
unzip raspbian-lite.zip

# 查看 SD 卡设备名
lsblk

# 写入(假设 SD 卡是 /dev/sdc)
sudo dd if=raspbian-lite.img of=/dev/sdc bs=4M status=progress

# 同步缓存
sync

写完之后 sync 一下确保数据都落盘了,拔卡不会丢数据。

场景四:替换服务器硬盘

服务器一块硬盘有坏道,急买一块新的,要对拷系统:

# 新硬盘插上后 lsblk 确认设备名
lsblk

# 旧盘 /dev/sda,新盘 /dev/sdb,大小相同
# 用 noerror,sync 跳过坏块
dd if=/dev/sda of=/dev/sdb bs=4M status=progress conv=noerror,sync
# 完成后检查新盘分区
fdisk -l /dev/sdb

# 启动后能挂在同一个设备用

注意:如果两块硬盘型号不同、容量不同,用 dd 对拷可能出问题。这时候用 dd + 分区工具 + rsync 组合更好。

今日作业(一道小题目)

题目:你接手一台服务器,内存 4GB 但没有配置交换空间,而且经常 OOM(内存耗尽)被杀进程。

要求:
1. 用 dd 创建一个 4GB 的交换文件(位置:/swapfile)
2. 设置正确的文件权限
3. 格式化为交换空间
4. 启用它,并确保重启后自动生效
5. 验证是否生效

写全你的命令序列。不限速。

E N D

运维少年 · 科技观察

最新文章

随机文章