Linux 中 fdisk 命令实战:分区表、MBR/GPT、创建删除与调整分区

安装新的 SSD 或硬盘后,你要做的第一件事就是对其分区。在格式化并存储文件之前,驱动器至少需要有一个分区。

在 Linux 中,有多种工具可用于创建分区,其中 fdisk 是最常用的一个。fdisk 是一个菜单驱动的命令行工具,允许你在存储设备上创建和操作分区表。

要在 Linux 中使用 fdisk 创建分区,请用 sudo fdisk /dev/sdX 打开目标磁盘,必要时创建分区表,用 n 添加新分区,用 p 查看布局,并用 w 写入更改。

本指南涵盖 Linux 中的 fdisk 命令。如果你更喜欢更直观的界面或需要高级功能,可以考虑 cfdisk、parted 或 gdisk 等工具。

请注意,fdisk 是一个危险的工具,应极其谨慎地使用。只有 root 用户或具有 sudo 权限的用户才能操作分区表。

语法

fdisk 命令的一般语法是:

fdisk [OPTIONS] DEVICE

例如,要打开 /dev/sdb:

sudo fdisk /dev/sdb

你最常用到的选项有:

• -l, --list - 打印给定设备的分区表并退出。 • -x, --list-details - 类似 -l,但包含更多细节,例如分区 UUID 和名称。 • -o, --output - 选择要打印的列,例如 -o Device,Size,Type。 • -t, --type - 仅识别给定的分区表类型,例如 gpt 或 dos。 • -w, --wipe - 控制何时从设备擦除旧的文件系统与分区表签名:auto、always 或 never。 • --bytes - 以字节而非人类可读单位打印大小。

运行 fdisk --help 查看完整的选项列表。

列出分区

要列出设备的分区表,请用 -l 选项调用 fdisk 命令,后接设备名。例如,要列出 /dev/sda 的分区表和分区,你可以运行:

sudo fdisk -l /dev/sda

当未提供设备作为参数时,fdisk 会打印 /proc/partitions 文件中列出的所有设备的分区表:

sudo fdisk -l
Disk /dev/nvme0n1: 232.91 GiB, 250059350016 bytes, 488397168 sectors
Disk model: Samsung SSD 960 EVO 250GB               
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 6907D1B3-B3AB-7E43-AD20-0707A656A1B5

Device            Start       End   Sectors   Size Type
/dev/nvme0n1p1     2048   1050623   1048576   512M EFI System
/dev/nvme0n1p2  1050624  34605055  33554432    16G Linux swap
/dev/nvme0n1p3 34605056 488397134 453792079 216.4G Linux filesystem

Disk /dev/sda: 465.78 GiB, 500107862016 bytes, 976773168 sectors
Disk model: WDC WD5000AAKS-0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0001cca3

Device     Boot Start       End   Sectors   Size Id Type
/dev/sda1        2048 976771071 976769024 465.8G 83 Linux

上面的输出显示了连接到你系统的所有设备的当前分区表。通常,SATA 设备名遵循 /dev/sd[a-z] 模式,而 NVMe 设备名遵循 /dev/nvme0n1,其分区命名为 /dev/nvme0n1p1、/dev/nvme0n1p2 等。

创建分区表与分区

在打开 fdisk 之前,请确认你要分区的磁盘。最安全的开始方式是仅用 lsblk 列出整个磁盘:

lsblk -d -o NAME,SIZE,MODEL
NAME          SIZE MODEL
sda         465.8G WDC WD5000AAKS-0
sdb         298.1G External USB 3.0
nvme0n1     232.9G Samsung SSD 960 EVO 250GB

在此示例中,/dev/sdb 是我们想要分区的外部磁盘。请使用整个磁盘路径,例如 /dev/sdb,而不是现有的分区路径,例如 /dev/sdb1。

要开始对驱动器分区,请使用设备名运行 fdisk。在本示例中我们将操作 /dev/sdb:

sudo fdisk /dev/sdb

命令提示符会改变,并打开你可以输入命令的 fdisk 对话框:

Welcome to fdisk (util-linux 2.41.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS (MBR) disklabel with disk identifier 0x3dceae47.

Command (m for help):

在空白磁盘上,fdisk 会在内存中创建一个 DOS(MBR)分区表。尚未向磁盘写入任何内容,我们稍后会用 GPT 表替换它。

要获取所有可用命令的列表,请输入 m:

Command (m for help): m
Help:

  DOS (MBR)
   a   toggle a bootable flag
   b   edit nested BSD disklabel
   c   toggle the dos compatibility flag

  Generic
   d   delete a partition
   F   list free unpartitioned space
   l   list known partition types
   n   add a new partition
   p   print the partition table
   t   change a partition type
   v   verify the partition table
   i   print information about a partition
   e   resize a partition
   T   discard (trim) sectors

  Misc
   m   print this menu
   u   change display/entry units
   x   extra functionality (experts only)

  Script
   I   load disk layout from sfdisk script file
   O   dump disk layout to sfdisk script file

  Save & Exit
   w   write table to disk and exit
   q   quit without saving changes

  Create a new label
   g   create a new empty GPT partition table
   G   create a new empty SGI (IRIX) partition table
   o   create a new empty MBR (DOS) partition table
   s   create a new empty Sun partition table

第一组会随分区表类型而变化。在 GPT 磁盘上,它列出的是 GPT 命令,而不是 DOS(MBR)命令。

T 命令会在你确认操作后立即丢弃扇区。它不会等待 w,而且用 q 退出也无法撤销它。

如果你正在分区一个新驱动器,请在创建分区之前创建分区表。如果设备已有分区表且你想保留它,请跳过此步骤。

fdisk 支持多种分区方案。MBR 和 GPT 是两种最流行的分区表标准,它们以不同的方式在驱动器上存储分区信息。GPT 是大多数现代系统的更好选择。选择使用哪种分区标准时要考虑的主要点是:

• 使用 MBR 以传统 BIOS 模式启动磁盘。 • 使用 GPT 以 UEFI 模式启动磁盘。 • MBR 标准支持创建最大 2 TiB 的磁盘分区。如果你有 2 TiB 或更大的磁盘,请使用 GPT。 • MBR 限制为 4 个主分区。如果你需要更多分区,可以将其中一个主分区设为扩展分区,并容纳额外的逻辑分区。使用 GPT,你最多可以有 128 个分区。GPT 不支持扩展或逻辑分区。

在本示例中,我们将使用 GPT 分区表。

输入 g 以创建新的空白 GPT 分区表:

Command (m for help): g
Created a new GPT disklabel (GUID: 4649EE36-3013-214E-961C-51A9187A7503).

下一步是创建新分区。

我们将创建两个分区。第一个大小为 100 GiB,第二个将占用剩余的磁盘空间。

运行 n 命令以创建新分区:

Command (m for help): n

系统会提示你输入分区号。按 "Enter" 使用默认值(1):

Partition number (1-128, default 1):

接下来,命令会要求你指定第一个扇区。在大多数情况下,使用默认值,以便 fdisk 能够正确对齐分区。按 "Enter" 使用默认值(2048):

First sector (2048-625142414, default 2048):

在下一个提示中,你需要输入最后一个扇区。你可以使用最后一个扇区的绝对值,或使用相对于起始扇区的值,方法是使用 + 符号后接分区大小。大小可以用 kibibytes(K)、mebibytes(M)、gibibytes(G)、tebibytes(T)或 pebibytes(P)指定。

输入 +100G 将分区大小设为 100 GiB:

Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-625142414, default 625141759): +100G
Created a new partition 1 of type 'Linux filesystem' and of size 100 GiB.

默认情况下,新分区的类型被设为 "Linux filesystem",这对大多数 Linux 数据分区来说都没问题。

更改分区类型

某些分区需要不同的类型。例如,EFI 系统分区、交换分区、LVM 物理卷或 RAID 成员应使用匹配的分区类型,以便工具和安装程序能正确识别它。

要列出可用的 fdisk 分区类型,请输入 l:

Command (m for help): l

对于 GPT 磁盘,常见的分区类型包括 Linux filesystem、Linux swap、EFI System、Linux LVM 和 Linux RAID。对于 MBR 磁盘,fdisk 显示数字 ID,例如 83 Linux、82 Linux swap / Solaris 和 8e Linux LVM。

对于常规数据分区,跳过此步骤并将类型保留为 Linux filesystem。如果你要创建交换分区,请输入 t,选择分区号,然后输入 l 显示的类型名称、别名或代码:

Command (m for help): t
Selected partition 1
Partition type or alias (type L to list all): swap
Changed type of partition 'Linux filesystem' to 'Linux swap'.

磁盘只有一个分区,因此 fdisk 会在不询问的情况下选择它。当存在多个分区时,它会先提示输入分区号。

让我们创建将占用剩余磁盘空间的第二个分区:

Command (m for help): n

对分区号、第一个和最后一个扇区使用默认值。这将创建一个使用磁盘上所有可用空间的分区。

Partition number (2-128, default 2):
First sector (209717248-625142414, default 209717248):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (209717248-625142414, default 625141759):
Created a new partition 2 of type 'Linux filesystem' and of size 198.1 GiB.

默认的最后一个扇区会停在距离磁盘末尾几个扇区之前。fdisk 会在 1 MiB 边界结束分区,GPT 磁盘的最后几个扇区保存备份分区表。

创建完分区后,使用 p 命令显示新分区表:

Command (m for help): p
Disk /dev/sdb: 298.09 GiB, 320072933376 bytes, 625142448 sectors
Disk model: nal USB 3.0     
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 4649EE36-3013-214E-961C-51A9187A7503

Device         Start       End   Sectors   Size Type
/dev/sdb1       2048 209717247 209715200   100G Linux filesystem
/dev/sdb2  209717248 625141759 415424512 198.1G Linux filesystem

通过运行 w 命令保存更改:

Command (m for help): w

该命令会将表写入磁盘并退出 fdisk 菜单。

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

内核将读取设备分区表,无需重启系统。

删除分区

要删除分区,请用 fdisk 打开磁盘并输入 d。当磁盘有多个分区时,fdisk 会询问要删除哪一个:

Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.

删除分区会从分区表中移除其条目并使数据不可访问,因此请确保你已备份。与所有其他更改一样,在输入 w 之前不会有任何内容写入磁盘。

激活分区

既然分区已经创建,下一步是格式化分区并将其挂载到系统的目录树。

我们将两个分区都格式化为 ext4。格式化会擦除目标分区上的数据,因此在运行这些命令之前请仔细核对设备名:

sudo mkfs.ext4 /dev/sdb1

sudo mkfs.ext4 /dev/sdb2

第一个分区的输出如下所示:

mke2fs 1.47.2 (1-Jan-2025)
Discarding device blocks: done
Creating filesystem with 26214400 4k blocks and 6553600 inodes
Filesystem UUID: d25ed86f-1e82-4290-8ddb-0f48f48f7dfe
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done
Writing inode tables: done
Creating journal (131072 blocks): done
Writing superblocks and filesystem accounting information: done

如果分区仍保留旧的文件系统,mkfs.ext4 会在覆盖之前要求确认。在回答之前请再次核对设备名。

在本示例中,我们将把分区挂载到 /mnt/audio 和 /mnt/video 目录。

使用 mkdir 创建挂载点:

sudo mkdir -p /mnt/audio /mnt/video

挂载新分区:

sudo mount /dev/sdb1 /mnt/audio

sudo mount /dev/sdb2 /mnt/video

分区将保持挂载状态,直到你卸载它们或关闭机器。要在 Linux 系统启动时自动挂载分区,请在其 /etc/fstab 文件中添加相应条目。通过 UUID 引用分区。像 /dev/sdb1 这样的设备名在启动之间可能会改变,但 UUID 保持不变。要打印 UUID,请使用 blkid:

sudo blkid /dev/sdb1
/dev/sdb1: UUID="d25ed86f-1e82-4290-8ddb-0f48f48f7dfe" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="b80b85ca-39ae-4320-ae22-dd8f69b41e43"

UUID 值就是在 /etc/fstab 中要使用的值。

你现在可以使用新分区来存储文件了。

调整分区大小

在 util-linux 2.40 及更高版本中,fdisk 可以使用 e 命令增大或缩小分区。用 fdisk --version 检查你的版本;更早的版本没有此命令。它只更改分区条目,而不是其中的文件系统,并且只能将分区增大到紧随其后的空闲空间中。

在下面的示例中,第二个分区为 1 GiB,磁盘的其余部分是空闲的。输入 e,选择分区,然后输入新大小。不输入值直接按 "Enter" 可使用该分区之后的所有空闲空间:

Command (m for help): e
Partition number (1,2, default 2): 2
New <size>{K,M,G,T,P} in bytes or <size>S in sectors (default 3G):
Partition 2 has been resized.

用 w 写入表后,增大文件系统以填满新空间。对于 ext4,请使用 resize2fs:

sudo resize2fs /dev/sdb2

缩小则按相反的顺序进行。对于 ext4,先卸载文件系统,缩小文件系统,然后缩小分区。你可以增大已挂载的 ext4 文件系统,但无法在挂载时缩小它。如果分区最终小于文件系统,你将丢失数据。当空闲空间位于分区之前时,请使用 gparted。它可以移动分区以及调整其大小。

快速参考

关于可打印的快速参考,请参阅 fdisk 速查表。

命令说明
sudo fdisk -l列出所有检测到磁盘的分区表
sudo fdisk -l /dev/sdX列出单个磁盘的分区表
sudo fdisk /dev/sdX在交互式 fdisk 模式中打开磁盘
m显示帮助与可用的交互命令
p打印当前内存中的分区表
n创建新分区
d删除分区
e调整分区大小(util-linux 2.40 及更高版本)
l列出可用的分区类型
t更改分区类型
g创建新的 GPT 分区表
o创建新的 MBR(DOS)分区表
w将更改写入磁盘并退出
q不保存更改即退出

故障排查

Re-reading the partition table failed.: Device or resource busy fdisk 写入了新表,但内核仍在使用旧表。当该磁盘上的某个分区已挂载时会发生这种情况。用 sudo umount /dev/sdXN 卸载该磁盘上的分区,然后运行 sudo partprobe /dev/sdX。如果磁盘包含根文件系统,请重启系统。

Partition #1 contains a ext4 signature 新分区起始于旧文件系统曾经所在的位置。在写入表时回答 Y 以移除旧签名。仅当你要在相同起始扇区重新创建分区并想保留其数据时,才回答 N。

fdisk: cannot open /dev/sdX: Permission denied 读写分区表需要 root 访问权限。请使用 sudo 运行 fdisk,即使你只是用 -l 列出分区时也是如此。

常见问题

MBR 与 GPT 有什么区别?MBR 是传统分区方案,磁盘大小限制为 2 TiB,最多 4 个主分区。GPT 是现代标准,支持更大的磁盘和更多分区,并且是 UEFI 系统上的标准布局。

如何将 MBR 转换为 GPT?备份磁盘,然后将分区表重新创建为 GPT 并恢复数据。在某些情况下要进行就地转换,可以使用 gdisk 或 sgdisk 等工具,但始终要验证兼容性并保留备份。

我可以在不丢失数据的情况下对磁盘分区吗?这取决于现有的布局和空闲空间。分区可能是破坏性的,因此请使用可靠的备份,并在非关键磁盘上测试后再进行更改。

fdisk 与 parted 有什么区别?fdisk 是一个菜单驱动的工具,在内存中保存分区表编辑,直到你用 w 写入它们。parted 会立即应用大多数更改,并且可以从 shell 提示符运行完整命令,因此更易于在脚本中使用。

结论

fdisk 涵盖了大多数日常分区工作:列出磁盘、在 MBR 和 GPT 之间切换、添加、删除和调整分区大小,以及更改类型。关于脚本化分区,请参阅我们的 parted 命令指南。