我们之前学习了关于硬盘的知识,并且知道了在硬盘上还有着文件系统。那么就让我们来学习在 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 兼容大部分的文件系统(前面有提到一个表格):
项目 | NTFS | exFat | ext2/3/4 | xfs |
---|---|---|---|---|
Windows 兼容性 | 好 | 好 | 不支持 | 不支持 |
Linux 兼容性 | 中 | 中 | 好 | 好 |
MacOS 兼容性 | 不支持 | 好 | 不支持 | 不支持 |
通常可以被 Linux 用作系统磁盘的文件系统格式的是:
ext2/3/4
扩展日志文件系统,是最常见的系统磁盘的文件系统,也可以用作数据磁盘。现在 ext2/3 已经用的比较少了。
xfs
一种高性能的文件系统,被 RockyLinux 等新的 Linux 发行版用作默认文件系统。
btrfs
新兴的文件系统,自带了快照和压缩等十分方便的功能,不过目前还不太稳定。
还有一些其它的被 Linux 支持的格式:
ntfs
是 Windows 上的默认文件系统,可以使用 ntfs-3g
包实现读取和写入。但是在 Linux 下有权限问题,并且不太稳定。
exfat/fat32
比较老的文件系统,在 Linux 上也需要额外的包才可以写入。
还有一些特殊用途的文件系统:
swap
交换分区,不可被用于存储数据,前面提到过。
我们要学习如何分区,那么就肯定要有一个硬盘。如果你按照上文的方法创建了虚拟机,请按照你使用的虚拟机软件,选择下面的文章完成创建虚拟磁盘的操作,然后再回到本篇继续学习。
进行分区需要具有 root
权限!
分区是一个非常危险的操作!进行操作前最好备份!如果你要调整系统磁盘分区,可以使用一个恢复镜像,例如一个 Linux 的安装磁盘或是 LiveCD。所以最好不要删除你安装系统的ISO文件(或者是U盘)!
除了下文的
parted
和fdisk
等工具,还有gdisk
(命令行)、cfdisk
(命令行,方向键交互)、gparted
等工具,本文在此不过多介绍。
parted
和fdisk
已经被绝大多数 Linux 发行版包含,你通常无需额外安装。但是可能会有少部分发行版缺少其中任何一个软件包。
下面标注有 parted 和 fdisk 的命令,表示这个命令需要在对应工具的命令行模式下执行
parted 有两种使用模式,一种是参数模式,一种是命令行模式。这两种模式区别不大,执行的命令都是相同的。下文均以命令行模式(非交互式)下的命令为展示。
# 参数模式
parted [设备文件] [你要执行的命令]
# 命令行模式
parted [设备文件]
# 然后再输入你的命令,输入完成后和终端一样需要回车
# 可使用 'quit'('q') 命令退出
parted 的命令也有两种模式:交互模式和非交互模式。
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
如前面所说,我们刚刚添加了一块硬盘,需要创建一个分区表才能进行分区。创建分区表需要使用 parted
或 fdisk
命令。
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 可以看作是
fat16
、fat32
等数据类型的总和,默认会自动选择格式。
-n
设置卷标-F [版本]
可以设置格式化的 fat
文件系统的版本,如 16
、32
等。mkfs.exfat
格式化成 exfat
-n
设置卷标mkfs.xfs
-L
设置卷标-f
强制格式化,会清空原有的分区mkfs.btrfs
-L
设置卷标-f
强制格式化btrfs 可用的参数很多,许多参数是为 raid(一种可以将多块硬盘模拟成一块的方法) 准备的,这里就不一一列举了。
分区完成后,我们可以使用 parted
或 fdisk
命令查看分区列表。
parted
print
fdisk
p
在这里我们就可以看到每个分区对应的设备文件了,一会我们要用到。
如果我们不再需要一个分区,或者分区方案有误,我们可以使用 parted
或 fdisk
命令删除分区。
parted
rm [分区号]
fdisk
d [分区号]
这里的分区号可以使用上一条查看分区列表的方式查看,其实就是 /dev/sdX@
中 @
所对应的数字(在其它类型的磁盘中是 p
后面的数字)。
parted
和 fdisk
还有一些其它的技巧,下面列举了一小部分:
parted
resizepart [分区号] [起始位置] [结束位置] # 可以修改分区的大小
rescue [起始位置] [结束位置] # 可以查找丢失的分区
更多的技巧这里就不一一列举了。
创建了分区,我们该如何访问呢?答案就是挂载。
事实上,Windows 中的C盘、D盘等盘符也是挂载的,只不过 Windows 会自动为我们完成。Windows 也同样支持挂载到一个目录。
在下面,我们称挂载的目标路径为“挂载点”。挂载点通常约定俗称使用 /mnt
目录下的子目录(挂载整个系统时除外)
mount
与 umount
命令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 | / | ext4 | rw,relatime | 0 | 1 |
UUID=XXXX | /boot | vfat | rw,relatime... | 0 | 2 |
UUID=XXXX | none | swap | defaults | 0 | 0 |
其中:
#
开头的行是注释none
defaults
默认选项ro
只读模式rw
读写模式,默认的挂载模式nofail
忽略挂载时的错误,常用于可移动设备如果你在更改 fstab 文件的时候出现了问题,系统会卡死,稍等会陷入恢复模式,此时会提示你输入 root 密码,然后便可以使用 nano 或者 vim 命令编辑 fstab 文件,使用
#
临时注释掉出现问题的那一行再重启便可以正常进入系统了。
在 Linux 中,有个非常好用的命令 dd
,这个命令可以从一个文件或者磁盘复制到另一个文件或者磁盘。
基本用法如下:
dd if=[输入文件/设备] of=[输出文件/设备]
其中 if
和 of
后面可以填硬盘的设备文件,也可以填写一个 .img 文件的路径。if
后还可以填写 /dev/zero
,这是一个特殊的设备文件,表示一直输出 0 (需要指定复制的大小,下面会说)。
dd 命令默认不显示进度,可以通过添加
status=progress
参数显示进度。还可以切换到别的终端,使用kill -USR1 [pid]
命令(pid 可以使用ps -ef | grep "[你运行dd的具体命令]"
获取,从左往右第二列就是),此时 dd 命令就会显示一个进度。kill
命令后面会讲到。
下面是 dd
命令其它常用的参数:
bs=[块大小]
指定每次复制的大小,可使用单位如 M
等,常配合 countcount=[块个数]
指定复制多少块,通常可设置 bs=1M
然后个数就是以 MB(MiB) 为单位的文件大小我们前面提到了像 /dev/loop0
这样的设备属于回环设备。
回环设备同样需要 root 才能操作。
回环设备通常指向一个镜像文件(如 img 格式)。要操作回环设备,我们需要使用 losetup
命令。
我们可以使用下面的命令查看空闲的loop设备(这里其实还不存在对应的设备文件):
losetup -f
会返回一个设备名,然后可以使用下面的方法进行关联:
losetup [设备文件] [你的img文件]
然后,我们可以使用上面的 mount
挂载回环设备。
要查看挂载的所有设备,可以使用
losetup -a
用完记得卸载(请先 umount
):
losetup -d [设备文件]
由于这章长且十分重要,所以设置以下作业:
/mnt/test
/dev/zero
读取,写入大小为 20MB 的空文件到 /mnt/test/hello.img
/etc/fstab
,持久挂载这个磁盘到 /mnt/backup
(以后会用到) 并重启losetup
挂载刚刚创建的 /mnt/backup/hello.img
到一个回环设备study-area-cn