在 Linux 中使用 parted 管理磁盘分区

当一块新磁盘出现在 lsblk 中时,Linux 已能识别它,但还没有可存储文件的位置。在创建文件系统并挂载之前,磁盘需要先有分区表以及至少一个分区。parted 命令可在终端中管理这些边界,同时支持 GPT 与 MBR 分区表,既可以交互运行,也能通过脚本执行。

与 fdisk 不同(fdisk 会暂存改动,直到你写入分区表才生效),parted 的大部分命令会立即执行。本指南将介绍如何检查磁盘、创建 GPT 分区表、添加对齐的分区、调整分区边界,以及删除分区——整个过程都让你清楚自己正在修改的是哪一层存储。

parted 命令语法

该命令的通用形式如下:

parted [OPTIONS] [DEVICE [COMMAND [ARGUMENTS]]]

始终显式指定设备。如果省略设备,parted 会自行选择一个,而在拥有多块磁盘的机器上,这种风险并不值得冒。

你最常用的选项有:

  1. -l, --list —— 列出所有被识别块设备的分区布局。
  2. -s, --script —— 从不提示输入。仅在已确认设备和命令无误后使用。
  3. -m, --machine —— 生成以冒号分隔的输出,便于脚本处理。
  4. -j, --json —— 在支持该选项的版本中生成 JSON 输出。
  5. -a, --align —— 选择新建分区的对齐方式,默认为 optimal(最优)。

示例中将选项放在设备之前,并用 -- 隔开 parted 命令。当参数以短横线开头时(例如表示磁盘最后扇区的 -1s 结束位置),这个分隔符很关键。若不加 --,parted 会把 -1s 当作无效选项而非位置参数。

安装 parted

大多数发行版都自带 parted。如果系统中没有该命令,请使用发行版的包管理器安装。

在 Ubuntu、Debian 及其衍生版上:

sudo apt update

sudo apt install parted

在 Fedora、RHEL 及其衍生版上:

sudo dnf install parted

继续之前,先确认已安装的版本:

parted --version

列出磁盘与空闲空间

先使用 lsblk,以便将每个设备名称与其容量、型号、文件系统和挂载点对应起来:

lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL

TYPE 列为 disk 的行代表整块设备,而标记为 part 的行是分区。请通过容量和型号来确认,而不要依赖 /dev/sdb 这类名称,因为设备名在每次启动之间可能会变化。

接下来,列出每块被识别磁盘的分区表:

sudo parted --list
Model: ATA Samsung SSD 870 (scsi)
Disk /dev/sda: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name                  Flags
 1      1049kB  538MB   537MB   fat32        EFI System Partition  boot, esp
 2      538MB   500GB   500GB   ext4

Partition Table 这一行会标明分区表类型为 gpt 还是 msdos(MBR)。分区行则显示各分区的边界、检测到的文件系统、GPT 名称以及所有标志。

要以 MiB 为单位查看单块磁盘并包含其未分配区域,可使用 unit MiB 后接 print free:

sudo parted /dev/sdb -- unit MiB print free
Model: QEMU QEMU HARDDISK (scsi)
Disk /dev/sdb: 102400MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start     End        Size       File system  Name  Flags
        0.02MiB   1.00MiB    0.98MiB    Free Space
 1      1.00MiB   51200MiB   51199MiB   ext4         data
        51200MiB  102400MiB  51200MiB   Free Space

没有编号的行是未分配区域。磁盘开头的那一小段空隙用于存放 GPT 表头,而分区 1 之后那 51200MiB 的区域则是可用于新建分区的空间。这是创建或扩展分区前应执行的只读命令,因为它能显示是否存在空闲空间,以及这些空间位于现有分区的哪一侧。

在 parted 3.4 及更高版本中,--json 会以结构化数据的形式返回相同的布局,便于脚本处理:

sudo parted --json /dev/sdb -- unit MiB print
{
   "disk": {
      "path": "/dev/sdb",
      "size": "102400MiB",
      "model": "QEMU QEMU HARDDISK (scsi)",
      "transport": "scsi",
      "logical-sector-size": 512,
      "physical-sector-size": 512,
      "label": "gpt",
      "max-partitions": 128,
      "partitions": [
         {
            "number": 1,
            "start": "1.00MiB",
            "end": "51200MiB",
            "size": "51199MiB",
            "name": "data",
            "filesystem": "ext4"
         }
      ]
   }
}

当脚本只需要某个单独的值时,可将其通过管道传给 jq,例如 jq -r '.disk.partitions[].size'。

你也可以只传入设备名,从而进入交互式会话:

sudo parted /dev/sdb
GNU Parted 3.7
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)

在 (parted) 提示符下,可以输入 print、mkpart、quit 等命令。后续示例均采用命令行模式,以便每条操作及其目标都清晰地呈现在一条可直接复制执行的命令中。

创建 GPT 分区表

新磁盘需要先有分区表,才能容纳分区。GPT 是当前系统的标准选择;当 512 字节扇区的 MBR 分区表会超出其 2 TiB 寻址上限时,GPT 是必需的。

在创建分区表之前,请立即再次执行检查命令:

lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL /dev/sdb

确认 /dev/sdb 就是目标磁盘后,创建 GPT 标签:

sudo parted --script /dev/sdb -- mklabel gpt

这会替换现有的分区表,并使旧分区无法访问。--script 选项只是抑制交互提示,它并非「预演」,也不会让操作更安全。只有在出于旧系统兼容性的需要、明确要用 MBR 分区表时,才使用 mklabel msdos。

创建对齐的分区

mkpart 命令接受一个 GPT 分区名、一个文件系统类型提示,以及起始和结束位置。要创建一个占满可用磁盘空间的数据分区,执行:

sudo parted --script /dev/sdb -- mkpart data ext4 1MiB 100%

这里名称是 data,ext4 用于指定期望的分区类型,它并不会创建 ext4 文件系统。从 1MiB 开始为 GPT 元数据留出空间,也让分区有一个通用的对齐起点;100% 则将其延伸到磁盘最后可用部分。

如果要创建两个分区,请各自指定范围。下面这个示例创建一个 50 GiB 的数据分区,并用剩余空间作为备份分区:

sudo parted --script /dev/sdb -- mkpart data ext4 1MiB 50GiB

sudo parted --script /dev/sdb -- mkpart backup ext4 50GiB 100%

MiB、GiB 这类 IEC 单位表示精确位置;而 MB、GB 这类十进制单位会让 parted 自行选择就近位置,因此在可重复的命令中使用明确的 IEC 单位更不容易出错。

打印完成后的布局:

sudo parted /dev/sdb -- unit MiB print free

随后检查分区 1 的对齐情况:

sudo parted /dev/sdb -- align-check optimal 1
1 aligned

对齐检查用于确认分区是否从适合该设备的边界开始。如果报告 not aligned(未对齐),应在写入数据之前,用一个合适的起始位置重新创建一个空分区。

新分区仍然没有文件系统。确认 /dev/sdb1 就是那个新的空分区后,再单独对其进行格式化:

sudo mkfs.ext4 -L data /dev/sdb1

-L data 选项用于指定文件系统标签,它与 GPT 分区名是两回事。当你准备把该文件系统挂接到目录树时,可参考我们的挂载与卸载指南。

重命名 GPT 分区

GPT 为每个分区保存一个人类可读的名称。若要在不改动文件系统标签的情况下重命名分区 1,可使用 name 命令:

sudo parted --script /dev/sdb -- name 1 archive

之后执行 print,确认 Name 列中的新值。分区名在 GPT 及其他几种分区表格式中可用,但在 MBR 分区表中不可用。

设置分区标志

标志用于标记分区的用途,以便固件和其他工具正确处理它。set 命令接受分区号、标志名,以及 on 或 off:

sudo parted --script /dev/sdb -- set 1 esp on

在 GPT 磁盘上最常用的标志有:

  1. esp —— 将分区标记为 EFI 系统分区。在 GPT 上,boot 与 esp 是同一个标志。
  2. bios_grub —— 标记 GRUB 在 BIOS 固件下启动 GPT 磁盘所需的小块未格式化分区。
  3. lvm —— 将分区标记为 LVM 物理卷。
  4. raid —— 将分区标记为软 RAID 成员。
  5. msftdata —— 将分区标记为 Microsoft 基本数据分区,即 Windows 所期望的类型。

要关闭某个标志,改为传入 off 即可:

sudo parted --script /dev/sdb -- set 1 lvm off

标志只记录意图并设置 GPT 分区类型,并不会真正创建任何东西。设置 lvm 不会执行 pvcreate,设置 esp 也不会在分区上建立 FAT32 文件系统。要查看当前分区表支持哪些标志,可进入交互会话并执行 help set。

调整分区大小

在扩展分区之前,先用 print free 确认其紧邻的后续位置就是未分配空间:

sudo parted /dev/sdb -- unit MiB print free

如果分区 1 之后紧跟着空闲空间,可将其结束边界移动到磁盘末尾:

sudo parted --script /dev/sdb -- resizepart 1 100%

resizepart 命令只改变分区的边界,并不会调整其中的文件系统大小。对于 ext4 文件系统,随后需要扩大文件系统:

sudo resize2fs /dev/sdb1

用 df 确认文件系统现在已经识别到新增的容量。其他文件系统需要各自的调整工具;例如 XFS 使用 xfs_growfs 来扩容,且无法被缩小。

缩小分区是另一套流程。你必须先卸载并缩小可缩小的文件系统、检查其错误,之后才能移动分区边界。切勿单独使用 resizepart 来缩小分区,否则它可能截断正在使用的文件系统数据。

删除分区

最后再列出一次分区表,记下你要删除的分区编号:

sudo parted /dev/sdb -- print

确认编号无误后,删除分区 2:

sudo parted --script /dev/sdb -- rm 2

该分区会立即从分区表中消失,其原有空间变为未分配区域。脚本模式不会给出确认提示,因此应将检查与删除拆分为两条独立命令,而不是串联执行。

快速参考

如需可打印的快速参考,请参阅 parted 速查表。

TaskCommand
List all partition tablessudo parted --list
Show one disk and its free spacesudo parted /dev/sdb -- unit MiB print free
Print the layout as JSONsudo parted --json /dev/sdb -- unit MiB print
Open interactive modesudo parted /dev/sdb
Create a GPT tablesudo parted --script /dev/sdb -- mklabel gpt
Create an ext4 data partitionsudo parted --script /dev/sdb -- mkpart data ext4 1MiB 100%
Check optimal alignmentsudo parted /dev/sdb -- align-check optimal 1
Rename GPT partition 1sudo parted --script /dev/sdb -- name 1 archive
Set the EFI system partition flagsudo parted --script /dev/sdb -- set 1 esp on
Extend partition 1sudo parted --script /dev/sdb -- resizepart 1 100%
Remove partition 2sudo parted --script /dev/sdb -- rm 2

故障排查

内核仍在使用旧的分区表:请卸载该磁盘上的文件系统、禁用其中包含的任何交换分区,然后执行 sudo partprobe /dev/sdb 让内核重新读取分区表。如果设备仍然繁忙,应安排重启,而不要强行再做一次分区更改。

parted 报告某个分区未正确对齐:使用 sudo parted /dev/sdb -- align-check optimal NUMBER 验证起始边界。如果该分区为空,可用 1MiB 起始位置或其他满足设备对齐要求的边界重新创建。

误删了分区:立即停止对该磁盘的写入。打开 sudo parted /dev/sdb,用 rescue START END 并填入大致的旧边界,当且仅当其位置和文件系统都匹配时,才确认恢复到的分区。数据恢复并不保证成功,尤其在已经写入新数据之后。

parted 提示分区正在使用中:检查 lsblk 和 findmnt,然后在修改其边界之前先卸载文件系统。磁盘也可能因为包含活跃的交换分区、LVM 物理卷、软 RAID 或加密映射而持续处于繁忙状态。

常见问题

应该用 parted 还是 fdisk?两者都支持 GPT 和 MBR 分区表。fdisk 提供交互式工作流,会暂存改动直到你写入;而 parted 适合一行命令、脚本、对齐检查,以及调整分区结束边界。

parted 会格式化分区吗?不会。parted 只创建分区条目并记录期望的文件系统类型,并不会真正建立文件系统。在核对设备名后,对新分区执行对应的 mkfs 命令即可。

resizepart 也会一并调整文件系统大小吗?不会。resizepart 只移动分区的结束边界。请用对应文件系统专用的工具单独扩大或缩小文件系统,并且务必先缩小文件系统,再缩小其所在的分区。

应该用 GPT 还是 MBR?对于当前的 Linux 系统、UEFI 启动盘以及大于 2 TiB 的磁盘,请使用 GPT。仅当较旧的操作系统或固件有要求时,才使用 MBR。

总结

当你需要对分区边界进行精确、可重复的控制时(尤其是在 GPT 磁盘上),parted 最为有用。请将检查命令与写入命令分开执行,使用明确的单位,并在出现意外输出时停下来,而不是用 --script 强行继续。