理解 Linux 中的 /etc/fstab 文件:格式、字段、挂载选项与实战

/etc/fstab 文件(filesystem table,文件系统表)是一个系统配置文件,它定义了分区、文件系统和存储设备在开机时如何挂载。系统在启动过程中读取该文件,并自动挂载其中的每一个条目。

当你需要新增磁盘、创建交换文件、挂载网络共享,或修改已有文件系统的挂载选项时,理解 /etc/fstab 是必不可少的。

本指南将讲解 /etc/fstab 的文件格式、每个字段的含义、常用挂载选项,以及如何安全地新增条目。

/etc/fstab 文件格式

/etc/fstab 是一个纯文本文件,每一行一个条目,每行定义一个要挂载的文件系统。以 # 开头的行是注释,系统会忽略它们。

要安全地查看文件内容,可以使用 less :

less /etc/fstab

一个典型的 /etc/fstab 文件看起来像下面这样:

# <file system>                           <mount point>  <type>  <options>         <dump>  <pass>
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  /              ext4    errors=remount-ro  0       1
UUID=b2c3d4e5-f6a7-8901-bcde-f12345678901  /home          ext4    defaults           0       2
UUID=c3d4e5f6-a7b8-9012-cdef-123456789012  none           swap    defaults           0       0
tmpfs                                      /tmp           tmpfs   defaults,noatime   0       0

每个条目包含六个以空格分隔的字段:

UUID=a1b2c3d4...  /home  ext4  defaults  0  2

[---------------] [---]  [--]  [------]  -  -

|                   |      |      |      |  |

|                   |      |      |      |  +-> 6. Pass (fsck order)

|                   |      |      |      +----> 5. Dump (backup flag)

|                   |      |      +-----------> 4. Options

|                   |      +------------------> 3. Type

|                   +-------------------------> 2. Mount point

+---------------------------------------------> 1. File system

这些字段之间用空格或制表符分隔,列与列之间并不一定需要对齐。上面示例中的对齐只是为了便于阅读。

字段说明

  • 文件系统(File system)- 要挂载的设备或分区。可指定为:UUID:UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 磁盘标签:LABEL=home 设备路径:/dev/sda1 网络路径:192.168.1.10:/export/share(用于 NFS)建议使用 UUID,因为像 /dev/sda1 这样的设备路径在增减磁盘时可能会变化。要查找分区的 UUID,可运行 blkid,或者如果想以设备树的形式查看同样的信息,运行 lsblk -f:sudo blkid
  • 挂载点(Mount point)- 文件系统被挂载到的目录。该目录必须已经存在。常见的挂载点包括 /、/home、/boot 和 /mnt/data。对于交换条目,此字段设为 none。
  • 类型(Type)- 文件系统类型。常用值包括:ext4 - 默认的 Linux 文件系统 xfs - RHEL 系发行版使用的高性能文件系统 btrfs - 支持快照的写时复制文件系统 swap - 交换分区或文件 tmpfs - 存储在内存中的临时文件系统 nfs - 网络文件系统 vfat - FAT32 文件系统(U 盘、EFI 分区)auto - 让内核自动检测文件系统类型
  • 选项(Options)- 以逗号分隔的挂载选项列表。详见下文的常用挂载选项一节。
  • Dump - 由 dump 备份工具使用。值为 0 表示该文件系统不被纳入备份;为 1 表示被纳入。大多数现代系统已不使用 dump,因此通常设为 0。
  • Pass - fsck 在开机时检查文件系统的顺序。根文件系统应为 1。其他文件系统应为 2,以便在根文件系统之后被检查。值为 0 表示不检查该文件系统。

常用挂载选项

每个 fstab 条目的第四个字段是一个以逗号分隔的挂载选项列表。以下是最常用的选项:

  • defaults - 使用标准默认选项(rw、suid、dev、exec、auto、nouser、async)。一些实际行为仍可能因文件系统和内核设置而异。
  • ro - 将文件系统挂载为只读。
  • rw - 将文件系统挂载为可读写。
  • relatime - 当存储的访问时间不比修改或变更时间更新,或已超过 24 小时时,才更新文件访问时间。自 Linux 2.6.30 起,内核默认就以这种方式工作。
  • noatime - 完全不更新文件访问时间。相比默认的 relatime 行为,在大多数系统上收益很小,但它对大量读取文件的负载仍有帮助。
  • nodiratime - 不更新目录的访问时间。
  • noexec - 不允许在该文件系统上执行二进制文件。
  • nosuid - 不允许 set-user-ID 或 set-group-ID 位生效。
  • nodev - 不解释该文件系统上的字符设备或块设备。
  • nofail - 如果设备开机时不存在,不报告错误。适用于可移动驱动器和网络共享。
  • auto - 在开机时自动挂载文件系统(默认行为)。
  • noauto - 不在开机时自动挂载。该文件系统仍可用 mount 手动挂载。
  • user - 允许普通用户挂载该文件系统。
  • errors=remount-ro - 发生错误时将文件系统重新挂载为只读。常见于根文件系统条目。
  • _netdev - 该文件系统需要网络访问。系统会等待网络可用后再挂载。用于 NFS、CIFS 和 iSCSI 挂载。
  • x-systemd.automount - 在首次访问时挂载文件系统,而不是在开机时挂载。由 systemd 管理。
  • x-systemd.device-timeout=30 - systemd 在放弃之前等待设备出现的时间。适用于需要几秒才能转动起来的外接硬盘盒。
  • x-systemd.requires=UNIT - 在挂载前等待另一个 systemd 单元启动。当文件系统依赖 VPN 或解密服务时很有用。
  • subvol=NAME - 挂载一个特定的 btrfs 子卷,而不是顶层子卷。在 btrfs 上安装发行版(如 Fedora 和 openSUSE)会使用 subvol=root 或 subvol=@ 这样的条目。

你可以把多个选项用逗号组合起来:

UUID=a1b2c3d4...  /data  ext4  defaults,noatime,nofail  0  2

所有者与权限选项

像 vfat、exfat 和 ntfs 这类文件系统并不存储 Unix 的所有者和权限位,因此内核必须在挂载时为其分配。默认情况下,驱动器上的所有内容都属于 root,这就是为什么普通用户常常无法写入刚挂载的 U 盘。下面的选项决定了内核所分配的内容:

  • uid=1000 - 拥有文件系统上每个文件的数字用户 ID。
  • gid=1000 - 拥有文件系统上每个文件的数字组 ID。
  • umask=022 - 从文件和目录上去除的权限位,写法与 umask 命令相同。
  • dmask=022 - 仅从目录上去除的权限位。
  • fmask=133 - 仅从文件上去除的权限位。

在写入条目之前,可以用 id 命令查看你自己的 ID:

id -u; id -g
1000
1000

第一个数字是用户 ID,第二个是组 ID。在 cifs 挂载中,当服务器不提供 Unix 所有者和模式时,uid、gid、file_mode 和 dir_mode 才会生效。如果启用了 Unix 扩展,服务器报告的值通常会优先生效。

fstab 在开机时如何被使用

在基于 systemd 的发行版上,/etc/fstab 中的挂载并不是在开机时逐行读取文件来完成的。一个名为 systemd-fstab-generator 的生成器会在启动序列的早期运行,并把每一个条目转换成一个原生的挂载单元。/mnt/data 这样的条目会变成一个名为 mnt-data.mount 的单元,systemd 启动它的方式与启动其他任何单元相同。

该生成器还会决定每个挂载发生的时机。本地文件系统被排在 local-fs.target 之前,因此它们会在系统其余部分启动之前就位。网络文件系统则被排在 remote-fs.target 之前,后者会等待网络就绪。systemd 能够自行识别 nfs 和 cifs 等类型,而 _netdev 选项会覆盖这种检测,适用于它无法分类的任何设备,例如用 ext4 格式化的 iSCSI 设备。

要查看由你的文件生成的单元,可以列出当前活动的挂载单元:

systemctl list-units --type=mount

因为这些单元是生成的而非手工编写的,所以修改 /etc/fstab 后,要等管理器重新加载配置才会被 systemd 读到。这正是下一节中需要使用 systemctl daemon-reload 的原因。

向 /etc/fstab 添加条目

在编辑 /etc/fstab 之前,务必先创建一个备份:

sudo cp /etc/fstab /etc/fstab.bak

第 1 步:查找 UUID

确认你要挂载的分区的 UUID:

sudo blkid /dev/sdb1
/dev/sdb1: UUID="d4e5f6a7-b8c9-0123-def0-123456789abc" TYPE="ext4"

第 2 步:创建挂载点

创建文件系统将被挂载到的目录:

sudo mkdir -p /mnt/data

第 3 步:添加条目

用文本编辑器打开 /etc/fstab :

sudo nano /etc/fstab

在文件末尾添加一行新内容:

UUID=d4e5f6a7-b8c9-0123-def0-123456789abc  /mnt/data  ext4  defaults,nofail  0  2

第 4 步:重新加载并测试条目

在基于 systemd 的系统上,编辑 /etc/fstab 后请重新加载生成的挂载单元:

sudo systemctl daemon-reload

然后验证文件语法和挂载关系:

sudo findmnt --verify

不用重启,可以使用 mount -a 来挂载那些尚未挂载、且没有使用 noauto 选项的 fstab 条目:

sudo mount -a

如果该命令没有任何输出,说明条目正确。如果出现错误,请在重启前修复 fstab 条目,因为错误的 fstab 可能导致系统无法正常启动。

确认文件系统已挂载:

df -h /mnt/data

常见 fstab 示例

交换文件(Swap File)

要向 fstab 添加一个交换文件:

/swapfile  none  swap  defaults  0  0

NFS 网络共享

要挂载一个需要网络访问的 NFS 共享:

192.168.1.10:/export/share  /mnt/nfs  nfs  defaults,_netdev,nofail  0  0

CIFS/SMB Windows 共享

要使用一个凭据文件挂载 Windows/Samba 共享:

//192.168.1.20/share  /mnt/smb  cifs  credentials=/etc/samba/creds,_netdev,nofail  0  0

凭据文件本身保存了访问该共享所用的账号:

username=shareuser

password=sharepassword

为它设置严格的权限,防止其他用户读取:

sudo chmod 600 /etc/samba/creds
警告:凭据文件以明文形式存储密码。请将其放在 /etc 下,归 root 所有并设置 0600 权限,切勿把它复制到项目目录或提交到版本控制。如果部署仓库引用了该路径,请将文件加入 .gitignore,并仅在服务器上保留真实的副本。

USB 或外接驱动器

要挂载一个可能并非始终连接的 removable 驱动器:

UUID=e5f6a7b8-c9d0-1234-ef01-23456789abcd  /mnt/usb  ext4  defaults,nofail,noauto  0  0

nofail 选项会在驱动器未连接时阻止启动报错。noauto 选项会阻止自动挂载;需要时用 sudo mount /mnt/usb 手动挂载。

用户可写的 exFAT 或 FAT32 驱动器

可移动驱动器通常使用 exfat 或 vfat 格式化,它们自身并不携带所有者信息。将整个文件系统映射到你的账号,这样无需 sudo 就能写入:

UUID=1234-ABCD  /mnt/usb  exfat  defaults,nofail,uid=1000,gid=1000,dmask=022,fmask=133  0  0

这些掩码使目录获得 0755 权限、普通文件获得 0644 权限,因此文件不会被标记为可执行。这里的 UUID 比 ext4 分区上的短得多,因为 vfat 和 exfat 存储的是卷序列号而非完整 UUID。请使用 blkid 为该设备报告的值。

为 /tmp 使用 tmpfs

要将 /tmp 挂载为内存中的临时文件系统:

tmpfs  /tmp  tmpfs  defaults,noatime,size=2G  0  0

快速参考

如需可打印的速查表,请参阅挂载备忘单(mount cheatsheet)。

任务命令
查看 fstab 内容less /etc/fstab
备份 fstabsudo cp /etc/fstab /etc/fstab.bak
查找分区 UUIDsudo blkid
重新加载 systemd 挂载单元sudo systemctl daemon-reload
列出生成的挂载单元systemctl list-units --type=mount
验证 fstab 语法sudo findmnt --verify
挂载所有 fstab 条目sudo mount -a
检查已挂载的文件系统mount 或 df -h
检查文件系统类型lsblk -f
从备份恢复 fstabsudo cp /etc/fstab.bak /etc/fstab

故障排查

编辑 fstab 后系统无法启动:一个无法挂载的必需条目可能会中断启动过程,并把你带入紧急修复 shell。如果根文件系统是只读的,在改动任何东西之前先将其重新挂载为可读写:

mount -o remount,rw /

恢复你之前创建的备份,或者打开文件并修正有问题的那一行:

cp /etc/fstab.bak /etc/fstab

然后重新加载生成的挂载单元并重启:

systemctl daemon-reload

reboot

这些命令假设紧急修复 shell 已经为你提供了 root 提示符。如果你无法进入该 shell,请从 live USB 启动,挂载根分区,并在那里编辑 /etc/fstab。在重启前运行 sudo findmnt --verify 和 sudo mount -a 可以从根本上避免这种情况。

mount -a 报错 “wrong fs type” 或 “bad superblock”:fstab 条目中的文件系统类型与设备上的实际文件系统不匹配。使用 sudo blkid 或 lsblk -f 查看正确的类型。

网络共享在开机时挂载失败:添加 _netdev 选项,告诉系统在挂载前等待网络就绪。在基于 systemd 的系统上,x-systemd.automount 也有助于解决时序问题。

“mount point does not exist”:第二个字段指定的目录不存在。在运行 mount -a 之前,先用 mkdir -p /path/to/mountpoint 创建它。

重新格式化分区后 UUID 发生变化:重新格式化分区会分配一个新的 UUID。运行 sudo blkid 查找新的 UUID,并相应地更新 fstab 条目。

常见问题(FAQ)

如果在 /etc/fstab 中出错会怎样? 如果条目引用了一个不存在的设备且没有 nofail 选项,系统可能会在启动时进入紧急修复 shell。对于非必需的文件系统,务必使用 nofail,并在重启前用 sudo mount -a 测试。

我应该使用 UUID 还是设备路径(/dev/sda1)? 使用 UUID。如果新增或移除磁盘,或者启动顺序发生变化,设备路径都可能改变。UUID 对每个文件系统都是唯一的,除非你重新格式化分区,否则不会变化。

nofail 选项有什么作用? 它告诉系统即使设备不存在或无法挂载,也继续启动。没有 nofail 时,缺失的设备会导致系统进入紧急修复 shell。

如何删除一个 fstab 条目? 用 sudo nano /etc/fstab 打开 /etc/fstab,删除或注释掉该行(在行首加 #),保存文件,然后用 sudo umount /mount/point 卸载该文件系统。

noauto 和 nofail 有什么区别? noauto 阻止文件系统在开机时自动挂载,你必须手动挂载它。nofail 仍然会自动挂载,但在设备缺失时不会导致启动错误。

总结

/etc/fstab 文件控制着文件系统如何在开机时挂载。每个条目都指定了设备、挂载点、文件系统类型、选项以及检查顺序。编辑前务必备份 fstab,使用 UUID 而非设备路径,并在重启前用 sudo mount -a 测试改动。