主页 实验环境 学习Linux - Study Area CN

磁盘分区以及文件系统

我们之前学习了关于硬盘的知识,并且知道了在硬盘上还有着文件系统。那么就让我们来学习在 Linux 上的硬盘分区以及文件系统的知识吧!

本章东西较多,请做好心理准备,建议学一部分练一部分,边看边练。

基本知识

磁盘设备

我们前文提到了 Linux 上的 /dev 是大部分设备对应的文件,当然也包括磁盘设备。

在 Linux 上,不仅磁盘本身是文件,磁盘的每一个分区也都对应着一个文件。

在 Linux 上常见的磁盘设备有以下几种:

在下面的内容中:

  • X: 表示 a - z 的小写字母
  • @: 表示从 0 开始的自然数
  • /dev/sdX: 最常见的一种磁盘类型,你通常见到的也是这种,例如 /dev/sda
    • /dev/sdX@ 表示这个磁盘的每一个分区。
  • /dev/nvme@n@: 表示 NVME 上的磁盘,第一个数字表示设备名,第二个是命名空间,通常是 1,例如 /dev/nvme0n1
    • /dev/nvme@n@p@ 表示这个磁盘的每一个分区。
  • /dev/loop@: 被称为回环设备,为模拟出来的,通常作为 img 等镜像文件的挂载点,可以是一个硬盘也可以仅仅是一个分区,例如 /dev/loop0
    • /dev/loop@p@ 表示作为整个磁盘时的每一个分区。
  • /dev/mmblk@: 为嵌入式的存储,这种比较少见,我们一般不会遇到。

文件系统

Linux 兼容大部分的文件系统(前面有提到一个表格):

项目NTFSexFatext2/3/4xfs
Windows 兼容性不支持不支持
Linux 兼容性
MacOS 兼容性不支持不支持不支持

通常可以被 Linux 用作系统磁盘的文件系统格式的是:

  • ext2/3/4

    扩展日志文件系统,是最常见的系统磁盘的文件系统,也可以用作数据磁盘。现在 ext2/3 已经用的比较少了。

  • xfs

    一种高性能的文件系统,被 RockyLinux 等新的 Linux 发行版用作默认文件系统。

  • btrfs

    新兴的文件系统,自带了快照和压缩等十分方便的功能,不过目前还不太稳定。

还有一些其它的被 Linux 支持的格式:

  • ntfs

    是 Windows 上的默认文件系统,可以使用 ntfs-3g 包实现读取和写入。但是在 Linux 下有权限问题,并且不太稳定。

  • exfat/fat32

    比较老的文件系统,在 Linux 上也需要额外的包才可以写入。

还有一些特殊用途的文件系统:

  • swap

    交换分区,不可被用于存储数据,前面提到过。

在虚拟机上创建硬盘

我们要学习如何分区,那么就肯定要有一个硬盘。如果你按照上文的方法创建了虚拟机,请按照你使用的虚拟机软件,选择下面的文章完成创建虚拟磁盘的操作,然后再回到本篇继续学习。

  1. 在 VirtualBox 上创建虚拟磁盘
  2. 在 VMWare Workstation 上创建虚拟磁盘

使用命令行工具进行分区

进行分区需要具有 root 权限!

分区是一个非常危险的操作!进行操作前最好备份!如果你要调整系统磁盘分区,可以使用一个恢复镜像,例如一个 Linux 的安装磁盘或是 LiveCD。所以最好不要删除你安装系统的ISO文件(或者是U盘)!

除了下文的 partedfdisk 等工具,还有 gdisk(命令行)、cfdisk(命令行,方向键交互)、gparted 等工具,本文在此不过多介绍。

partedfdisk 已经被绝大多数 Linux 发行版包含,你通常无需额外安装。但是可能会有少部分发行版缺少其中任何一个软件包。

parted 和 fdisk 的基本命令格式

下面标注有 parted 和 fdisk 的命令,表示这个命令需要在对应工具的命令行模式下执行

parted

parted 有两种使用模式,一种是参数模式,一种是命令行模式。这两种模式区别不大,执行的命令都是相同的。下文均以命令行模式(非交互式)下的命令为展示。

# 参数模式
parted [设备文件] [你要执行的命令]

# 命令行模式
parted [设备文件]
# 然后再输入你的命令,输入完成后和终端一样需要回车
# 可使用 'quit'('q') 命令退出

parted 的命令也有两种模式:交互模式和非交互模式。

  • 交互模式就是输入一个命令,后面不带任何的参数,然后程序会要求你输入这个命令的每一个参数。
  • 非交互模式就是把这个命令的参数都以空格的形式填写在这个命令后,你不需要填写任何内容。

fdisk

fdisk 只有一种模式:交互式命令行模式。

fdisk 的使用和 parted 的使用方式几乎差不多,除了命令不同。

fdisk 可以使用 q 退出。

注意:fdisk 默认不会保存到磁盘,需要执行 w 命令才会真正写入磁盘。引用软件的提示: 使用写入命令前请三思

下面的命令中 <Enter> 表示无需输入任何内容直接回车即可。

查看所有硬盘

当我们需要进行分区时,我们肯定要知道有哪些硬盘。下面的任意一个指令均可:

  • lsblk

    执行效果: (个人最喜欢用的一种)

    NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
    sda      8:0    0 119.2G  0 disk
    ├─sda1   8:1    0   800M  0 part
    ├─sda2   8:2    0  79.2G  0 part
    └─sda3   8:3    0   845M  0 part
    sdb      8:16   0 931.5G  0 disk
    ├─sdb1   8:17   0   500M  0 part /boot
    ├─sdb2   8:18   0   524M  0 part [SWAP]
    ├─sdb3   8:19   0    60G  0 part /
    sdc      8:32   0 238.5G  0 disk
    ├─sdc1   8:33   0 174.4G  0 part
    ├─sdc2   8:34   0    32M  0 part
    └─sdc3   8:35   0    60G  0 part
    sr0     11:0    1  1024M  0 rom
    

    最左侧一列是设备名称,第三列是大小,第五列是设备的类型,第六列是挂载点(下面会说到)。

  • fdisk -l

    执行效果:

    ...
    
    Disk /dev/sdb:931.51 GiB,1000204886016 字节,1953525168 个扇区
    磁盘型号:WDC WD10EZEX-22M
    单元:扇区 / 1 * 512 = 512 字节
    扇区大小(逻辑/物理):512 字节 / 4096 字节
    I/O 大小(最小/最佳):4096 字节 / 4096 字节
    磁盘标签类型:gpt
    磁盘标识符:7690BA4B-E69F-4431-B4E6-XXXXXXXXXXXX
    
    设备             起点       末尾       扇区   大小 类型
    /dev/sdb1        2048    1026047    1024000   500M EFI 系统
    /dev/sdb2     1026048    2099199    1073152   524M Linux swap
    /dev/sdb3     2099200  127928319  125829120    60G Linux 文件系统
    /dev/sdb4   127928320 1282436494 1154508175 550.5G Microsoft 基本数据
    /dev/sdb5  1282437120 1953523711  671086592   320G Linux 文件系统
    
    ...
    

    每一个磁盘都会有这么一些内容,第一行有磁盘的设备文件和大小,下面是磁盘的其它信息,可以清晰看到磁盘的每一个分区的大小和类型。

  • df -h

    执行效果:

    文件系统        大小  已用  可用 已用% 挂载点
    dev             5.7G     0  5.7G    0% /dev
    run             5.7G  1.7M  5.7G    1% /run
    efivarfs        128K   89K   35K   73% /sys/firmware/efi/efivars
    /dev/sdb3        59G   33G   24G   59% /
    tmpfs           5.7G  258M  5.5G    5% /dev/shm
    ...
    tmpfs           5.7G   39M  5.7G    1% /tmp
    /dev/sdb5       320G   35G  285G   11% /mnt/xdata
    /dev/sdb1       499M  174M  326M   35% /boot
    /dev/sdb4       551G   90G  461G   17% /mnt/data
    

创建分区表

如前面所说,我们刚刚添加了一块硬盘,需要创建一个分区表才能进行分区。创建分区表需要使用 partedfdisk 命令。

parted

mklabel [gpt/mbr]

fdisk

g     # 创建 GPT 分区表
# 或者
o     # 创建 MBR 分区表

如果没有特殊需求建议选择 GPT 分区表。

创建新分区

有了分区表,我们可以开始分区了。

parted

mkpart primary [文件系统] [起始位置] [结束位置]

这里的 primary 表示分区类型,一般GPT分区表下无需修改。

文件系统可以是 ext4、ext3、ext2、xfs、fat32、ntfs 等等,也可不填。

起始位置和结束位置可以写数字,表示扇区数,也可以写单位,如 1G 表示 1GB, 也可以写百分比,如 100% 表示使用剩余的所有空间

fdisk

n       # 创建新分区
p       # 设置为主分区
<Enter>
<Enter> # 起始扇区号,默认会接在上一个分区后面
+[大小] # 分区大小,可以是数字,也可以是单位,如 +1G 表示 1GB

格式化分区

创建完分区后,我们需要对分区进行格式化,才能使用。Linux 并不像 Windows 那么贴心,会主动提示你格式化,但是也给了你更多的控制能力。

格式化要使用 mkfs 命令,但是格式是:

mkfs.[文件系统] [设备文件] [更多可选参数]
# 等价于
mkfs -t [文件系统] [设备文件] [更多可选参数]

注意文件系统和 mkfs 中间的 “.” ,如 mkfs.ext4等。

不同文件系统可以使用的参数也有些许不同。下面是一个列表:

  • mkfs.ext4
    • -L 可以设置卷标,可以看作磁盘的名字。
    • -N 可以设置 inode 的大小。inode 可以看作存储文件或目录的基本信息的东西。这个参数就决定了你的最大文件的数量。
    • -F 强制格式化,不过只有部分版本需要。
  • mkfs.vfat

    VFat 可以看作是 fat16fat32 等数据类型的总和,默认会自动选择格式。

    • -n 设置卷标
    • -F [版本] 可以设置格式化的 fat 文件系统的版本,如 1632 等。
  • mkfs.exfat 格式化成 exfat
    • -n 设置卷标
  • mkfs.xfs
    • -L 设置卷标
    • -f 强制格式化,会清空原有的分区
  • mkfs.btrfs
    • -L 设置卷标
    • -f 强制格式化

    btrfs 可用的参数很多,许多参数是为 raid(一种可以将多块硬盘模拟成一块的方法) 准备的,这里就不一一列举了。

查看分区列表

分区完成后,我们可以使用 partedfdisk 命令查看分区列表。

parted

print

fdisk

p

在这里我们就可以看到每个分区对应的设备文件了,一会我们要用到。

删除分区

如果我们不再需要一个分区,或者分区方案有误,我们可以使用 partedfdisk 命令删除分区。

parted

rm [分区号]

fdisk

d [分区号]

这里的分区号可以使用上一条查看分区列表的方式查看,其实就是 /dev/sdX@@ 所对应的数字(在其它类型的磁盘中是 p 后面的数字)。

其它技巧

partedfdisk 还有一些其它的技巧,下面列举了一小部分:

parted

resizepart [分区号] [起始位置] [结束位置] # 可以修改分区的大小
rescue [起始位置] [结束位置] # 可以查找丢失的分区

更多的技巧这里就不一一列举了。

挂载分区

创建了分区,我们该如何访问呢?答案就是挂载。

事实上,Windows 中的C盘、D盘等盘符也是挂载的,只不过 Windows 会自动为我们完成。Windows 也同样支持挂载到一个目录。

在下面,我们称挂载的目标路径为“挂载点”。挂载点通常约定俗称使用 /mnt 目录下的子目录(挂载整个系统时除外)

mountumount 命令

Linux 中挂载分区可以使用 mount 命令,卸载分区使用 umount 命令。

事实上,在图形化的文件管理器中,我们可以直接点击磁盘进行挂载(需要输入 root 密码验证身份),右面向下的箭头上面还有条横线的就是卸载按钮。

mount 命令的格式如下:

mount -t [文件系统] [设备文件] [挂载点]

-t 参数可以省略,Linux 会自动识别文件系统。

-o [挂载参数] 可以设置挂载参数,下面会列举出来。

然后我们就可以使用你设置的挂载点访问磁盘了。

可以指定 --mkdir 参数,会在挂载的时候自动创建对应的文件夹。

umount 命令的格式如下:

umount [挂载点/设备文件]

自动挂载

每次开机都要手动挂载分区是一件很麻烦的事情,我们可以使用 /etc/fstab 文件让系统自动挂载。

如果你查看这个文件,你会看到以下内容(不同系统默认的内容可能不同):

# Static information about the filesystems.
# See fstab(5) for details.

# <file system> <dir> <type> <options> <dump> <pass>
# /dev/sda3
UUID=25236755-bc8f-4ee4-a733-fc71ed33c408       /               ext4            rw,relatime     0 1

# /dev/sda1
UUID=D0EE-69A5          /boot           vfat            rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2

# /dev/sda2
UUID=94a6c32f-c2d2-4401-8749-689b005ac9f0       none            swap            defaults        0 0

每一行代表一个挂载点,每一列代表一个参数。每一列之间应该用 <tab> 和一个空格分隔。通常第一条就是你的系统。

整理起来就是这样:

分区的UUID挂载点文件系统的类型挂载选项是否自动运行 dump是否自动运行 fsck
UUID=XXXX/ext4rw,relatime01
UUID=XXXX/bootvfatrw,relatime...02
UUID=XXXXnoneswapdefaults00

其中:

  • # 开头的行是注释
  • UUID 可以使用查看分区的方法查看
  • 挂载点在处理 swap 的时候需要填 none
  • 不同文件系统挂载选项不同,使用逗号分隔,以下是常见的选项:
    • defaults 默认选项
    • ro 只读模式
    • rw 读写模式,默认的挂载模式
    • nofail 忽略挂载时的错误,常用于可移动设备
  • dump 是一个自动备份程序,后面会使用 crontab 实现自动备份
  • fsck 是一个磁盘健康检查程序,可以自动修复错误,推荐开启,可以填写为 1

如果你在更改 fstab 文件的时候出现了问题,系统会卡死,稍等会陷入恢复模式,此时会提示你输入 root 密码,然后便可以使用 nano 或者 vim 命令编辑 fstab 文件,使用 # 临时注释掉出现问题的那一行再重启便可以正常进入系统了。

dd 命令

在 Linux 中,有个非常好用的命令 dd,这个命令可以从一个文件或者磁盘复制到另一个文件或者磁盘。

基本用法如下:

dd if=[输入文件/设备] of=[输出文件/设备]

其中 ifof 后面可以填硬盘的设备文件,也可以填写一个 .img 文件的路径。if 后还可以填写 /dev/zero,这是一个特殊的设备文件,表示一直输出 0 (需要指定复制的大小,下面会说)。

dd 命令默认不显示进度,可以通过添加 status=progress 参数显示进度。还可以切换到别的终端,使用 kill -USR1 [pid] 命令(pid 可以使用 ps -ef | grep "[你运行dd的具体命令]" 获取,从左往右第二列就是),此时 dd 命令就会显示一个进度。kill 命令后面会讲到。

下面是 dd 命令其它常用的参数:

  • bs=[块大小] 指定每次复制的大小,可使用单位如 M 等,常配合 count
  • count=[块个数] 指定复制多少块,通常可设置 bs=1M 然后个数就是以 MB(MiB) 为单位的文件大小

回环设备

我们前面提到了像 /dev/loop0 这样的设备属于回环设备。

回环设备同样需要 root 才能操作。

回环设备通常指向一个镜像文件(如 img 格式)。要操作回环设备,我们需要使用 losetup 命令。

我们可以使用下面的命令查看空闲的loop设备(这里其实还不存在对应的设备文件):

losetup -f

会返回一个设备名,然后可以使用下面的方法进行关联:

losetup [设备文件] [你的img文件]

然后,我们可以使用上面的 mount 挂载回环设备。

要查看挂载的所有设备,可以使用

losetup -a

用完记得卸载(请先 umount):

losetup -d [设备文件]

课后作业

由于这章长且十分重要,所以设置以下作业:

  1. 在虚拟机中创建一个虚拟磁盘,大小大于等于系统磁盘
  2. 给这个磁盘初始化分区表并且创建一个 xfs 分区,分区大小为整个磁盘的容量。
  3. 尝试把这个磁盘挂载到 /mnt/test
  4. 使用 dd 命令从 /dev/zero 读取,写入大小为 20MB 的空文件到 /mnt/test/hello.img
  5. 卸载这个磁盘
  6. 编辑 /etc/fstab,持久挂载这个磁盘到 /mnt/backup (以后会用到) 并重启
  7. 使用 losetup 挂载刚刚创建的 /mnt/backup/hello.img 到一个回环设备
  8. 格式化这个回环设备,并且往里写上一些留言
  9. 可以把这个制作好的 img 文件发到论坛,让其它小伙伴看看你的成果
  10. 你可以选择留下这个文件,也可以删除

study-area-cn