本章系统归纳磁盘与文件系统核心知识:MBR/GPT 结构与对比、主分区/扩展分区/逻辑分区、Ext2/Ext4 文件系统逻辑结构、文件读取/创建/删除/复制/剪切过程、软链接与硬链接、虚拟文件系统(VFS)、常用管理命令(fdisk、parted、mke2fs、mount、df、du、dd 等)。文中多处分区与文件(及文件系统)的对比 (层次关系、同分区/跨分区操作、分区级 vs 文件级命令)便于区分概念。大量 Mermaid 图表 (含 emoji)辅助理解,每节附用例、使用场景与练习 。内容只增不减。
目录
- [前言:为什么 Linux 要有分区?分区与文件系统有什么区别?](#前言:为什么 Linux 要有分区?分区与文件系统有什么区别?)
- [一、MBR 主引导记录](#一、MBR 主引导记录)
- [二、MBR 与 GPT 对比](#二、MBR 与 GPT 对比)
- 三、主分区、扩展分区与逻辑分区
- [四、Ext2/Ext4 文件系统逻辑结构](#四、Ext2/Ext4 文件系统逻辑结构)
- 五、文件的读取、创建、删除、复制与剪切
- 六、软链接与硬链接
- 七、虚拟文件系统(VFS)
- 八、文件系统管理常用命令
- [九、设备文件与 mknod](#九、设备文件与 mknod)
- [十、分区挂载与 /etc/fstab](#十、分区挂载与 /etc/fstab)
- 十一、综合练习(含 11.1~11.15)
- 十二、文件系统访问控制列表(ACL)
- 十三、回环设备(Loopback)与虚拟磁盘
- 十四、压缩与归档
- [十五、第 9 章补充练习](#十五、第 9 章补充练习)
- [附录:Swap 分区创建与启用](#附录:Swap 分区创建与启用)
全章总览:从磁盘到文件(一张图串起整章)

自上而下:磁盘 → 分区表 → 分区 → 格式化 → 文件系统(inode + 块)→ 挂载 → 用户通过路径访问文件。
前言:为什么 Linux 要有分区?分区与文件系统有什么区别?
0.1 为什么 Linux 需要分区
一块裸盘就像一整间空仓库,不做任何隔断也能往里扔东西------但一旦出问题就会全部乱套。分区就是给仓库砌隔间,好处至少有以下几点:
| 原因 | 具体说明 | 举例 |
|---|---|---|
| 故障隔离 | 一个分区的文件系统损坏,不影响其他分区的数据 | /home 分区满了或损坏,/(根)仍可正常运行 |
| 空间管控 | 每个分区有独立的空间上限,防止某个目录把整盘写满 | 日志目录 /var/log 独立分区,日志暴增不会撑满根 |
| 安全策略 | 不同分区可用不同挂载选项(只读、noexec、nosuid 等) | /tmp 挂载为 noexec,禁止在临时目录执行恶意程序 |
| 备份与恢复 | 可以只备份/恢复某个分区,不需要整盘操作 | 只备份 /home(用户数据),不备份 /(系统可重装) |
| 多系统共存 | 同一块盘可以装多个操作系统,各用各的分区 | sda1 装 CentOS,sda2 装 Ubuntu,sda3 作共享数据 |
| 性能优化 | 将频繁读写的数据放在独立分区/独立磁盘上,减少 I/O 竞争 | 数据库放单独分区甚至单独磁盘 |
| Swap 需要 | Linux 的 swap(交换空间)通常需要专用分区或专用文件 | 一个 2GB 的 swap 分区用于内存不足时换页 |
最常见的 Linux 分区方案(服务器典型):
text
/ → 系统根(10~50GB)
/boot → 内核与引导文件(500MB~1GB)
/home → 用户数据
/var → 日志、邮件、数据库
swap → 交换空间(物理内存的 1~2 倍)
一句话 :分区 = 物理磁盘的"隔间",目的是隔离风险、管控空间、灵活管理。
0.2 分区与文件系统:到底有什么区别
很多初学者把"分区"和"文件系统"搞混。它们是两个层次、两个阶段的事情:
fdisk / parted
划分区
mkfs.ext4
格式化
mount
挂载
💿 裸盘
📦 分区
/dev/sda1
🔧 文件系统
ext4 / xfs
📂 挂载点
/mydata
📄 文件
/mydata/a.txt
| 对比项 | 分区(Partition) | 文件系统(File System) |
|---|---|---|
| 是什么 | 磁盘上的一段连续空间,由分区表记录起止位置 | 分区内的数据组织规则与结构(Super Block、inode 表、数据块等) |
| 类比 | 仓库里的一个隔间(只是划了一块地方) | 隔间里的货架、编号、登记簿(规定了东西怎么放、怎么找) |
| 什么时候做 | 第一步:先分区(fdisk / parted) | 第二步:再格式化(mkfs) |
| 能直接存文件吗 | 不能;裸分区只是一段空间,没有"名录"和"指针" | 能;格式化后有了 inode、目录项、数据块,才能存文件 |
| 一个分区几个文件系统 | 通常 1 对 1:一个分区一种文件系统 | 一个文件系统只在一个分区(或逻辑卷)上 |
| 可以换吗 | 分区大小可调(但不方便,通常需卸载) | 可以重新格式化为另一种文件系统(数据会丢失) |
| 查看命令 | fdisk -l、lsblk(看分区布局) |
blkid(看文件系统类型)、df -hT(看已挂载的文件系统空间) |
| 标识 | 设备名 /dev/sda1、分区类型 ID(如 83=Linux) | UUID、LABEL、类型(ext4/xfs/swap) |
一个生活类比:
- 磁盘 = 一栋大楼
- 分区 = 大楼里的房间(只是把空间隔开了)
- 文件系统 = 房间里的书架 + 索引卡(决定了书怎么分类、怎么找)
- 文件 = 书架上的一本书
你不能往一个没装书架的空房间里"按索引找书";同理,裸分区必须先格式化(装上文件系统)才能存文件。
0.3 常见误区
| 误区 | 真相 |
|---|---|
| "分区就是格式化" | 分区只是划空间;格式化才是建文件系统,两步不可跳 |
| "一块盘只能一个分区" | MBR 最多 4 主(或 3 主 + 若干逻辑),GPT 最多 128 |
| "分区越多越好" | 过多分区会使空间碎片化且管理复杂;按需划分即可 |
| "文件系统坏了就是硬盘坏了" | 文件系统损坏是逻辑层 问题(可 fsck 修复);硬盘物理坏道才是硬件层问题 |
| "ext4 和 xfs 一样,随便选" | ext4 更通用稳定、支持缩容;xfs 大容量高并发更优、不能缩容------各有所长 |
一、MBR 主引导记录
MBR(Master Boot Record) 位于硬盘的 0 柱面、0 磁头、1 扇区 ,即第一个物理扇区(LBA0),总大小 512 字节。
1.1 三部分组成
💾 MBR 512 字节
🔧 Boot Loader
446 字节
启动操作系统
📋 DPT 分区表
64 字节
4×16 字节
✨ Magic Number
2 字节
0x55AA
📦 分区项 1
📦 分区项 2
📦 分区项 3
📦 分区项 4
| 组成部分 | 大小 | 说明 |
|---|---|---|
| Boot Loader | 446 字节 | 主引导程序,负责启动操作系统;检查分区表并将控制权交给 GRUB 等引导程序 |
| DPT(Disk Partition Table) | 64 字节 | 硬盘分区表;共 4 个分区表项,每项 16 字节,记录分区数量与各分区大小 |
| Magic Number | 2 字节 | 结束标志:小端(如 Intel)为 0x55AA;用于标识 MBR 是否有效 |
1.2 分区表项结构(每项 16 字节)
| 偏移 | 长度 | 说明 |
|---|---|---|
| 0 字节 | 1 字节 | 分区状态(00H=非活动,80H=活动/启动分区) |
| 1--3 字节 | 3 字节 | 分区起始磁头号、扇区号、柱面号 |
| 4 字节 | 1 字节 | 文件系统类型(如 83H=Linux、07H=NTFS、0BH=FAT32) |
| 5--7 字节 | 3 字节 | 分区结束磁头号、扇区号、柱面号 |
| 8--11 字节 | 4 字节 | 分区起始相对扇区号(LBA) |
| 12--15 字节 | 4 字节 | 分区总扇区数 |
1.3 备份与恢复 MBR
| 使用场景 | 命令 |
|---|---|
| 🔒 备份 MBR | dd if=/dev/sda of=/root/mbr.back bs=512 count=1 |
| ♻️ 恢复 MBR(慎用) | dd if=/root/mbr.back of=/dev/sda bs=512 count=1 |
| 🔍 查看 MBR 十六进制 | hexdump -C -n 512 /dev/sda |
| 🗑️ 清除 MBR(危险) | dd if=/dev/zero of=/dev/sda bs=512 count=1 |
示例 :备份后验证 Magic Number(MBR 最后 2 字节应为 55 aa):
bash
dd if=/dev/sda of=/root/mbr.back bs=512 count=1
hexdump -C /root/mbr.back | tail -2
# 应看到最后一行为 ... 55 aa
二、MBR 与 GPT 对比
💿 磁盘分区方案
📋 MBR
传统方案
🛡️ GPT
新一代方案
最大 2.2TB
最多 4 个主分区
BIOS 引导
❌ 无校验保护
最大 18EB
最多 128 个分区
UEFI 引导
✅ CRC 校验 + 备份
| 对比项 | MBR | GPT |
|---|---|---|
| 全称 | Master Boot Record | GUID Partition Table |
| 分区表位置 | 磁盘第 1 个扇区 | 磁盘第 2 个扇区 + 末尾备份 |
| 最大磁盘容量 | 2.2TB | 18EB(约 1800 万 TB) |
| 最大分区数 | 4 个主分区(或 3 主 + 1 扩展) | 128 个(Windows 限制) |
| 数据保护 | 无 | CRC32 校验 + 备份分区表 |
| 引导方式 | BIOS(Legacy) | UEFI |
| 分区工具 | fdisk | parted / gdisk |
| 兼容性 | 所有系统 | Windows 8+、Linux、macOS |
选择建议 :磁盘 ≤ 2TB 且旧系统 → MBR;磁盘 > 2TB 或新系统 → GPT。
三、主分区、扩展分区与逻辑分区
3.1 规则概览
- 主分区 + 扩展分区 ≤ 4(受 MBR 分区表仅 4 项限制)
- 扩展分区最多 1 个
- 常见组合:三主一扩展 或 四个主分区;未分区空间无法直接使用
- 逻辑分区 从扩展分区内划分,编号从 5 开始(如 sda5、sda6...)
3.2 分区结构图
💿 磁盘 /dev/sda
📦 主分区 1
/dev/sda1
📦 主分区 2
/dev/sda2
📦 主分区 3
/dev/sda3
📂 扩展分区
/dev/sda4
📄 逻辑分区 1
/dev/sda5
📄 逻辑分区 2
/dev/sda6
📄 逻辑分区 3
/dev/sda7
磁盘"切块"直观图(一块盘从左到右的布局)
扩展分区内部
💿 一块磁盘 /dev/sda
包含
📦 sda1 主
📦 sda2 主
📦 sda3 主
📂 sda4 扩展
sda5
sda6
sda7
3.3 扩展分区与 EBR
扩展分区采用链表 形式:每个逻辑分区对应一个 EBR(扩展引导记录),其结构类似 MBR,但只使用分区表前两项------第一项描述当前逻辑分区,第二项指向下一个逻辑分区的 EBR。
示例 :一台机器上 fdisk -l 输出中,主分区为 sda1、sda2,扩展分区为 sda3,逻辑分区为 sda5、sda6(无 sda4,因 4 被扩展分区占用;逻辑从 5 开始)。
3.4 分区与文件系统、文件的关系与对比
从层次上看:物理磁盘 → 分区 → 文件系统(格式化)→ 目录与文件。分区是"容器",文件系统是"规则与结构",文件/目录是"内容"。
| 对比项 | 分区(Partition) | 文件系统(File System) | 文件 / 目录(File / Directory) |
|---|---|---|---|
| 是什么 | 磁盘上连续扇区的逻辑划分,由分区表定义 | 分区上的一种数据结构与规则,用于组织 inode、块、目录项 | 文件系统内的数据单位:元数据在 inode,数据在块;目录是特殊文件 |
| 存储位置 | 由 MBR/GPT 分区表记录(起止扇区) | 占用整个分区;Super Block、块组等都在分区内 | 占用分区内的 inode 与数据块 |
| 标识方式 | 设备名(如 /dev/sda1)、分区类型(83/8e 等) | 类型(ext4/xfs)、UUID、LABEL | 路径(如 /home/user/a.txt)、inode 号(分区内唯一) |
| 在"树"中的位置 | 本身不在目录树中;挂载后其"根"对应挂载点 | 挂载后以挂载点为根,整棵树在该分区或跨多分区 | 挂载点下的路径,可跨多个分区(不同路径在不同分区) |
| 典型操作 | 创建/删除/改类型(fdisk、parted)、不关心"文件" | 格式化(mkfs)、检查(fsck)、调参(tune2fs) | 读写、创建、删除、复制、链接(应用程序与 shell) |
| 能否直接存数据 | 不能;未格式化的分区无法以"文件"方式使用 | 能;格式化后通过挂载点以目录树形式呈现 | 能;文件存数据,目录存目录项(文件名↔inode) |
| 范围/边界 | 一块盘内分区互不重叠;分区有起止扇区 | 一个文件系统只在一个分区内(或一个逻辑卷上) | 单文件可跨多个块;inode 与块号均在同一文件系统内有效 |
小结:分区是"物理/扇区级"的划分;文件系统是分区上的"格式";文件与目录是文件系统里的"逻辑对象"。同一块盘上可有多个分区,每个分区一种文件系统;挂载后用户看到的是统一的目录树,不同路径可能落在不同分区上。
从磁盘到文件:一眼看懂两种视角
👁️ 逻辑视角(用户看到的)
🔩 物理视角(磁盘上)
挂载
挂载
挂载
💿 整块磁盘
/dev/sda
📦 分区1
sda1
📦 分区2
sda2
📦 分区3
sda3
/ 根
/home
/mydata
📄 file1.txt
📄 file2.txt
四、Ext2/Ext4 文件系统逻辑结构
一个分区在格式化为 Ext2/Ext3/Ext4 后,最前是 Boot Sector ,其后是多个 块组(Block Group)。
4.0 Inode 是什么
Inode (index node,索引节点 )是 Unix/Linux 文件系统里用来描述一个文件或一个目录 的元数据 的数据结构。可以理解为:每个文件或目录在文件系统内都对应一个 inode ,inode 里存的是"这个对象的属性与数据在哪",不存文件名(文件名在父目录的数据块里,即目录项 Dentry)。
| 项目 | 说明 |
|---|---|
| 含义 | 索引节点;文件/目录在文件系统内的"身份证"与元数据表 |
| 存什么 | 文件类型(普通文件、目录、符号链接等)、权限、大小、时间戳(atime/mtime/ctime)、所有者 UID/GID、指向数据块的指针(或 Extent);符号链接若路径很短可把路径直接存在 inode 里 |
| 不存什么 | 不存文件名 ;文件名存在父目录的数据块里(目录项:文件名 ↔ inode 号) |
| 在哪存 | 文件系统内的 Inode Table(每个块组里有一段),由 Super Block 和 GDT 定位 |
| inode 号 | 在同一文件系统内唯一 ;不同分区上可以有相同 inode 号。ls -i、stat 可查看 |
| 与 ls -l 的关系 | ls -l 里除"文件名"外的信息(权限、链接数、所有者、大小、时间)都来自 inode;文件名来自目录项 |
小结:读一个文件时,先通过路径在目录里查到"文件名 → inode 号",再根据 inode 号找到 inode,从 inode 里拿到数据块指针才能读到内容。创建文件时要分配空闲 inode、写 inode 表、在父目录里加一条"新文件名 → 新 inode 号"。
如何查看 inode :ls -i 文件名 显示 inode 号;stat 文件名 显示 inode 号及 inode 中的元数据(大小、权限、时间等)。
Inode 与文件:一张图看懂"名字在哪、数据在哪"
💾 Data Blocks
📇 Inode Table
📁 目录 /home 的数据块
查 inode 号
读数据
目录项 Dentry
──────
file.txt → inode 号 12345
Inode #12345
──────
类型: 普通文件
权限: -rw-r--r--
大小: 1024
指针 → 块 88,89,90
块 88
块 89
块 90
文件名在目录的数据块 里;inode 里是元数据 + 数据块指针;数据块里才是文件内容。
4.1 块组内部结构
🧱 块组 Block Group
⭐ Super Block
文件系统全局信息
📋 GDT
块组描述符表
🟢 Block Bitmap
块使用状态
🔵 Inode Bitmap
inode 使用状态
📇 Inode Table
文件元数据
💾 Data Blocks
文件实际数据
| 组成部分 | 说明 |
|---|---|
| Super Block | 记录整个文件系统的全局信息:inode/block 总量、使用量、剩余量及文件系统格式等;因非常重要,在每个块组都会有一份备份 |
| GDT(Group Descriptor Table) | 块组描述符表;每个块组描述符记录该块组中 inode 表起始位置、数据块起始位置、空闲 inode/块数量等;同样在各块组有备份 |
| Block Bitmap | 块位图;占一个块,每个 bit 对应本块组的一个块,1=已用,0=空闲 |
| Inode Bitmap | inode 位图;占一个块,每个 bit 表示一个 inode 是否空闲 |
| Inode Table | inode 表;每个文件/目录占一个 inode,存文件类型、权限、大小、时间戳及数据块指针等(即 ls -l 中除文件名外的信息) |
| Data Blocks | 数据块;常规文件存数据,目录存文件名与 inode 号(Dentry);符号链接若路径短可存 inode 中 |
4.2 重要说明
- 文件名与文件类型 存放在目录的数据块 中(目录项);其余元数据 (权限、大小、时间等)存放在 inode 中。
- 各分区在物理上并行 ,在逻辑上必须通过根目录形成树形结构。
4.3 Inode 与数据块指针
📇 Inode 结构
📌 直接指针 ×12
直接指向数据块
📎 一级间接 ×1
指向一个指针块
→ 256 个数据块
📎📎 二级间接 ×1
→ 64K 个数据块
📎📎📎 三级间接 ×1
→ 16M 个数据块
💾 数据块
📋 指针块
💾 数据块
- 直接指针:前 12 个指针直接指向数据块
- 一级间接:第 13 个指针指向一个块,该块再存 256 个块指针
- 二级/三级间接:用于更大文件
Ext4 引入 Extent 机制,用连续区间描述替代大量单块指针,提高大文件寻址效率。
4.4 分区与文件系统、文件层次对比(inode/块 作用范围)
- 分区:扇区连续区间,由分区表界定;一块磁盘可有多个分区。
- 文件系统:建在分区(或逻辑卷)上;Super Block、块组、inode 表、数据块都只在该分区内。
- inode 号、块号 :只在本文件系统内唯一。不同分区上的两个文件可以有相同的 inode 号;硬链接不能跨分区,就是因为 inode 不能跨文件系统引用。
| 层级 | 边界 | 典型标识 | 跨边界 |
|---|---|---|---|
| 磁盘 | 一块物理/虚拟盘 | /dev/sda、/dev/nvme0n1 | 多块盘 → 多设备 |
| 分区 | 分区表内一项(起止 LBA) | /dev/sda1、/dev/sda2 | 同盘多分区并列 |
| 文件系统 | 一个分区(或 LV) | UUID、LABEL、挂载点 | 挂载点可对应不同分区 |
| 文件/目录 | inode + 数据块(均在同一个文件系统内) | 路径、inode 号(分区内唯一) | 软链接可跨分区(存路径字符串) |
因此:复制/剪切/硬链接 若跨分区,必须做"跨文件系统"处理(复制数据或存路径);同分区内 可只改元数据(如 mv、硬链接)。
五、文件的读取、创建、删除、复制与剪切
5.1 文件操作流程总览
📖 读取文件
1️⃣ 根 inode 已知
2️⃣ 查 Inode Table → Block
3️⃣ 读 Dentry 找子目录 inode
4️⃣ 逐级直到目标文件
5️⃣ 读取数据块 ✅
✏️ 创建文件
1️⃣ Inode Bitmap 找空闲 inode
2️⃣ Inode Table 写元数据
3️⃣ Block Bitmap 分配数据块
4️⃣ 父目录 Dentry 添加记录 ✅
🗑️ 删除文件
1️⃣ 删除父目录 Dentry 记录
2️⃣ Inode Bitmap 标记未使用
3️⃣ Block Bitmap 标记未使用
⚠️ 数据未擦除,可恢复
5.2 读取文件(例如 /etc/httpd/httpd.conf)
- 根目录 inode 号已知(根自引用),查 Inode Table 得根对应 Block ,读 Dentry,得到
etc的 inode 号。 - 查 Inode Table 得
etc的 Block,读 Dentry 得httpd的 inode 号。 - 同理得到
httpd.conf的 inode 号及其数据块,最终读取内容。
"读一个文件"的路径图:从路径到数据块
Dentry: etc → inode
Dentry: httpd → inode
Dentry: httpd.conf → inode
📂 路径
/etc/httpd/httpd.conf
/ 根目录
inode → Block
etc
inode → Block
httpd
inode → Block
httpd.conf
inode → 数据块
💾 文件内容
5.3 创建文件(例如 /etc/testfile.txt)
- 在 Inode Bitmap 中找空闲 inode,在 Inode Table 中写入元数据。
- 在 Block Bitmap 中分配空闲块并标记。
- 找到父目录的数据块,在 Dentry 中增加:
testfile.txt↔ 新 inode 号。
5.4 删除文件(例如 /etc/fstab)
- 删除父目录中对应 Dentry 记录。
- Inode Bitmap 标为未使用。
- Block Bitmap 标为未使用。
⚠️ 数据并未被擦除,只是标记可复用,被新数据覆盖后才真正消失。这就是误删后仍有可能恢复的原因。
删除文件时磁盘上发生了什么(数据还在!)
删除后
目录项
a.txt 被抹掉
Inode 99
标为空闲
数据块
内容仍在
⚠️ 未擦除
🗑️ 删除前
目录项
a.txt → inode 99
Inode 99
已用
数据块
存着内容
只改"名册"和位图,数据块里的内容要等被新文件覆盖才消失,因此误删可恢复。
5.5 复制与剪切
| 操作 | 本质 | 速度 |
|---|---|---|
| 复制 | 新建文件 + 读取源数据 + 写入新块 | 与文件大小成正比 |
| 同分区剪切 | 仅修改目录项 Dentry,不搬数据 | ⚡ 极快 |
| 跨分区剪切 | 复制到目标分区 + 删除源文件 | 同复制 |
示例 :同分区内 mv /home/a.txt /home/sub/b.txt 只改 Dentry;mv /home/a.txt /mnt/backup/b.txt(/mnt/backup 为另一分区)则先复制再删源,耗时会随文件变大而增加。
5.6 同分区与跨分区操作对比
| 操作 | 同分区(同一文件系统内) | 跨分区(不同文件系统) |
|---|---|---|
| mv 剪切 | 只改父目录的 Dentry,不搬数据,瞬间完成 | 先复制到目标分区,再删除源文件,耗时为 O(文件大小) |
| cp 复制 | 新 inode + 新数据块,都在本分区内 | 新 inode + 新数据块在目标分区,需读写两边的块设备 |
| 硬链接 ln | 允许:同一 inode 多一个目录项 | 不允许:inode 号仅在本文件系统内有效 |
| 软链接 ln -s | 允许:链接文件存路径字符串 | 允许:路径可指向任意挂载点(另一分区) |
| 删除文件 | 只影响本分区 inode/块位图与目录项 | 同上(删除总是针对一个分区内的 inode) |
| df 显示 | 同一挂载点对应一个分区,df 按分区统计 | 不同路径可能对应不同分区,df 分别显示各挂载点 |
记忆要点:凡涉及"共享同一 inode"或"只改元数据不拷贝数据"的操作,都只能在同一分区内;跨分区必然涉及数据拷贝或路径引用(软链接)。
同分区 mv vs 跨分区 mv:为什么一个飞快、一个很慢
❌ 跨分区 mv:先复制再删
复制
📄 /home/a.txt
分区A
📇 inode A
💾 数据块 A
📄 /mnt/b.txt
分区B
📇 inode B
💾 数据块 B
✅ 同分区 mv:只改目录项
📄 原路径
/home/a.txt
📇 同一个 inode
同一份数据块
📄 新路径
/home/backup/a.txt
六、软链接与硬链接
6.1 软链接与硬链接对比图
🔗 软链接
读取路径
📄 源文件
📇 Inode X
→ Data Blocks
📄 软链接文件
📇 Inode Y
存路径字符串
🔗 硬链接
📄 文件名 A
📇 同一个 Inode
同一组 Data Blocks
📄 文件名 B
6.2 本质区别
| 类型 | 本质 |
|---|---|
| 软链接(符号链接) | Inode 中存的是路径字符串;大小 = 路径字符个数 |
| 硬链接 | 多个 Dentry 指向同一 inode;inode 号相同 |
6.3 创建与查看
bash
# 创建软链接(-s),可对文件或目录,可跨文件系统
ln -s inittab inittab_soft
ln -sv /home/backup/abc /home/backup/test/abc2 # 建议用绝对路径
# 创建硬链接(默认),仅文件,不能跨文件系统
ln inittab inittab_hard
# 查看 inode 与链接数
ls -li inittab inittab_hard inittab_soft
6.4 对比小结
| 特性 | 硬链接 | 软链接 |
|---|---|---|
| 对象 | 仅文件 | 文件或目录 |
| 跨文件系统 | ❌ 不可以 | ✅ 可以 |
| 链接次数 | 增加源文件链接数 | 不增加 |
| 大小 | 与源文件相同 | 等于路径字符串长度 |
| 删除源文件 | 不影响(inode 与数据仍在) | 软链接失效(悬空 ❌) |
| 链接数为 1 时再删 | 彻底删除 | - |
使用场景
| 场景 | 推荐 | 示例 |
|---|---|---|
| 多目录共享同一文件 | 硬链接 | ln /etc/hosts /tmp/hosts_link |
| 快捷方式 / 别名路径 | 软链接 | ln -s /opt/jdk-17 /usr/local/java |
| 跨文件系统引用 | 软链接 | ln -s /mnt/data/file ~/file |
| 库版本管理 | 软链接 | ln -s libfoo.so.1.2 libfoo.so |
6.5 硬链接与复制的区别
- 硬链接 :共享同一 inode + 同一数据块。修改任一即修改两者。
- 复制 :新 inode + 新数据块,仅内容相同,修改互不影响。
6.6 练习
- 创建文件
/tmp/origin.txt,写入 "hello";创建硬链接/tmp/hard.txt。用ls -li确认 inode 相同。 - 删除源文件
/tmp/origin.txt,确认/tmp/hard.txt仍可读取。 - 创建软链接
/tmp/soft.txt→/tmp/hard.txt,删除/tmp/hard.txt,观察软链接状态。
参考答案
bash
echo "hello" > /tmp/origin.txt
ln /tmp/origin.txt /tmp/hard.txt
ls -li /tmp/origin.txt /tmp/hard.txt # inode 相同,链接数 2
rm /tmp/origin.txt
cat /tmp/hard.txt # 仍输出 hello
ln -s /tmp/hard.txt /tmp/soft.txt
rm /tmp/hard.txt
ls -l /tmp/soft.txt # 闪烁或标红,软链接悬空
cat /tmp/soft.txt # 报错 No such file
七、虚拟文件系统(VFS)
👤 用户应用程序
open / read / write
🔀 VFS 虚拟文件系统
统一接口层
📦 ext4
📦 XFS
📦 NFS
📦 FAT32
📦 /proc
💾 磁盘
🌐 网络
🔌 USB
🐧 内核数据
VFS(Virtual File System) 是内核中的抽象层,运行后建立、卸载时删除,不持久存储在磁盘。
7.1 主要作用
- 统一接口:对上层提供统一的 open、read、write、stat 等,用户无需关心底层文件系统。
- 抽象差异:用统一数据结构管理不同文件系统。
- 多文件系统互访:同一套系统调用可访问不同介质。
- 对接内核子系统:如内存管理、块设备等。
7.2 核心数据结构
| 结构 | 说明 |
|---|---|
struct file |
代表打开的文件,含 f_op 指向操作方法集 |
struct inode |
文件元数据(权限、大小、所有者等) |
struct super_block |
已挂载文件系统及其元数据 |
struct dentry |
路径的一个组成部分(目录项缓存) |
struct file_operations |
操作方法集(open/read/write/close 等) |
7.3 常见文件系统类型(名称一览)
ext2、ext3、ext4、xfs、btrfs、reiserfs、jfs、FAT32(vfat)、NTFS、ISO9660、CIFS、NFS、tmpfs、proc、sysfs、ocfs2、gfs2 等。
7.4 常见文件系统类型详解(是什么 / 用来做什么 / 适用场景)
| 类型 | 是什么 | 用来做什么 | 适用场景 |
|---|---|---|---|
| ext2 | 第二代扩展文件系统,无日志 | 传统 Linux 数据存储;适合只读或对一致性要求不高的场景 | 老系统、嵌入式、U 盘等小容量只读场景 |
| ext3 | ext2 + 日志(Journal) | 在 ext2 基础上增加日志,掉电后恢复快,无需长时间 fsck | 从 ext2 升级、需要稳定性且不需 ext4 新特性的环境 |
| ext4 | 第四代扩展文件系统,ext 系列当前主流 | 大文件、大分区、延迟分配、Extent、更快的 fsck | 桌面/工作站、通用服务器;高稳定性、广泛兼容性首选 |
| xfs | SGI 开发的高性能 64 位日志文件系统 | 大文件、高并发 I/O、在线扩容(只能扩大不能缩小) | 企业级、数据库、大容量存储;RHEL/CentOS 默认根文件系统 |
| btrfs | B-Tree 文件系统,写时复制(COW) | 快照、子卷、透明压缩、去重、多设备/RAID、在线 scrub | 需要快照/备份、压缩、高级存储管理;部分发行版根文件系统 |
| vfat / FAT32 | Windows 兼容的 FAT 文件系统 | 与 Windows/U 盘/相机等交换数据;无权限、无日志 | U 盘、SD 卡、双系统共享分区、老设备兼容 |
| ntfs | Windows NT 文件系统,Linux 通过 ntfs-3g 读写 | 读写 Windows NTFS 分区;大文件、ACL、压缩 | 双系统共享数据盘、挂载 Windows 分区 |
| swap | 交换分区/文件,非普通文件系统 | 将内存页换出到磁盘,扩展"可用内存" | 物理内存不足时;休眠(hibernate)需 swap ≥ 内存 |
| tmpfs | 基于内存的临时文件系统(可部分用 swap) | 存临时文件,重启即丢;高速读写 | /tmp、/run、/dev/shm;不需要持久化的缓存、临时目录 |
| proc | 虚拟文件系统,不占磁盘 | 暴露内核与进程信息为"文件" | /proc ;查看进程、内核参数、硬件信息(如 cat /proc/cpuinfo) |
| sysfs | 虚拟文件系统,不占磁盘 | 暴露内核设备/驱动/总线等为"文件" | /sys;设备管理、udev、电源、模块等 |
| iso9660 | 光盘标准文件系统 | 挂载光盘或 ISO 镜像 | CD/DVD、.iso 镜像 (常配合 -o loop) |
| nfs | 网络文件系统(Network File System) | 通过网络挂载远程目录,多机共享 | 无状态计算节点共享存储、集群 home 目录、跨主机共享 |
| cifs/smb | Windows 网络共享协议在 Linux 上的实现 | 挂载 Windows 共享目录或 Samba 服务 | 访问 Windows 共享文件夹、NAS、Samba 服务器 |
选择建议 :通用 Linux 分区首选 ext4 或 xfs ;大容量/高 I/O 服务器倾向 xfs ;需要快照与高级特性选 btrfs ;与 Windows 或移动设备互通用 vfat/ntfs。
八、文件系统管理常用命令
8.0 命令全景图
🛠️ 磁盘管理命令
📋 分区
🔧 格式化
📌 挂载
📊 信息查看
🔩 维护
fdisk
MBR 分区
parted
GPT/MBR
gdisk
GPT 专用
mkfs
通用格式化
mke2fs
ext 专用
mkswap
Swap
mount 挂载
umount 卸载
/etc/fstab
永久挂载
df 磁盘空间
du 目录大小
blkid 设备属性
lsblk 块设备列表
fsck 检查修复
tune2fs 调参
dd 底层复制
8.0.1 命令含义速查(是什么、用来做什么)
| 命令 | 全称/含义 | 用来做什么 |
|---|---|---|
| fdisk | Fixed Disk / 分区表操作程序 | 对 MBR 磁盘进行交互式分区:查看、新建、删除、改类型 |
| parted | Partition Editor(分区编辑器) | 对 MBR/GPT 磁盘分区,支持 >2TB;操作即时生效 |
| gdisk | GPT fdisk | 专门针对 GPT 分区表的交互式分区工具 |
| mkfs | Make File System(制作文件系统) | 在分区上创建文件系统(格式化)的通用前端 |
| mke2fs | Make ext2/3/4 File System | 创建 ext 系列文件系统的专用工具 |
| mkswap | Make Swap | 将分区或文件格式化为 swap 交换空间 |
| blkid | Block ID(块设备标识) | 查看块设备的 UUID、LABEL、TYPE 等属性 |
| e2label | ext2 Label | 查看或设置 ext 系列分区的卷标 |
| tune2fs | Tune ext2 File System | 调整 ext 文件系统参数(卷标、预留、ACL、自检等) |
| dumpe2fs | Dump ext2 File System | 导出 ext 文件系统的超级块、块组描述符等详细信息 |
| fsck | File System ChecK | 检查并修复文件系统(通用接口,会调用 e2fsck 等) |
| e2fsck | ext2 File System ChecK | 专门检查/修复 ext 系列文件系统 |
| mount | Mount(挂载) | 将文件系统关联到目录树,使分区可访问 |
| umount | Unmount(卸载) | 将文件系统从目录树解除关联 |
| fuser | File USER(文件使用者) | 查看或终止正在使用某文件/挂载点的进程 |
| lsblk | LiSt BLocK devices | 以树状列出块设备及分区、挂载点 |
| df | Disk Free | 显示已挂载文件系统的磁盘空间(及 inode)使用情况 |
| du | Disk Usage | 统计文件或目录占用的磁盘空间 |
| dd | 据称来自 DD(数据定义/复制),无官方全称 | 按块复制/转换数据:备份 MBR、做镜像、写 U 盘等 |
| free | 内存与 swap 状态 | 显示物理内存与 swap 总量、已用、可用 |
| mknod | Make NODe(创建设备节点) | 创建设备文件(字符设备/块设备),需主次设备号 |
| swapon | Swap On | 启用 swap 分区或 swap 文件 |
| swapoff | Swap Off | 关闭已启用的 swap |
8.0.2 分区级与文件/文件系统级操作对比
管理磁盘时,有的命令面向分区(设备) ,有的面向已挂载的文件系统或文件,容易混淆。下表区分"分区级"与"文件/文件系统级"。
| 对比项 | 分区级(Partition / 设备) | 文件/文件系统级(Filesystem / 文件) |
|---|---|---|
| 关心对象 | 扇区划分、分区表、设备节点(/dev/sda1) | 挂载点、目录树、inode、块使用情况、单个文件大小 |
| 典型命令 | fdisk、parted、gdisk、lsblk、blkid(设备属性) | mount、umount、df、du、fsck、tune2fs、dumpe2fs |
| 查看"空间" | lsblk 看分区大小;不关心"已用/剩余" | df 看某挂载点所在分区的已用/剩余;du 看某目录下文件占用 |
| 查看"是谁" | blkid 看分区 UUID、LABEL、TYPE | ls -l、stat 看文件 inode、权限、大小;dumpe2fs 看文件系统内部 |
| 创建/删除 | 分区:fdisk n/d;不涉及"文件" | 文件系统:mkfs;文件:touch、rm、cp、mv |
| 是否需挂载 | 不需要;分区存在即可有设备文件 | 需要;未挂载则无法通过路径访问其上的文件 |
| 示例 | fdisk -l /dev/sdb 看分区布局;blkid /dev/sdb1 看分区类型与 UUID |
df -h /home 看 /home 所在分区空间;du -sh /var/log 看目录占用 |
小结:先有分区(分区级),再格式化并挂载,之后用户通过路径访问的是文件系统级;排障时"空间不足"看 df/du(文件系统级),"分区不见了"看 lsblk/fdisk(分区级)。
8.1 fdisk(MBR 分区)
是什么 :交互式 MBR 分区表操作工具,适用于 ≤ 2TB 磁盘。
| 交互命令 | 作用 |
|---|---|
m |
帮助 |
p |
显示分区表 |
n |
新建分区(p=主分区 / e=扩展分区) |
d |
删除分区 |
t |
修改分区类型(L 列出所有) |
w |
保存并退出 |
q |
不保存退出 |
| 使用场景 | 示例 |
|---|---|
| 查看磁盘分区 | fdisk -l |
| 查看指定磁盘 | fdisk -l /dev/sdb |
| 交互式分区 | fdisk /dev/sdb → n → p → 1 → 默认 → +5G → w |
| 内核重读分区表 | partx -a /dev/sdb 或 partprobe |
更多示例:
bash
# 示例 1:仅查看分区表,不进入交互(适合脚本判断)
fdisk -l /dev/sda | grep -E "^/dev"
# 示例 2:创建主分区后改为 swap 类型(82)
fdisk /dev/sdb # n → p → 2 → +2G → t → 2 → 82 → w
# 示例 3:删除第二个分区后保存
fdisk /dev/sdb # d → 2 → w
partprobe /dev/sdb
8.2 parted(GPT/MBR 通用分区)
是什么 :支持 MBR 和 GPT 的分区工具,支持 > 2TB 磁盘,操作即时生效。
| 使用场景 | 示例 |
|---|---|
| 创建 GPT 分区表 | parted /dev/sdb mklabel gpt |
| 创建分区 | parted /dev/sdb mkpart data1 xfs 1MiB 500GiB |
| 查看分区 | parted /dev/sdb print |
| 删除分区 | parted /dev/sdb rm 1 |
| 调整分区大小 | parted /dev/sdb resizepart 1 800GiB |
更多示例:
bash
# 示例 1:先看当前分区表再决定是否 mklabel
parted /dev/sdb print
# 示例 2:创建两个主分区(GPT 下可全部为主分区)
parted /dev/sdb mkpart primary ext4 1MiB 10GiB
parted /dev/sdb mkpart primary xfs 10GiB 100%
# 示例 3:给分区设置名称(GPT 支持分区名)
parted /dev/sdb name 1 mydata
⚠️ parted 操作即时生效 ,没有
w保存步骤,务必谨慎!
8.3 mke2fs / mkfs(格式化)
是什么 :创建文件系统(格式化)。mkfs 是通用前端,mke2fs 是 ext 系列专用。
| 选项 | 说明 |
|---|---|
| `-t ext2 | ext3 |
-j |
创建 ext3 |
| `-b 1024 | 2048 |
-L LABEL |
卷标 |
-m # |
预留给 root 的块百分比,默认 5% |
-i # |
每多少字节一个 inode |
-N # |
指定 inode 个数 |
-c |
创建前检查坏块 |
| 使用场景 | 示例 |
|---|---|
| 格式化为 ext4 | mkfs -t ext4 /dev/sdb1 或 mkfs.ext4 /dev/sdb1 |
| 格式化为 xfs | mkfs.xfs /dev/sdb1 |
| ext3 并设卷标 | mke2fs -j -L MYDATA /dev/sdb1 |
| ext4 低预留 | mke2fs -t ext4 -m 1 /dev/sdb1 |
更多示例:
bash
# 示例 1:格式化时指定块大小与 inode 密度(大量小文件时可增大 inode 数)
mke2fs -t ext4 -b 4096 -i 8192 -L LOGS /dev/sdb2
# 示例 2:创建前检查坏块(适合新盘或怀疑有坏道)
mke2fs -t ext4 -c /dev/sdb1
# 示例 3:格式化为 vfat(U 盘与 Windows 兼容)
mkfs.vfat -F 32 -n MYUSB /dev/sdc1
8.4 blkid(查看块设备属性)
是什么:查看块设备的 UUID、TYPE、LABEL 等属性。
| 使用场景 | 示例 |
|---|---|
| 查看所有设备 | blkid |
| 指定设备 | blkid /dev/sda1 |
| 仅 UUID | blkid -s UUID /dev/sda1 |
| 仅设备名 | blkid -o device |
| 按卷标查 | blkid -L MYDATA |
| 按 UUID 查 | blkid -U xxxxxxxx-xxxx-... |
更多示例:
bash
# 示例 1:只输出 UUID,便于写 fstab 或脚本
blkid -s UUID -o value /dev/sdb1
# 示例 2:列出所有 ext4 设备的 UUID 与挂载点
blkid -t TYPE=ext4 -o list
# 示例 3:排除某设备(如 loop)只看真实磁盘
blkid /dev/sd*
8.5 e2label(查看/设置卷标)
是什么 :专门针对 ext 系列分区查看或设置卷标(LABEL),便于用 mount -L LABEL 或 fstab 中 LABEL=xxx 挂载。
bash
e2label /dev/sdb1 # 查看
e2label /dev/sdb1 SOYSAUCE # 设置
更多示例 :设置后可用 blkid -L SOYSAUCE 或 findfs LABEL=SOYSAUCE 找到设备。
8.6 tune2fs(调整 ext 参数)
是什么:在不损坏数据的前提下调整 ext 文件系统参数。
| 选项 | 说明 |
|---|---|
-l |
显示超级块信息 |
-j |
无损 ext2 → ext3 |
-L LABEL |
修改卷标 |
-m # |
调整预留块百分比 |
-o acl |
设置默认挂载选项 |
-c # / -i # |
挂载次数/天数后自检 |
| 使用场景 | 示例 |
|---|---|
| 查看超级块 | tune2fs -l /dev/sdb1 |
| 升级 ext2→ext3 | tune2fs -j /dev/sdb1 |
| 调预留为 3% | tune2fs -m 3 /dev/sdb1 |
| 启用 ACL | tune2fs -o acl /dev/sdb1 |
更多示例:
bash
# 示例 1:每 30 次挂载或 180 天后强制自检(0 表示禁用基于时间的检查)
tune2fs -c 30 -i 180d /dev/sdb1
# 示例 2:关闭上次错误时的自动自检(避免启动时卡在 fsck)
tune2fs -E clear_fsck /dev/sdb1
# 示例 3:查看当前预留块与 inode 数
tune2fs -l /dev/sdb1 | grep -E "Block count|Inode count|Reserved"
8.7 dumpe2fs(导出文件系统信息)
是什么:导出 ext 文件系统的超级块与块组描述符等底层信息,便于排查或学习文件系统布局。
bash
dumpe2fs /dev/sdb1 # 超级块 + 块组描述符
dumpe2fs -h /dev/sdb1 # 仅超级块,不含 GDT
更多示例:
bash
# 仅看块大小与 inode 信息
dumpe2fs -h /dev/sdb1 | grep -E "Block size|Inode size|Inode count"
# 查看某个 inode 所在块组
dumpe2fs /dev/sdb1 | grep -A2 "Block group"
8.8 fsck / e2fsck(检查与修复)
是什么 :检查并修复文件系统。检查前必须先卸载。
| 使用场景 | 示例 |
|---|---|
| 自动检测并检查 | fsck /dev/sdb1 |
| 指定类型 | fsck -t ext4 /dev/sdb1 |
| 强制检查 ext | e2fsck -f /dev/sdb1 |
| 自动修复 | e2fsck -p /dev/sdb1 |
更多示例:
bash
# 示例 1:只读方式检查,不修改(-n 表示 no-op,仅报告)
e2fsck -n /dev/sdb1
# 示例 2:强制检查并自动修复,非交互(-y 对所有问题回答 yes)
e2fsck -f -y /dev/sdb1
# 示例 3:检查前先卸载,避免数据不一致
umount /mydata && e2fsck -f /dev/sdb1 && mount /dev/sdb1 /mydata
8.9 mount / umount(挂载与卸载)
是什么 :mount 将文件系统关联到目录树;umount 解除关联。
| 选项 | 说明 |
|---|---|
-a |
挂载 /etc/fstab 中所有项 |
-t FSTYPE |
文件系统类型 |
-r / -w |
只读 / 读写 |
-L LABEL / -U UUID |
按卷标/UUID 指定设备 |
-o ro,rw,remount,acl,noatime,loop |
挂载选项 |
| 使用场景 | 示例 |
|---|---|
| 基本挂载 | mount /dev/sdb1 /mnt |
| 只读挂载 | mount -o ro /dev/sdb1 /mnt |
| 重新以读写挂载 | mount -o remount,rw /mnt |
| 挂载 ISO 镜像 | mount -o loop centos.iso /mnt/iso |
| 用 UUID 挂载 | mount -U xxxxxxxx /mnt |
| 显示已挂载 | mount 或 findmnt |
| 卸载 | umount /mnt 或 umount /dev/sdb1 |
device busy 时用
lsof /mnt或fuser -v /mnt查进程;fuser -km /mnt终止后再卸载。
更多示例:
bash
# 示例 1:用卷标挂载,便于 fstab 易读
mount -L MYDATA /mydata
# 示例 2:挂载时启用 noatime(不更新访问时间,减轻 I/O)
mount -o noatime /dev/sdb1 /mydata
# 示例 3:挂载 NFS 并指定选项
mount -t nfs -o rw,soft,timeo=5 192.168.1.10:/export/data /mnt/nfs
8.10 fuser(查看/终止进程)
| 使用场景 | 示例 |
|---|---|
| 查看访问挂载点的进程 | fuser -v /mnt |
| 强制终止后卸载 | fuser -km /mnt && umount /mnt |
更多示例:
bash
# 查看占用 /mydata 的进程及 PID
fuser -v /mydata
# 仅 kill 读写的进程(-k 发送 SIGKILL)
fuser -km /mydata
umount /mydata
# 查看占用某文件的进程
fuser -v /mydata/largefile.zip
8.11 lsblk(查看块设备列表)
是什么:以树状图列出所有块设备及其挂载点。
bash
lsblk # 树状显示
lsblk -f # 包含文件系统类型、UUID、挂载点
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT
更多示例:
bash
# 只看磁盘与分区名、大小、挂载点
lsblk -o NAME,SIZE,MOUNTPOINT
# 排除 loop 设备(如 Docker 镜像)
lsblk -e 7
# 按设备名排序
lsblk -S
8.12 df(磁盘空间与 inode)
是什么 :显示已挂载文件系统的磁盘空间或 inode 使用情况。
| 使用场景 | 示例 |
|---|---|
| 空间概览 | df -h |
| inode 使用 | df -ih |
| 带文件系统类型 | df -hT |
| 仅看某目录 | df -h /home |
| POSIX 不换行 | df -P |
更多示例:
bash
# 只看本地磁盘(排除 tmpfs、nfs 等)
df -hT -t ext4 -t xfs
# 某目录所在文件系统的 inode 使用率(小文件多时易满)
df -ih /var/spool
# 人类可读且只显示"已用%"和挂载点
df -h --output=pcent,target
8.13 du(目录空间占用)
是什么:统计文件或目录实际占用的磁盘空间。
| 使用场景 | 示例 |
|---|---|
| 目录总大小 | du -sh /var/log |
| 一级子目录 | du -h --max-depth=1 /var |
| 找大目录排序 | `du -sh /var/* |
| 每个文件 | du -h /root/ |
更多示例:
bash
# 当前目录下一级子目录大小,并排序
du -h --max-depth=1 . | sort -hr
# 只统计当前目录下直接文件(不含子目录)
du -ch * 2>/dev/null | tail -1
# 找出 / 下占用最大的 5 个目录(需 root)
du -x --max-depth=1 / 2>/dev/null | sort -hr | head -6
8.14 dd(底层复制与转换)
是什么:按块复制数据,可用于备份 MBR、创建镜像、制作启动盘等。
| 参数 | 说明 |
|---|---|
if= |
输入源 |
of= |
输出目标 |
bs= |
块大小 |
count= |
读写块数 |
seek= |
输出时跳过的块数 |
| 使用场景 | 示例 |
|---|---|
| 备份 MBR | dd if=/dev/sda of=/root/mbr.back bs=512 count=1 |
| 创建 1GB 测试文件 | dd if=/dev/zero of=/tmp/1g.img bs=1M count=1024 |
| 制作 USB 启动盘 | dd if=centos.iso of=/dev/sdc bs=4M status=progress |
| 创建空洞文件 | dd if=/dev/zero of=sparse bs=1M count=1 seek=1023 |
| 擦除磁盘前 1MB | dd if=/dev/zero of=/dev/sdb bs=1M count=1 |
更多示例:
bash
# 示例 1:带进度显示(较新 dd 支持)
dd if=/dev/sda of=/backup/sda.img bs=4M status=progress conv=fsync
# 示例 2:从镜像恢复单个分区到 U 盘
dd if=system.img of=/dev/sdc1 bs=4M status=progress
# 示例 3:克隆整盘到另一块盘(两盘容量需一致,慎用)
dd if=/dev/sda of=/dev/sdb bs=4M status=progress conv=fsync
8.15 free(内存与 Swap)
bash
free -h # 人类可读
free -m # 以 MB 显示
| 字段 | 说明 |
|---|---|
| total | 总内存 |
| used | 已用 |
| free | 完全空闲 |
| buff/cache | 缓冲/缓存(可回收) |
| available | 真正可用 |
8.16 命令使用场景汇总
| 场景 | 推荐命令 |
|---|---|
| 🆕 新磁盘分区(≤2TB) | fdisk |
| 🆕 新磁盘分区(>2TB) | parted + GPT |
| 🔧 格式化 | mkfs.ext4 / mkfs.xfs |
| 📌 临时挂载 | mount |
| 📌 永久挂载 | 编辑 /etc/fstab |
| 📊 查看磁盘空间 | df -hT |
| 📊 查看目录大小 | du -sh |
| 🔍 查看设备属性 | blkid / lsblk -f |
| 🔩 调整 ext 参数 | tune2fs |
| 🩺 修复文件系统 | e2fsck -f(先卸载) |
| 💾 备份 MBR | dd |
九、设备文件与 mknod
9.1 设备类型
🔌 设备文件
📦 块设备 b
硬盘/U盘
随机访问
🔤 字符设备 c
键盘/终端
线性访问
💾 /dev/sda
⌨️ /dev/tty0
9.2 主设备号与次设备号
- 主设备号(major) :标识设备类型(驱动)。
- 次设备号(minor) :同一类型下的具体设备。
bash
ls -l /dev/sda
# brw-rw----. 1 root disk 8, 0 ... # major=8, minor=0
9.3 硬盘设备命名
| 类型 | 设备名 | 分区示例 |
|---|---|---|
| IDE | /dev/hda, hdb, hdc, hdd | hda1--hda4 主分区,hda5... 逻辑 |
| SATA/SCSI/USB | /dev/sda, sdb, ... | sda1--sda4 主分区,sda5... 逻辑 |
| NVMe | /dev/nvme0n1 | nvme0n1p1, p2... |
9.4 mknod(创建设备文件)
bash
mknod [选项] NAME TYPE [MAJOR MINOR]
| 使用场景 | 示例 |
|---|---|
| 创建字符设备 | mknod mydev c 66 0 |
| 指定权限 | mknod -m 640 mydev2 c 66 1 |
更多示例:
bash
# 查看现有设备的主次设备号再仿造(如 tty 为 5,0)
ls -l /dev/tty
# 创建设备节点(通常由 udev 自动管理,手工创建多用于测试)
mknod -m 666 /tmp/null c 1 3
十、分区挂载与 /etc/fstab
10.1 磁盘管理完整流程
≤ 2TB
> 2TB 🆕 新磁盘接入
🔍 fdisk -l / lsblk
识别磁盘
📋 分区方案?
fdisk /dev/sdb
parted /dev/sdb
mklabel gpt
🔄 partprobe
内核重读
🔧 mkfs.ext4 /dev/sdb1
📁 mkdir -p /mydata
📌 mount /dev/sdb1 /mydata
📊 df -hT 验证
📝 写入 /etc/fstab
永久挂载
🔄 重启验证
10.2 /etc/fstab 字段
| 字段 | 含义 | 示例 |
|---|---|---|
| 1 | 设备 | UUID=xxx、LABEL=xxx、/dev/sda1 |
| 2 | 挂载点 | /、/home(swap 写 swap) |
| 3 | 文件系统类型 | ext4、xfs、swap |
| 4 | 挂载选项 | defaults、acl、noatime |
| 5 | 转储频率 | 0=不备份,1=每日 |
| 6 | 自检次序 | 0=不检,1=根优先,2=次之 |
示例:
text
UUID=069d1634-... / ext4 defaults 1 1
/dev/sdb1 /mydata ext4 defaults 0 0
/dev/sdb2 swap swap defaults 0 0
更多示例:按卷标挂载、加 noatime、ACL:
text
LABEL=MYDATA /mydata ext4 defaults,noatime,acl 0 0
/swapfile swap swap defaults 0 0
10.3 查看已挂载
bash
mount # 简要
findmnt # 树状显示
cat /etc/mtab
cat /proc/mounts # 最详细
挂载前后:分区如何变成"目录里的文件"
▶️ mount /dev/sdb1 /mydata 后
⏸️ 挂载前
mount
/dev/sdb1
只是一块分区
无法用路径访问
📂 /mydata
挂载点
📄 文件A
📄 文件B
📁 子目录
挂载后,访问
/mydata/文件A就是在访问该分区内文件系统的根目录下的"文件A"。
10.4 分区、挂载点与路径对比
| 概念 | 含义 | 示例 | 用户/命令看到的是 |
|---|---|---|---|
| 分区(设备) | 磁盘上的一段连续空间,有设备文件 | /dev/sdb1 | lsblk、fdisk、blkid;无"目录树" |
| 挂载点 | 目录树上的一个目录,挂载后代表该分区的"根" | /mydata | 该目录下看到的是该分区内文件系统的根目录 |
| 路径(文件/子目录) | 挂载点下的相对路径,对应分区内的文件或目录 | /mydata/foo、/mydata/app/log.txt | 实际位于该分区内的 inode 与数据块 |
对比 :同一分区只能挂载到一个挂载点(或先卸再挂到别处);一个挂载点同一时刻只对应一个分区。路径 /mydata/a 和 /mydata/b 在同一分区上;路径 /home/user 和 /mydata 可能在不同分区上,用 df 可区分。
十一、综合练习
11.1 分区与格式化练习
- 用
fdisk -l查看系统中所有磁盘及分区。 - 对
/dev/sdb创建一个 5GB 的主分区和一个 3GB 的扩展分区(内含 2 个逻辑分区各 1.5GB)。 - 将 sdb1 格式化为 ext4,卷标为 DATA。
- 用
blkid确认 UUID 和类型。
参考答案
bash
fdisk -l
fdisk /dev/sdb # n → p → 1 → +5G → n → e → 2 → +3G → n → +1.5G → n → +1.5G → w
partprobe /dev/sdb
mke2fs -t ext4 -L DATA /dev/sdb1
blkid /dev/sdb1
11.2 挂载与 fstab 练习
- 将
/dev/sdb1挂载到/mydata,用df -hT验证。 - 以只读方式重新挂载
/mydata,尝试写入文件确认失败。 - 再重新以读写方式挂载。
- 将
/dev/sdb1写入/etc/fstab实现开机自动挂载(用 UUID)。
参考答案
bash
mkdir -p /mydata && mount /dev/sdb1 /mydata
df -hT | grep mydata
mount -o remount,ro /mydata
echo "test" > /mydata/a.txt # 报错 Read-only
mount -o remount,rw /mydata
UUID=$(blkid -s UUID -o value /dev/sdb1)
echo "UUID=$UUID /mydata ext4 defaults 0 0" >> /etc/fstab
mount -a # 验证 fstab 无误
11.3 链接练习
- 创建文件
/tmp/src.txt,写入内容。创建硬链接和软链接。用ls -li对比 inode。 - 删除源文件,分别测试硬链接和软链接是否可读。
11.4 文件系统维护练习
- 用
tune2fs -l /dev/sdb1查看 block count、inode count、block size。 - 用
dumpe2fs -h /dev/sdb1查看超级块信息。 - 卸载
/dev/sdb1,用e2fsck -f /dev/sdb1强制检查并修复。
11.5 磁盘信息练习
- 用
df -hT列出所有挂载点的文件系统类型和空间使用。 - 用
du -sh /var/*找出 /var 下最大的 3 个子目录。 - 用
lsblk -f查看所有块设备及其 UUID。
参考答案
bash
df -hT
du -sh /var/* 2>/dev/null | sort -rh | head -3
lsblk -f
11.6 dd 与 Swap 练习
- 用
dd备份/dev/sda的 MBR 到/root/mbr.bak。 - 用
dd创建一个 512MB 的全零文件/tmp/swapfile,格式化为 swap 并启用。
参考答案
bash
dd if=/dev/sda of=/root/mbr.bak bs=512 count=1
dd if=/dev/zero of=/tmp/swapfile bs=1M count=512
chmod 600 /tmp/swapfile
mkswap /tmp/swapfile
swapon /tmp/swapfile
free -h # 确认 swap 增加
swapoff /tmp/swapfile
rm /tmp/swapfile
11.7 综合实战
- 完整流程:对新磁盘 /dev/sdb 创建 10GB ext4 分区,开机自动挂载到 /mydata。
步骤:
fdisk -l查看fdisk /dev/sdb→ n → p → 1 → +10G → wpartprobe /dev/sdbmkfs.ext4 /dev/sdb1mkdir -p /mydata && mount /dev/sdb1 /mydatadf -hT验证blkid /dev/sdb1获取 UUID- 写入
/etc/fstab:UUID=xxx /mydata ext4 defaults 0 0 - 重启后
df -hT再次确认
11.8 仅用命令行完成分区+格式化+挂载
- 对一块新盘(如
/dev/sdb)仅用命令行 完成:创建一个 8GB 的 ext4 分区,卷标为BACKUP,挂载到/backup,并用df -h验证。 - 用
blkid获取该分区 UUID,写一行/etc/fstab实现开机自动挂载;执行mount -a验证无误。
参考答案
bash
# 20:分区(非交互可用 echo + fdisk 或 parted)
parted /dev/sdb mklabel msdos
parted /dev/sdb mkpart primary ext4 1MiB 8GiB
# 或 fdisk:fdisk /dev/sdb → n → p → 1 → 回车 → +8G → w
partprobe /dev/sdb
mkfs.ext4 -L BACKUP /dev/sdb1
mkdir -p /backup && mount /dev/sdb1 /backup
df -h /backup
# 21:fstab
UUID=$(blkid -s UUID -o value /dev/sdb1)
echo "UUID=$UUID /backup ext4 defaults 0 0" >> /etc/fstab
mount -a && df -h /backup
11.9 软硬链接对比实验
- 在
/tmp下创建文件base.txt,内容为 "link test"。分别创建硬链接hard.txt和软链接soft.txt。用ls -li比较三者的 inode 与链接数。 - 删除
base.txt后,分别cat hard.txt和cat soft.txt,并解释结果差异。 - 再创建软链接
soft2指向目录/etc,用ls -l soft2和ls soft2观察输出。
参考答案
bash
echo "link test" > /tmp/base.txt
ln /tmp/base.txt /tmp/hard.txt
ln -s /tmp/base.txt /tmp/soft.txt
ls -li /tmp/base.txt /tmp/hard.txt /tmp/soft.txt
# base 与 hard 的 inode 相同,链接数为 2;soft 的 inode 不同,大小为路径长度
rm /tmp/base.txt
cat /tmp/hard.txt # 仍能输出 "link test"(数据仍在)
cat /tmp/soft.txt # 报错 No such file(软链接指向已删除的路径)
ln -s /etc /tmp/soft2
ls -l /tmp/soft2 # 显示软链接本身
ls /tmp/soft2 # 显示 /etc 目录内容
11.10 dd 备份与 Swap 文件
- 用
dd将系统第一块磁盘的 MBR 备份到/root/mbr.bak,再用hexdump -C -n 64查看备份文件末尾是否包含55 aa。 - 创建一个 256MB 的 swap 文件
/swapfile(用dd或fallocate),设置权限为 600,格式化为 swap 并启用;用free -h和swapon --show验证。最后关闭并删除该 swap 文件。
参考答案
bash
# 25
dd if=/dev/sda of=/root/mbr.bak bs=512 count=1
hexdump -C -n 64 /root/mbr.bak | tail -4
# 最后应看到 1fe 处 55 aa
# 26
dd if=/dev/zero of=/swapfile bs=1M count=256
# 或:fallocate -l 256M /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
free -h && swapon --show
swapoff /swapfile && rm -f /swapfile
11.11 文件系统类型与命令含义
- 说出 ext4、xfs、swap、tmpfs、vfat 各适合什么场景;根分区一般选 ext4 还是 xfs 有何考量?
- 写出下列命令的"全称/含义"并各举一个用法:
fdisk、mkfs、mount、blkid、fsck。
参考答案
- 27:ext4 通用稳定,桌面/通用服务器;xfs 大容量、高 I/O、企业/数据库;swap 扩展内存、休眠;tmpfs 临时目录、不持久;vfat U 盘、跨平台共享。根分区:RHEL/CentOS 默认 xfs,Debian/Ubuntu 常用 ext4,两者皆可,xfs 更偏大容量与性能。
- 28 :fdisk(Fixed Disk,分区表操作)→
fdisk -l /dev/sda;mkfs(Make File System)→mkfs.ext4 /dev/sdb1;mount(挂载)→mount /dev/sdb1 /mnt;blkid(Block ID)→blkid /dev/sda1;fsck(File System ChecK)→fsck /dev/sdb1(需先卸载)。
11.12 挂载排错与 umount 忙
- 执行
umount /mydata时报 "device is busy",请写出两种查出"谁在用"的方法,以及如何在不重启的前提下卸载成功。 - 在
/etc/fstab中误写入了不存在的 UUID,导致mount -a失败。如何在不删该行的前提下临时跳过该项,使系统能正常挂载其他条目?
参考答案
bash
# 29:查占用
fuser -v /mydata
# 或
lsof /mydata
# 结束进程后卸载;若必须卸载可强制结束占用该挂载点的进程(慎用)
fuser -km /mydata
umount /mydata
# 30:挂载时跳过错误项(-a 会继续挂载其他),或先注释掉错误行再 mount -a
mount -a
# 若希望开机不挂载错误项,需编辑 fstab 注释或修正该行
11.13 df 与 du、inode 与空间
- 用命令说明:为什么有时
df显示某分区还有不少空间,但无法创建新文件?如何确认是 inode 用尽? - 在
/tmp下用一条命令创建 100 个空文件f1.txt~f100.txt,再用du -sh /tmp和df -h /tmp对比,简要说明 df 与 du 分别反映什么。
参考答案
bash
# 31:inode 用尽时会出现 "No space left on device",但 df 显示还有空间。查看 inode 使用率:
df -ih /mydata
# 若 IUse% 接近或为 100%,说明 inode 耗尽。解决:删除小文件或备份后重新格式化并增大 inode 数(-N 或 -i)
# 32
touch /tmp/f{1..100}.txt
du -sh /tmp # 统计目录下文件占用的磁盘块
df -h /tmp # 显示 /tmp 所在文件系统的总空间与剩余
# df 看的是文件系统级别;du 看的是目录下内容实际占用
11.14 多分区与挂载选项
- 一块盘上已有
/dev/sdb1(ext4,挂载在 /data1)和/dev/sdb2(xfs)。请写出将 sdb2 挂载到/data2且启用noatime的完整命令;并写一条 fstab 条目使开机自动挂载(用 UUID)。 - 用
mount -o loop挂载一个 ISO 镜像到/mnt/iso,要求只读,并写出卸载命令。
参考答案
bash
# 33
mkdir -p /data2
mount -o noatime /dev/sdb2 /data2
blkid -s UUID -o value /dev/sdb2 # 得到 UUID
# 在 /etc/fstab 添加一行(将 UUID 替换为实际值):
# UUID=xxxx /data2 xfs defaults,noatime 0 0
mount -a
# 34
mount -o loop,ro /path/to/image.iso /mnt/iso
umount /mnt/iso
11.15 综合命令组合
- 不进入 fdisk 交互,用一条命令行(可含管道)列出
/dev/sda上所有分区设备名(如 /dev/sda1)。 - 写出:将
/dev/sdb1格式化为 ext4、卷标为LOG、预留块 1%、挂载到/var/log/app并加入 fstab(用 UUID)的完整命令序列。
参考答案
bash
# 35
fdisk -l /dev/sda | grep -E '^/dev/sda'
# 36
mkfs.ext4 -L LOG -m 1 /dev/sdb1
mkdir -p /var/log/app
mount /dev/sdb1 /var/log/app
UUID=$(blkid -s UUID -o value /dev/sdb1)
echo "UUID=$UUID /var/log/app ext4 defaults 0 0" >> /etc/fstab
十二、文件系统访问控制列表(ACL)
12.1 ACL 是什么
标准 Linux 权限(owner/group/other)只能为一个所有者 和一个属组 设置权限。ACL(Access Control List) 允许为任意用户或组单独设置权限,实现更细粒度的访问控制。
12.2 查看与设置 ACL
| 命令 | 全称/含义 | 用途 |
|---|---|---|
| getfacl | Get File ACL | 查看文件或目录的 ACL |
| setfacl | Set File ACL | 设置文件或目录的 ACL |
setfacl 常用选项:
| 选项 | 说明 | 示例 |
|---|---|---|
-m |
修改(添加/更改)ACL 条目 | setfacl -m u:jerry:rw file.txt(给用户 jerry 读写权限) |
-x |
删除指定的 ACL 条目 | setfacl -x u:jerry file.txt(移除用户 jerry 的 ACL) |
-b |
删除所有 ACL 条目 | setfacl -b file.txt |
-R |
递归设置目录下所有文件 | setfacl -R -m g:dev:rwx /project |
-d |
设置默认 ACL(新建文件继承) | setfacl -d -m u:jerry:rw /shared |
12.3 示例
bash
# 查看文件的 ACL
getfacl /data/report.txt
# 给用户 jerry 对文件的读写权限
setfacl -m u:jerry:rw /data/report.txt
# 给 dev 组对目录的读写执行权限(递归)
setfacl -R -m g:dev:rwx /project
# 设置默认 ACL:在 /shared 下新建的文件自动继承
setfacl -d -m u:jerry:rw /shared
# 移除 jerry 的 ACL
setfacl -x u:jerry /data/report.txt
# 移除所有 ACL
setfacl -b /data/report.txt
注意 :文件系统必须启用 ACL 支持。ext4 默认启用;若未启用可用
tune2fs -o acl /dev/sdb1或在 mount 时加-o acl。设置 ACL 后,ls -l权限位末尾会出现+号。
十三、回环设备(Loopback)与虚拟磁盘
13.1 回环设备是什么
回环设备(loopback device) 是一种用软件模拟硬件 的机制:把一个普通文件 当作块设备来使用。典型应用:挂载 ISO 镜像、创建虚拟磁盘、用文件做 swap。
13.2 用 dd 创建虚拟磁盘文件
bash
# 创建一个 1GB 的全零文件(虚拟磁盘)
dd if=/dev/zero of=/var/disk.img bs=1M count=1024
# 创建一个稀疏文件(看起来 1GB,实际只占最后 1M)
dd if=/dev/zero of=/var/sparse.img bs=1M count=1 seek=1023
# 查看实际大小 vs 显示大小
ls -lh /var/sparse.img # 显示 1GB(逻辑大小)
du -sh /var/sparse.img # 显示 1MB(实际占用)
13.3 格式化并挂载回环文件
bash
# 格式化为 ext4
mkfs.ext4 /var/disk.img
# 用 loop 方式挂载
mount -o loop /var/disk.img /mnt/vdisk
# 验证
df -h /mnt/vdisk
# 卸载
umount /mnt/vdisk
13.4 挂载 ISO 镜像
bash
# 下载 ISO(示例)
wget http://mirror.example.com/centos.iso
# 用 loop 挂载为只读
mount -o loop,ro centos.iso /mnt/iso
# 查看内容
ls /mnt/iso
# 卸载
umount /mnt/iso
13.5 常用 mount 选项补充
| 选项 | 说明 | 示例 |
|---|---|---|
noatime |
不更新文件的访问时间戳,减少写 I/O | mount -o noatime /dev/sdb1 /data |
sync |
所有写操作同步到磁盘(慢但安全) | mount -o remount,sync /data |
async |
写操作异步(默认,快但掉电可能丢数据) | mount -o async /dev/sdb1 /data |
noexec |
禁止在该分区执行程序(安全加固) | /tmp 挂载为 noexec |
nosuid |
忽略 SUID/SGID 位(安全加固) | mount -o nosuid /dev/sdb1 /data |
loop |
挂载回环设备(把文件当块设备) | mount -o loop disk.img /mnt |
remount |
不卸载直接重新挂载(可改选项) | mount -o remount,ro /data |
示例:先 sync 方式测试性能差异
bash
# 默认 async 挂载,复制文件
mount /dev/sdb1 /data
time cp -r /etc/* /data/ # 较快
# 重新挂载为 sync,再复制
mount -o remount,sync /data
time cp -r /etc/* /data/ # 明显变慢(每次写都等磁盘确认)
十四、压缩与归档
14.1 常见压缩格式对比
| 格式 | 扩展名 | 压缩命令 | 解压命令 | 查看命令 | 特点 |
|---|---|---|---|---|---|
| gzip | .gz |
gzip file |
gunzip file.gz |
zcat file.gz |
最通用,速度与压缩比均衡 |
| bzip2 | .bz2 |
bzip2 file |
bunzip2 file.bz2 |
bzcat file.bz2 |
压缩比高于 gzip,速度较慢 |
| xz | .xz |
xz file |
unxz file.xz |
xzcat file.xz |
压缩比最高,速度最慢 |
| zip | .zip |
zip out.zip file |
unzip out.zip |
unzip -l out.zip |
跨平台兼容(Windows/Mac/Linux) |
| compress | .Z |
compress file |
uncompress file.Z |
zcat file.Z |
历史悠久,现已少用 |
通用规律:压缩比 xz > bzip2 > gzip > compress;速度正好反过来。
14.2 gzip / gunzip
bash
gzip file.txt # 压缩,生成 file.txt.gz,删除原文件
gzip -k file.txt # 压缩,保留原文件
gzip -d file.txt.gz # 解压(等同 gunzip)
gunzip file.txt.gz # 解压
zcat file.txt.gz # 不解压直接查看内容
gzip -9 file.txt # 最高压缩比(1-9,默认6)
gzip -r /var/log/ # 递归压缩目录下所有文件
14.3 bzip2 / bunzip2
bash
bzip2 file.txt # 压缩,生成 file.txt.bz2,删除原文件
bzip2 -k file.txt # 压缩,保留原文件
bzip2 -d file.txt.bz2 # 解压(等同 bunzip2)
bunzip2 file.txt.bz2 # 解压
bzcat file.txt.bz2 # 不解压直接查看内容
bzip2 -9 file.txt # 最高压缩比
14.4 xz / unxz
bash
xz file.txt # 压缩,生成 file.txt.xz,删除原文件
xz -k file.txt # 压缩,保留原文件
xz -d file.txt.xz # 解压(等同 unxz)
unxz file.txt.xz # 解压
xzcat file.txt.xz # 不解压直接查看内容
xz -9 file.txt # 最高压缩比(1-9,默认6)
14.5 zip / unzip(跨平台)
bash
zip backup.zip file1 file2 # 压缩多文件,不删原文件
zip -r html.zip /home/html/ # 递归压缩目录
unzip backup.zip # 解压到当前目录
unzip -l backup.zip # 仅查看内容列表,不解压
unzip backup.zip -d /tmp/restore # 解压到指定目录
14.6 tar(归档工具)
tar 本身只做归档 (把多个文件打包成一个 .tar),不压缩;配合 gzip/bzip2/xz 可实现"打包+压缩"。
| 选项 | 说明 |
|---|---|
-c |
创建归档 |
-x |
解开归档 |
-t |
查看归档内容(不解开) |
-f FILE |
指定归档文件名(必须紧跟文件名) |
-v |
显示过程 |
-z |
调用 gzip 压缩/解压(.tar.gz) |
-j |
调用 bzip2 压缩/解压(.tar.bz2) |
-J |
调用 xz 压缩/解压(.tar.xz) |
-C DIR |
解压到指定目录 |
--xattrs |
保留扩展属性(含 ACL) |
常用组合:
bash
# 归档(不压缩)
tar -cf archive.tar file1 file2 dir/
# 归档 + gzip 压缩
tar -zcf backup.tar.gz /etc/
# 归档 + bzip2 压缩
tar -jcf backup.tar.bz2 /etc/
# 归档 + xz 压缩
tar -Jcf backup.tar.xz /etc/
# 查看归档内容
tar -tf backup.tar.gz
# 解压到当前目录
tar -xf backup.tar.gz
# 解压到指定目录
tar -xf backup.tar.gz -C /tmp/restore
# 解压 bzip2 归档
tar -jxf backup.tar.bz2 -C /tmp/
# 保留 ACL 等扩展属性
tar --xattrs -zcf backup.tar.gz /data/
14.7 压缩与归档命令速查
📦 压缩与归档
🗜️ 压缩(单文件)
📋 归档(多文件打包)
gzip / gunzip
.gz
bzip2 / bunzip2
.bz2
xz / unxz
.xz
tar
.tar
tar -zcf
.tar.gz
tar -jcf
.tar.bz2
tar -Jcf
.tar.xz
zip / unzip
.zip
压缩+归档一体
十五、第 9 章补充练习
15.1 ACL 练习
- 在
/data目录下创建文件report.txt,用 ACL 给用户jerry设置读写权限,用getfacl验证;再移除该 ACL。
参考答案
bash
touch /data/report.txt
setfacl -m u:jerry:rw /data/report.txt
getfacl /data/report.txt # 应看到 user:jerry:rw-
setfacl -x u:jerry /data/report.txt
getfacl /data/report.txt # jerry 的条目已消失
15.2 回环设备与挂载选项练习
- 用
dd创建一个 200MB 的文件/var/vdisk.img,格式化为 ext4,用 loop 方式挂载到/mnt/vdisk,复制/etc到其中,验证后卸载。 - 将一个分区重新挂载为
noatime,用stat观察读取文件后 atime 是否变化;再重新挂载为sync,复制文件感受性能差异。
参考答案
bash
# 38
dd if=/dev/zero of=/var/vdisk.img bs=1M count=200
mkfs.ext4 /var/vdisk.img
mkdir -p /mnt/vdisk
mount -o loop /var/vdisk.img /mnt/vdisk
cp -r /etc/* /mnt/vdisk/
df -h /mnt/vdisk
umount /mnt/vdisk
# 39
mount -o remount,noatime /mydata
stat /mydata/somefile # 记下 atime
cat /mydata/somefile > /dev/null
stat /mydata/somefile # atime 不变
mount -o remount,sync /mydata
time cp -r /etc/* /mydata/ # 明显慢于 async
15.3 压缩与归档练习
- 用
tar -zcf将/etc打包压缩为/tmp/etc_backup.tar.gz,用tar -tf查看内容,再解压到/tmp/restore/。 - 分别用 gzip、bzip2、xz 压缩同一个文件(如
/var/log/messages的副本),对比压缩后文件大小和压缩耗时,说明三者区别。
参考答案
bash
# 40
tar -zcf /tmp/etc_backup.tar.gz /etc/
tar -tf /tmp/etc_backup.tar.gz | head -20
mkdir -p /tmp/restore
tar -xf /tmp/etc_backup.tar.gz -C /tmp/restore/
ls /tmp/restore/etc/
# 41
cp /var/log/messages /tmp/test_gz
cp /var/log/messages /tmp/test_bz2
cp /var/log/messages /tmp/test_xz
time gzip /tmp/test_gz
time bzip2 /tmp/test_bz2
time xz /tmp/test_xz
ls -lh /tmp/test_gz.gz /tmp/test_bz2.bz2 /tmp/test_xz.xz
# xz 最小、bzip2 次之、gzip 最大;速度反之
15.4 综合实战(来自第 9 章原题)
- 创建一个 2G 的分区,文件系统为 ext2,卷标为 DATA,块大小为 1024,预留 8%;挂载至
/backup,用卷标挂载并启用 ACL;将其升级为 ext3(不损坏数据);调预留为 3%;以 noatime 重新挂载后验证;强制检查文件系统。
参考答案
bash
# 分区(假设 /dev/sdb 有空间)
fdisk /dev/sdb # n → p → 1 → +2G → w
partprobe /dev/sdb
# 格式化
mke2fs -b 1024 -L DATA -m 8 /dev/sdb1
# 挂载(卷标 + ACL)
mkdir -p /backup
mount -o acl -L DATA /backup
# 或先 tune2fs -o acl /dev/sdb1 再 mount -L DATA /backup
# 复制测试数据
cp -r /etc/* /backup/
# 升级 ext2 → ext3(不丢数据)
umount /backup
tune2fs -j /dev/sdb1
mount -L DATA /backup
# 调预留 3%
tune2fs -m 3 /dev/sdb1
# noatime 重新挂载
mount -o remount,noatime /backup
stat /backup/inittab
cat /backup/inittab > /dev/null
stat /backup/inittab # atime 不变
# 强制检查
umount /backup
e2fsck -f /dev/sdb1
附录:Swap 分区创建与启用
Swap 管理流程
🆕 创建分区
fdisk → type 82
🔧 mkswap
格式化为 swap
✅ swapon
启用
📊 free -h
验证
📝 /etc/fstab
永久启用
bash
# 分区后格式化为 swap
mkswap -L MYSWAP /dev/sdb2
# 启用 / 关闭
swapon /dev/sdb2
swapoff /dev/sdb2
# 查看
free -h
swapon --show # 详细 swap 信息
# 用文件做 swap(无需分区)
dd if=/dev/zero of=/swapfile bs=1M count=1024
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
在 /etc/fstab 中永久启用:
text
/dev/sdb2 swap swap defaults 0 0
# 或文件 swap:
/swapfile swap swap defaults 0 0
文档版本 : v3.0
最后更新: 2026-02-13