分区工具实战

掌握分区工具是 Linux 系统管理的必备技能。本章系统讲解 fdisk、gdisk、parted、
sgdisk、sfdisk 五大分区工具的使用方法,涵盖日常分区操作、自动化部署、分区调整
和分区恢复等场景。


分区工具概览

工具选择指南

工具分区表交互模式脚本模式典型用途
fdiskMBR + GPT有限手动 MBR 操作、快速查看
gdiskGPT 专用GPT 专家级操作
cgdiskGPT 专用ncursesGPT 的可视化交互
partedMBR + GPT脚本化分区、大容量磁盘
sgdiskGPT 专用批量 GPT 操作、自动化
sfdiskMBR + GPT有限管道脚本、分区表备份

选择原则:

  • 手动交互:gdisk(GPT)或 fdisk(MBR)
  • 脚本自动化:sgdisk(GPT)或 sfdisk(MBR/GPT)
  • 跨平台/大磁盘:parted
  • 批量操作:sgdisksfdisk

fdisk

MBR 分区操作

fdisk 是最传统的 Linux 分区工具,支持 MBR 和 GPT(自 util-linux 2.26 起)。

创建 MBR 分区

sudo fdisk /dev/sdb

交互命令:

命令说明
p打印分区表
n新建分区
d删除分区
t更改分区类型
a切换引导标志
w写入并退出
q不保存退出

示例:创建一个 Linux LVM 分区

Command: n
Partition type: p (primary)
Partition number: 1
First sector: (回车接受默认)
Last sector: +50G
Command: t
Selected partition 1
Hex code: 8e
Command: w

GPT 分区操作

fdisk 对 GPT 的支持有限,只能执行基本操作。对于复杂 GPT 操作,推荐使用 gdisk
或 sgdisk。

sudo fdisk /dev/sdb
# 在 GPT 磁盘上 fdisk 会自动检测并进入 GPT 模式
Command: g (创建 GPT 分区表)
Command: n (新建分区)

常用命令速查

# 列出所有磁盘分区
sudo fdisk -l
 
# 列出指定磁盘
sudo fdisk -l /dev/sda
 
# 只显示 MBR 分区表
sudo fdisk -l /dev/sdb | grep "^/dev"
 
# 非交互式创建分区(危险)
echo -e "n\np\n1\n\n\nw" | sudo fdisk /dev/sdb

gdisk / cgdisk

GPT 专用工具

gdisk 是 GPT 分区的专业工具,功能远超 fdisk 对 GPT 的支持。

sudo gdisk /dev/sda

gdisk 的专家模式(输入 ? 查看完整帮助):

命令说明
b备份 GPT 数据到文件
c更改分区 GUID
d删除分区
i显示分区详细信息
n新建分区
o创建新的 GPT 空白分区表
p打印分区表
r进入恢复/专家模式
s排序分区表项
t更改分区类型代码
v验证磁盘
w写入并退出
x进入专家模式

GPT type code 操作

# 查看所有 GPT type code
sudo gdisk /dev/sda
# 输入 t,然后输入 L 列出所有代码
 
# 常用代码
# 8300  Linux Filesystem
# 8200  Linux Swap
# 8E00  Linux LVM
# EF00  EFI System Partition
# EF02  BIOS Boot Partition

交互式与脚本模式

gdisk 支持通过脚本执行批量操作:

# 脚本模式:使用 gdisk -l 配合 sgdisk
# 或使用 heredoc
sudo gdisk /dev/sda <<EOF
n
1
2048
+1G
EF00
n
2
 
+50G
8300
w
y
EOF

cgdisk 是 gdisk 的 ncurses 可视化版本,提供菜单式操作,适合不熟悉命令行
交互的用户。

sudo cgdisk /dev/sda

parted

交互模式

parted 是 GNU 项目开发的分区工具,支持 MBR 和 GPT,特别适合大容量磁盘
)。

sudo parted /dev/sda

交互模式下的常用命令:

命令说明
print显示分区表
mkpart创建分区
rm删除分区
resizepart调整分区大小
move移动分区
set设置分区标志
align-check检查对齐
rescue恢复丢失的分区
mklabel创建新的分区表
quit退出

示例:创建 GPT 分区表和分区

(parted) mklabel gpt
(parted) mkpart ESP fat32 1MiB 513MiB
(parted) set 1 esp on
(parted) mkpart root ext4 513MiB 50GiB
(parted) mkpart home ext4 50GiB 100%
(parted) print

示例:设置分区标志

(parted) set 1 boot on
(parted) set 1 esp on
(parted) set 2 lvm on

脚本模式(自动化部署)

parted 的脚本模式非常适合自动化部署和 Kickstart 安装:

#!/bin/bash
# parted 脚本示例:自动化分区
parted -s /dev/sdb \
    mklabel gpt \
    mkpart primary fat32 1MiB 513MiB \
    set 1 esp on \
    mkpart primary ext4 513MiB 50GiB \
    mkpart primary ext4 50GiB 100%
 
# -s 标志:脚本模式,不提示确认

Kickstart 中的 parted 示例

part /boot/efi --fstype=vfat --size=512 --ondisk=sda
part /boot     --fstype=ext4 --size=1024 --ondisk=sda
part /         --fstype=ext4 --size=50000 --ondisk=sda
part /home     --fstype=ext4 --size=100000 --ondisk=sda
part swap      --size=8192 --ondisk=sda

常用命令

# 查看磁盘分区表
sudo parted /dev/sda print
 
# 查看所有磁盘
sudo parted -l
 
# 以脚本模式创建分区
sudo parted -s /dev/sdb mklabel gpt mkpart primary 1MiB 100%
 
# 检查分区对齐
sudo parted -s /dev/sda align-check optimal 1
 
# 恢复分区(交互)
sudo parted /dev/sda
(parted) rescue 1MiB 100GiB

sgdisk

批量操作

sgdisk(SGDisk)是 GPT 分区的命令行脚本工具,是 gdisk 的脚本版本。

# 创建 GPT 分区表
sudo sgdisk --zap-all /dev/sdb
 
# 创建分区
sudo sgdisk --new=1:0:+512M --typecode=1:EF00 /dev/sdb
sudo sgdisk --new=2:0:+50G --typecode=2:8300 /dev/sdb
sudo sgdisk --new=3:0:0 --typecode=3:8300 /dev/sdb
 
# 查看分区表
sudo sgdisk --print /dev/sdb

常用选项

选项说明
--print / -p打印分区表
--new / -n创建分区(partnum:start:end
--delete / -d删除分区
--typecode / -t设置类型代码
--change-name / -c设置分区名称
--zap-all / -Z清除所有分区数据
--clear / -o清除分区表(保留数据)
--backup / -b备份分区表到文件
--load-backup / -l从文件恢复分区表
--verify / -v验证 GPT 完整性
--align-check / -A检查分区对齐

分区表复制

sgdisk 可以在磁盘之间复制分区表:

# 将 sda 的分区表复制到 sdb
sudo sgdisk --replicate=/dev/sdb /dev/sda
 
# 仅复制分区布局,生成新的 GUID
sudo sgdisk --replicate=/dev/sdb /dev/sda
sudo sgdisk --randomize-guids /dev/sdb

分区对齐检查

# 检查所有分区是否 1MiB 对齐
sudo sgdisk --align-check=optimal /dev/sda
 
# 输出示例
# Partition 1 is not optimally aligned.
# Partition 2 is optimally aligned.

批量检查多个磁盘

for disk in /dev/sd[a-z]; do
    if sudo sgdisk -p "$disk" >/dev/null 2>&1; then
        echo "=== $disk ==="
        sudo sgdisk --align-check=optimal "$disk"
    fi
done

sfdisk

自动化分区(管道脚本)

sfdisk 是 util-linux 中的分区工具,擅长通过管道进行自动化分区操作。

查看分区表

sudo sfdisk -l /dev/sda
 
# 输出格式类似 fdisk -l,但更易于脚本解析

使用脚本创建分区

# 方式一:使用 heredoc
sudo sfdisk /dev/sdb <<EOF
label: gpt
unit: sectors
 
/dev/sdb1 : start=2048, size=1048576, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="ESP"
/dev/sdb2 : start=1050624, size=104857600, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="root"
/dev/sdb3 : start=105908224, size=0, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="home"
EOF
 
# 方式二:使用 --append 追加分区
echo "start=2048, size=1048576, type=EF00" | sudo sfdisk --append /dev/sdb

sfdisk 脚本格式说明

label: gpt              # 分区表类型
unit: sectors           # 扇区单位(支持 sectors, bytes, KiB, MiB 等)
grain: 1048576          # 最小对齐粒度(可选)

/dev/sdb1 : start=2048, size=1048576, type=EF00, name="ESP"
#        字段间用逗号+空格分隔
#        start: 起始扇区
#        size: 扇区数(0 表示使用所有剩余空间)
#        type: GPT type GUID 或短代码
#        name: 分区名称(GPT 专有)

备份与恢复分区表

sfdisk 是备份和恢复分区表的首选工具:

# 备份分区表(纯文本格式)
sudo sfdisk -d /dev/sda > /backup/sda-partitions.dump
 
# 恢复分区表
sudo sfdisk /dev/sda < /backup/sda-partitions.dump
 
# 备份为二进制格式
sudo sfdisk --backup /dev/sda
# 输出文件:/dev/sda.dump(包含 MBR + 备份扇区)
 
# 恢复二进制备份
sudo sfdisk --restore /dev/sda

脚本化备份所有磁盘

#!/bin/bash
BACKUP_DIR="/backup/partition-tables"
mkdir -p "$BACKUP_DIR"
 
for disk in /dev/sd[a-z]; do
    if [ -b "$disk" ]; then
        name=$(basename "$disk")
        sudo sfdisk -d "$disk" > "$BACKUP_DIR/${name}.dump" 2>/dev/null
        echo "Backed up $disk to $BACKUP_DIR/${name}.dump"
    fi
done

分区调整

扩容分区(growpart / parted resizepart)

扩容分区有两种主流方式:growpart(Cloud-Init 项目)和 parted resizepart

使用 growpart

# 安装 growpart
sudo apt install cloud-guest-utils  # Debian/Ubuntu
sudo yum install cloud-utils-growpart  # CentOS/RHEL
 
# 扩展 /dev/sdb 的第 2 个分区到磁盘末尾
sudo growpart /dev/sdb 2
 
# 扩展到指定大小
sudo growpart /dev/sdb 2 --size-gb 100

使用 parted resizepart

# 交互模式
sudo parted /dev/sdb
(parted) resizepart 2 100GiB   # 扩展到 100GiB
 
# 脚本模式
sudo parted -s /dev/sdb resizepart 2 100GiB

扩容后扩展文件系统

# ext4
sudo resize2fs /dev/sdb2
 
# xfs
sudo xfs_growfs /dev/sdb2
 
# 一步完成(lvm2 内置支持)
sudo lvextend -r -L +50G /dev/vg0/lv_root

LVM 逻辑卷扩容

# 扩展物理卷
sudo pvresize /dev/sdb2
 
# 扩展逻辑卷
sudo lvextend -L +50G /dev/vg0/lv_root
 
# 扩展文件系统(-r 自动 resize)
sudo lvextend -r -L +50G /dev/vg0/lv_root

缩容分区(风险与流程)

警告:缩容操作有数据丢失风险,务必提前备份。缩容只能在文件系统缩小之后进行,
且必须在卸载状态下操作(ext4 支持在线缩小,xfs 不支持缩小)。

ext4 缩容流程

# 1. 卸载分区
sudo umount /dev/sdb2
 
# 2. 检查文件系统
sudo e2fsck -f /dev/sdb2
 
# 3. 缩小文件系统到 30GiB
sudo resize2fs /dev/sdb2 30GiB
 
# 4. 缩小分区(parted)
sudo parted -s /dev/sdb resizepart 2 30GiB
 
# 5. 重新挂载验证
sudo mount /dev/sdb2 /mnt
df -h /mnt

xfs 缩容:xfs 不支持缩小。若需要缩小 xfs 分区,流程为:

# 1. 备份数据
sudo xfsdump -L "" -M "" -f /backup/xfs-backup.tar /mnt
 
# 2. 卸载
sudo umount /mnt
 
# 3. 缩小分区
sudo parted -s /dev/sdb resizepart 2 30GiB
 
# 4. 重新创建 xfs 文件系统
sudo mkfs.xfs /dev/sdb2
 
# 5. 挂载并恢复数据
sudo mount /dev/sdb2 /mnt
sudo xfsrestore -f /backup/xfs-backup.tar /mnt

分区恢复

GPT 备份头恢复

GPT 磁盘在末尾保留了分区表的完整备份。当主 GPT 头损坏时可恢复。

使用 sgdisk 恢复

# 检查 GPT 完整性
sudo sgdisk --verify /dev/sda
 
# 从备份恢复
sudo sgdisk --load-backup=/dev/sda
 
# 或使用 gdisk
sudo gdisk /dev/sda
# x (专家模式) → e (从备份重建) → w (写入)

手动恢复

# GPT 备份头位置
# 最后一个扇区:LBA -1(头部备份)
# 倒数第 33 至第 2 扇区:分区项数组备份
 
# 计算磁盘扇区数
SECTORS=$(sudo blockdev --getsz /dev/sda)
 
# 备份头位置
HEAD_BACKUP=$((SECTORS - 1))
TABLE_BACKUP_START=$((SECTORS - 33))
TABLE_BACKUP_END=$((SECTORS - 2))
 
echo "磁盘总扇区数: $SECTORS"
echo "备份头 LBA: $HEAD_BACKUP"
echo "备份分区项 LBA: $TABLE_BACKUP_START - $TABLE_BACKUP_END"

MBR 恢复

# 备份 MBR
sudo dd if=/dev/sda of=/backup/mbr.bin bs=512 count=1
 
# 恢复 MBR 引导代码(仅前 446 字节,保留分区表)
sudo dd if=/backup/mbr.bin of=/dev/sda bs=446 count=1 conv=notrunc
 
# 恢复完整 MBR(包含分区表,危险操作)
sudo dd if=/backup/mbr.bin of=/dev/sda bs=512 count=1
 
# 从另一个相同磁盘恢复
sudo dd if=/dev/sdb of=/dev/sda bs=512 count=1

testdisk 分区恢复

testdisk 是一个强大的分区恢复工具,可扫描磁盘寻找丢失的分区。

# 安装 testdisk
sudo apt install testdisk  # Debian/Ubuntu
sudo yum install testdisk  # CentOS/RHEL
 
# 运行 testdisk
sudo testdisk /dev/sda

testdisk 的交互流程:

  1. 选择磁盘 → Select
  2. 选择分区表类型(Intel/EFI GPT)→ Partition table type
  3. 选择 Analyse → Advanced → Boot → Search
  4. testdisk 会扫描磁盘寻找丢失的分区
  5. 找到后可选择 Write(写入分区表)或 Quick Search 继续扫描

testdisk 功能

功能说明
Analyse扫描丢失的分区
Advanced查看/恢复文件
Geometry修改磁盘几何参数
Options调整高级选项
Type更改磁盘类型
Copy复制文件从磁盘

使用 PhotoRec 恢复文件(testdisk 的姊妹工具):

# PhotoRec 恢复已删除的文件(不依赖分区表)
sudo photorec /dev/sdb
 
# 选择分区 → 选择文件系统类型 → 选择保存目录

工具对比总结

场景推荐工具命令示例
手动创建 GPT 分区gdisksudo gdisk /dev/sda
手动创建 MBR 分区fdisksudo fdisk /dev/sdb
脚本化创建分区(GPT)sgdisksudo sgdisk -n 1:0:+512M -t 1:EF00 /dev/sdb
脚本化创建分区(通用)partedsudo parted -s /dev/sdb mklabel gpt mkpart ...
扩容分区growpartsudo growpart /dev/sdb 2
备份分区表sfdisksudo sfdisk -d /dev/sda > backup.dump
恢复 GPT 备份sgdisksudo sgdisk --load-backup=/dev/sda
恢复丢失分区testdisksudo testdisk /dev/sda
复制分区表sgdisksudo sgdisk --replicate=/dev/sdb /dev/sda
检查对齐sgdisksudo sgdisk -A 1:optimal /dev/sda

实战案例

案例一:新磁盘全盘分区(GPT + LVM)

# 1. 创建 GPT 分区表
sudo sgdisk --zap-all /dev/sdb
 
# 2. 创建 BIOS Boot Partition(1MiB)
sudo sgdisk --new=1:0:+1M --typecode=1:EF02 /dev/sdb
 
# 3. 创建 LVM 物理分区(剩余全部空间)
sudo sgdisk --new=2:0:0 --typecode=2:8E00 /dev/sdb
 
# 4. 创建 LVM 物理卷
sudo pvcreate /dev/sdb2
 
# 5. 创建卷组
sudo vgcreate vg_data /dev/sdb2
 
# 6. 创建逻辑卷
sudo lvcreate -L 50G -n lv_root vg_data
sudo lvcreate -l 100%FREE -n lv_home vg_data
 
# 7. 格式化
sudo mkfs.ext4 /dev/vg_data/lv_root
sudo mkfs.ext4 /dev/vg_data/lv_home

案例二:分区表备份脚本

#!/bin/bash
# backup-partition-tables.sh
# 自动备份所有 GPT 磁盘的分区表
 
BACKUP_DIR="/backup/partition-tables/$(date +%Y%m%d)"
LOG_FILE="$BACKUP_DIR/backup.log"
 
mkdir -p "$BACKUP_DIR"
exec > >(tee "$LOG_FILE") 2>&1
 
echo "=== 分区表备份开始: $(date) ==="
 
for disk in /dev/sd[a-z]; do
    if [ ! -b "$disk" ]; then
        continue
    fi
 
    disk_name=$(basename "$disk")
 
    # 检查是否为 GPT 磁盘
    if sudo sgdisk -p "$disk" >/dev/null 2>&1; then
        echo "备份 GPT: $disk"
        sudo sgdisk --backup="$BACKUP_DIR/${disk_name}.sgdisk" "$disk"
        sudo sgdisk --verify "$disk"
        echo "  状态: $?"
    fi
 
    # 同时备份 sfdisk 格式(兼容 MBR)
    echo "备份 sfdisk: $disk"
    sudo sfdisk -d "$disk" > "$BACKUP_DIR/${disk_name}.sfdisk"
done
 
echo "=== 备份完成: $(date) ==="
echo "备份目录: $BACKUP_DIR"
ls -la "$BACKUP_DIR"

案例三:无损扩容 root 分区

#!/bin/bash
# resize-root.sh
# 在线扩容 root 分区和文件系统
 
set -e
 
DISK="${1:-/dev/sda}"
PART_NUM="${2:-2}"
 
echo "扩容 $DISK 第 ${PART_NUM} 个分区..."
 
# 1. 扩展分区
sudo growpart "$DISK" "$PART_NUM"
 
# 2. 检测文件系统类型
FSTYPE=$(lsblk -no FSTYPE "/dev/$(basename "$DISK")${PART_NUM}")
echo "文件系统类型: $FSTYPE"
 
# 3. 扩展文件系统
case "$FSTYPE" in
    ext4)
        sudo resize2fs "/dev/$(basename "$DISK")${PART_NUM}"
        ;;
    xfs)
        sudo xfs_growfs /
        ;;
    *)
        echo "不支持的文件系统类型: $FSTYPE"
        exit 1
        ;;
esac
 
# 4. 验证
df -h /
echo "扩容完成"

注意事项

  1. 操作前备份:任何分区操作前都应备份重要数据和分区表
  2. 卸载分区:缩小分区必须在卸载状态下进行(ext4 可在线缩小但不推荐)
  3. 4K 对齐:所有现代分区工具默认对齐,但手动指定扇区时需注意
  4. GPT 备份:GPT 磁盘应定期备份分区表,sgdisk --backup 是最可靠的方式
  5. RAID/LVM 层级:在 RAID 或 LVM 上操作分区时,注意层级关系,先操作底层
  6. 内核重读:分区表修改后可能需要 partprobe 或重启才能被内核识别
# 通知内核重新读取分区表
sudo partprobe /dev/sda
 
# 或强制重新扫描
echo 1 | sudo tee /sys/block/sda/device/rescan