—
type: learning-note
title: Linux:FHS 文件系统层次
date: 2026-09-18
description:FHS(文件系统层次标准):定义与为什么需要、man hier 怎么查、根目录 22 条目 =19 标准 +3 本机私货、六个重点目录(/etc /var /usr /proc /home /bin)、软链接与 UsrMerge、ls -l「大小」列的四种含义
—
# 2026-09-18 学习笔记
> 📌 我的 GitHub:https://github.com/AR-firefly
## 笔记区
### 核心观点
**FHS = Filesystem Hierarchy Standard(文件系统层次标准)**
它规定的是**具体的东西**:`/` 底下该有哪些目录、每个目录放什么。
⚠️ 不是"规定了文件系统、层次、标准这三个词"——那三个词是**名字在描述它自己**:
| 词 | 意思 | 说的是 |
| ———- | ———- | —————————— |
| Filesystem | 文件系统 | 管哪个领域 |
| Hierarchy | 层次、层级 | 怎么组织(树形) |
| Standard | 标准 | 什么性质(大家约定好用同一套) |
**"文件系统"这个词有两层意思**(今天只用第一层):
| 层 | 指什么 | 什么时候学 |
| — | ————————————- | —————- |
| 1 | 从 `/` 开始的那一整棵**目录树** | 今天 |
| 2 | 文件在**磁盘上**的组织格式(ext4 等) | 第 2 天(inode) |
### 为什么要 FHS
**秦始皇统一度量衡**——统一之前,各国尺子长短不一,同一个"三尺"到哪都不是一回事。
FHS 之前也是这样:同样是"配置放哪",各家发行版各写各的。统一之后:
– 脚本、软件换台机器不用重写
– 人换系统不用重新学"东西在哪"
**不统一会出的具体乱子**:你写了个脚本 `cat /var/log/syslog | grep ERROR`,在**自己这台**跑通了;发给同学,他的发行版把日志放在别处,脚本立刻死:
```
cat: /var/log/syslog: No such file or directory
```
**脚本没错、也没坏,就是"东西不在那个位置"。**
### 根目录全景:22 条目 = 19 标准 + 3 私货
```
ls / 的 22 个条目:
bin boot dev etc home init lib lib64 lost+found media mnt opt
proc root run sbin snap srv sys tmp usr var
```
| 类别 | 数量 | 是谁 |
| ————————– | —— | ————————————————————————————————————————————————– |
| **FHS 规定的标准目录** | **19** | `/bin` `/boot` `/dev` `/etc` `/home` `/lib` `/lost+found` `/media` `/mnt` `/opt` `/proc` `/root` `/run` `/sbin` `/srv` `/sys` `/tmp` `/usr` `/var` |
| **本机特有的**(FHS 没有) | **3** | `/init`(WSL 的启动程序,**是文件不是目录**)· `/lib64`(软链接→`usr/lib64`)· `/snap`(Ubuntu 的 snap 包系统) |
**怎么知道那 3 个是"私货"**:`man hier` 里**查不到它们**。19 vs 22 差出来的,就是不遵守 FHS 的"本地加料"。
> **`/lost+found` 是标准目录,不是私货**。`man hier` 里有它:
> `This directory contains items lost in the filesystem.` —— 文件系统出问题后,fsck 找回的碎片放进这里。
### 关键方法/流程
**① 查一个目录是干什么的 —— 三步走**
| 步 | 怎么做 | 它能告诉你什么 |
| — | ——————– | ———————————————————– |
| 1 | 在 `man hier` 里搜它 | **是标准目录** → 直接给你官方定义 |
| 2 | **搜不到** | 这个"搜不到"**本身就是关键信息**:它**不是 FHS 标准目录** |
| 3 | `ls` 进去看 | 看到的是「**这台机器实际**放了什么」——辅助,替代不了第 1 步 |
⚠️ **"查不到"要再往下分一层**:`man hier` 没有 ≠ "只有你一台有"。`/snap` 是**所有 Ubuntu 都有**、`/init` 是**所有 WSL 都有**。要问"它是谁的",得**另外查**。
**② 查 FHS 本身**:`man hier`
```
hier(7) Miscellaneous Information Manual
NAME
hier – description of the filesystem hierarchy
```
– `hier` = hierarchy 砍掉后半截(man 文档的名字都很短)
– `(7)` = man 手册的**章节号**(7 = 杂项 / 约定类)
– `description` = 描述、说明
– `of the filesystem hierarchy` = "文件系统层次结构的"
**退出**:按 `q`(quit)。`man` 用的阅读器和 `less` 是同一个,不按 `q` 会卡在里面出不来。
**③ `man` 的三种用法**(分情况,不是一律 `man`)
| 你不认识的是 | 用什么查 | 例子 |
| ———— | ————————————– | ————– |
| **顶级目录** | `man hier` | `man hier` |
| **命令** | `man 命令名` | `man ls` |
| **配置文件** | `man 5 名字`(**第 5 节** = 文件格式) | `man 5 passwd` |
**边界**:`man hier` **只管 FHS 列出的目录**。`/snap` 那种私货,`man hier` 和 `man snap` 都查不到——得去查发行版文档。**没有任何一个命令能查所有东西。**
**④ 管道的复用**:`man hier | grep "/srv"`
– `man hier` = 打开文档
– `|` = 管道:把左边命令的输出当作右边命令的输入
– `grep "/srv"` = 挑出含 `/srv` 的行
⚠️ **`grep` 是模糊匹配**,会多命中:`man hier | grep "/opt"` 实际输出 **5 行**(涉及 3 个目录条目:`/opt`、`/etc/opt`、`/var/opt`——后两个的**说明行**里也含 `/opt` 三个字符);`grep "/run"` 输出 **3 行**(`/run`、`/var/run`)。要精确匹配得再加条件(**没学,用到再说**)。
### 六个重点目录速查
| 目录 | 放什么 | 我的一句话 |
| ———— | ———————————- | ————————————————– |
| `/etc` | **配置**(基本不变) | 里面的东西就是配置,**不管有没有 `.conf` 后缀** |
| `/var` | **可变数据**(日志等,一直涨) | "啥杂七杂八的都往里面送"——**磁盘满先查这** |
| `/usr` | **发行版给的软件**(可共享、只读) | 谁装同版本 Ubuntu 都有,**一模一样** |
| `/usr/local` | **本机专属的程序**(自己装的) | "大家都有的" vs "我独有的"——**`local` = 本机独有** |
| `/proc` | **内核窗口**(伪文件系统) | 不占磁盘,里面是**内核实时生成**的 |
| `/home` | **家目录**(FHS 里标 optional) | 每个用户的私人空间 |
| `/bin` | **命令**(系统修复时也要能用) | 它是**软链接**,指向 `/usr/bin` |
**几条原文依据**(`man hier`):
– `/etc`:`Contains configuration files which are local to the machine.` —— `local to the machine` = **本机专属**
– `/var`:`This directory contains files which may change in size, such as spool and log files.`
– `/var/log`:`Miscellaneous log files.`
– `/usr`:`It should hold only shareable, read-only data, so that it can be mounted by various machines running Linux.`
– `/usr/local`:`This is where programs which are local to the site typically go.`
– `/lost+found`:`This directory contains items lost in the filesystem.`
– `/proc`:`This is a mount point for the proc filesystem, which provides information about running processes and the kernel.` + `This pseudo-filesystem …`
– `/home`:`… The structure of this directory depends on local administration decisions (optional).`
– `/bin`:`This directory contains executable programs which are needed in single user mode and to bring the system up or repair it.`
**为什么这么分**:
– `/etc` vs `/var` → 按「**变不变**」劈开(配置不动 / 日志一直涨)
– `/usr` → 按「**可共享、只读**」来(多台机器共用一份)
– `/bin` → 按「**系统快死了也得能用**」来(单用户模式 / 修复时要用)
### 软链接与 UsrMerge
**`ls -l` 里的 `->` = 软链接**。左边是它自己,右边是它**指向的目标**:
```
/bin -> usr/bin 大小 7 ← 'usr/bin' 是 7 个字符
/lib -> usr/lib 大小 7
/lib64 -> usr/lib64 大小 9
/sbin -> usr/sbin 大小 8
```
**UsrMerge(merged-/usr)**:原来 `/bin` `/sbin` `/lib` 是**独立目录**,后来被合并进 `/usr`,**原位换成软链接**。
**为什么要合并**:`/` 和 `/usr` 分开被认为**冗余**;管理更简单、容器/沙箱更好用。
**老路径为什么还能用**:**只要软链接还在,`/bin/ls` 就照样能用**——这就是"兼容性保留"。
### `ls -l`「大小」那一列:含义随类型变
| 类型 | 那一列是 | 例子 |
| ————– | ———————————– | ———————————— |
| **普通文件** | **内容的字节数** | `/etc/passwd` = 1476 |
| **目录** | 目录项占用的**块大小**(通常 4096) | `/etc` = 4096 |
| **软链接** | **目标路径字符串的字符数** | `/bin` = **7**(`usr/bin` 7 个字符) |
| **伪文件系统** | **0** —— 它不存磁盘 | `/proc` = 0、`/sys` = 0 |
**所以**:"大小 = 0"**不等于**"空";"大小 = 7"**不等于**"7 字节内容"。**这一列的含义取决于文件类型。**
### 实战记录
**根目录**
– `ls /` → 22 个条目(见上)
– `ls -l /` → `dr-xr-xr-x 321/313/323 root root 0 … proc` —— **同一台机器跑三次,那个数字三次都不同**(321 → 313 → 323),因为 `/proc` 是**实时**的
**六个目录**
– `ls /etc | head -20` → 169 项,`/etc/passwd` `/etc/group` `/etc/shadow` 的修改时间都是 **Sep 17**(= 我建组建用户那天)
– `ls /var` → 13 项;`ls /var/log | head -12` → 27 项;`/var/log/syslog` 有 **519602 字节**
– `ls /usr` → 10 项;`ls /usr/local` → 10 项。**注意:`/usr/local/bin` 是空的,但 `/usr/local/lib` 里有 `python3.14`、`/usr/local/share` 里有 5 项**——不是"全空"
– `dpkg -S /usr/bin/ls` → `coreutils-from-uutils: /usr/bin/ls`;`ls /usr/bin | wc -l` → **905**
– `ls /proc | head -15` → 前 15 全是数字(**PID**);`cat /proc/version` → `Linux version 6.18.33.2-microsoft-standard-WSL2 …`
– `ls /home` → `ar-26710` `s1tester2`(**没有 `s1tester`**——因为它当年是用不带 `-m` 的 `useradd` 建的)
– `echo $HOME` → `/home/ar-26710`;`echo ~` → 一样
– `ls /bin | wc -l` → **905**;`ls /usr/bin | wc -l` → **905**(**同一个目录**)
**软链接**
– `ls -ld /bin` → `lrwxrwxrwx … 7 /bin -> usr/bin`
– `readlink /bin` → `usr/bin`
– `ls -li /bin/ls /usr/bin/ls` → **inode 号都是 1935**(同一个文件)
– `ls -di /bin/ /usr/bin/` → **1471 / 1471**(加斜杠强制跟随,证明是同一个目录)
**/mnt(WSL 招牌)**
– `ls /mnt` → `c` `d` `wsl` `wslg` —— **Windows 的 C 盘 D 盘挂在这儿**
– `ls "/mnt/d/学习/AI学习计划"` → 能看到 `CLAUDE.md`、`kb`、`总学习路径` 等 **18 项**
– Windows 路径 `D:\\学习\\AI学习计划` ↔ WSL 路径 `/mnt/d/学习/AI学习计划`
### 踩的坑
| 现象 | 什么情况 | 怎么处理 |
| ———————————————————————- | ——————————————————————– | ————————————————————————————————————————————- |
| `du -sh /proc` 报一堆 `Permission denied` | `/proc` 里混着大量**只有 root 能读**的东西(如 `/proc/1/task/1/fd`) | **报错是正常的**。加 `2>/dev/null` 把报错扔掉:`du -sh /proc 2>/dev/null` → `0` |
| `ls` 里中文名显示成 `''$'\\345\\207\\272\\351\\242\\230\\345\\215\\225''.json'` | 那是**八进制字节码**,解出来就是「出题单」。文件**没坏**,是显示方式 | 同一项在 UTF-8 locale 下正常显示为 `出题单.json`。名字带**空格**的会被加单引号(`'harness engineering'`),那是**方便你复制回命令行** |
| `ls -di /bin` 显示 inode `13`,和 `/usr/bin` 的 `1471` 不一样 | `ls -di` 对软链接显示**链接自己**,**不跟随**目标 | 要看目标就**加斜杠**:`ls -di /bin/`;或用 `stat -L` |
**新学的两个输出通道概念**:
| 通道 | 编号 | 装什么 |
| ————— | —– | ——– |
| 标准输出 stdout | **1** | 正常结果 |
| 标准错误 stderr | **2** | 报错信息 |
`2>/dev/null` = 把**报错**扔掉(`/dev/null` 是黑洞设备,写进去就消失)。
—
## 线索区(学完后合上材料,自问自答)
**Q: FHS 这个缩写里,"Standard" 说明它是什么性质的东西?**
A: **大家约定好用同一套**的规范,不是"建议"。它规定的是**具体内容**:`/` 底下有哪些目录、每个目录放什么。
**Q: 你怎么知道 `/snap` 不是 FHS 标准目录?**
A: `man hier` 里**没有它**。"**查不到**"本身就是答案,不是"没查到"。
**Q: `man hier` 查不到,就说明只有我这台有吗?**
A: **不是**。只能说明"**它不属于 FHS 标准**"。它是"谁的"还要再分:`/snap` 是**所有 Ubuntu 都有**、`/init` 是**所有 WSL 都有**,跟"只有你一台有"是两回事。
**Q: `/lost+found` 是私货吗?**
A: **不是**,它是 **FHS 标准目录**。`man hier` 里写着 `This directory contains items lost in the filesystem.`
**Q: 在 `/etc` 里看到一个没有后缀的文件 `foo`,怎么判断它是不是配置?**
A: **看它在哪,不看它长什么样**。`/etc` 的定义就是 `Contains configuration files`——进了这个门,里面的就是配置。
**Q: `man hier | grep "/opt"` 会出几行?为什么?**
A: 你的机器上出 **5 行**。因为 `grep` 是**模糊匹配**——**含有** `/opt` 就命中,不管在哪个位置。命中的 5 行涉及 3 个目录条目(`/opt`、`/etc/opt`、`/var/opt`),后两个的**说明行**里也含 `/opt`。
**Q: `/usr` 和 `/usr/local` 的区别?**
A: `/usr` = **发行版给的**(谁装同版本 Ubuntu 都有,一模一样);`/usr/local` = **本机独有的**(你自己装的,别人的机器没有)。
**Q: 为什么 `du -sh /proc` 显示 0?**
A: 因为 `/proc` 是**伪文件系统**——里面的内容是**内核实时生成的**,不存在磁盘上。
**Q: `ls -l` 里 `/bin` 那行的「大小」是 7。这个 7 是什么?**
A: 是**目标路径字符串的长度**——`/bin` 指向 `usr/bin`,`usr/bin` 正好 **7 个字符**。软链接自身存的**只有"指向哪个路径"这个字符串**,它根本不知道目标文件多大。
**Q: `/bin` 和 `/usr/bin` 是一个目录还是两个?**
A: **一个**。`/bin` 是软链接指向 `/usr/bin`。证据:两个路径的 inode 号都是 **1471**(加斜杠强制跟随后)。
**Q: `/mnt` 和 `/media` 分别管什么?**
A: `/media` = **可移动介质**(U 盘、CD/DVD),系统自动挂;`/mnt` = **临时挂载**,多半人手动挂。WSL 把你的 Windows C/D 盘挂在 `/mnt/c`、`/mnt/d`。
—
## 总结(50字以内,用自己的话概括今天学到了什么)
看懂 Linux 目录树:22 个顶级条目里 19 个是 FHS 标准;会查(`man hier`);分清六个重点目录各放什么;软链接是"指路牌"(`/bin` → `/usr/bin`);`ls -l` 的「大小」列含义随类型变。
—
## 复习卡片
| 概念 | 一句话 | 我的场景 |
| ———————— | ————————————————- | ———————————– |
| FHS | 规定 `/` 底下有哪些目录、各放什么 | 判断一个目录该放什么 |
| `man hier` | 系统自带的 FHS 说明书 | 查任何标准目录 |
| `hier(7)` 的 `(7)` | man 的章节号(7=杂项) | 读 man 页标题 |
| `man 5 passwd` | 查**配置文件格式**用第 5 节 | 查 `/etc/passwd` 的字段定义 |
| `q` | 退出 man / less | 卡在文档里出不来 |
| 22 vs 19 | 19 = FHS 标准,多的 **3** 个是本机私货 | 认出 `/snap` `/init` `/lib64` |
| `/init` `/lib64` `/snap` | 3 个本机私货:WSL / 软链接 / Ubuntu | 它们 `man hier` 查不到 |
| `/lost+found` | **是标准目录**,不是私货 | 装 fsck 找回的碎片 |
| "查不到" | = **不属于标准**,不是"没查到" | 判断陌生目录 |
| `/etc` | 配置,**基本不变** | 改配置去这 |
| `.conf` 后缀 | **不是**判断依据,**位置**才是 | `/etc/bash.bashrc` 没有后缀也是配置 |
| `/var` | **可变数据**,日志在这,**一直涨** | 磁盘满先查这 |
| `/var/log` | 日志目录(27 项) | 排查看日志 |
| `/usr` | **发行版给的**软件,可共享只读 | `/usr/bin` 有 905 个命令 |
| `/usr/local` | **本机独有**的软件 | `bin` 空,但 `lib`/`share` 有内容 |
| `local` 的含义 | "**本机专属**",不是"本地 vs 远程" | 别理解成"本地电脑" |
| `/proc` | **内核窗口**,伪文件系统,不占磁盘 | 看进程、看内核信息 |
| PID | 进程号,`/proc` 下每个数字目录 = 一个进程 | `ls /proc` 那一堆数字 |
| `/home` | 家目录,FHS 里标 **optional** | 用户的私人空间 |
| `$HOME` / `~` | "我家在哪",两者等价 | `echo ~` → `/home/ar-26710` |
| `/bin` | 命令,**系统修复时也要能用**的那批 | 905 个,且是软链接 |
| 软链接 | "**指路牌**":自身只存目标路径 | `ls -l` 里的 `->` |
| `readlink` | 直接打印软链接指向哪 | `readlink /bin` → `usr/bin` |
| UsrMerge | `/bin` `/sbin` `/lib` 合并进 `/usr`,原位留软链接 | 为什么 `/bin` 是箭头 |
| 软链接的权限 | 永远是 `rwxrwxrwx`,**不生效**(看目标的) | `lrwxrwxrwx` 那 9 位 |
| `l` 开头 | `ls -l` 第一位 = **软链接**(`-`文件 `d`目录) | 读 `ls -l` 第一列 |
| 「大小」列(软链接) | = **目标路径的字符数** | `/bin` = 7(`usr/bin` 7 字符) |
| 「大小」列(目录) | = **4096**(块大小),不是内容大小 | `/etc` = 4096 |
| 「大小」列(伪文件系统) | = **0** | `/proc` `/sys` |
| `/mnt` | 临时挂载点;WSL 把 Windows 盘挂这 | `/mnt/d/学习/AI学习计划` |
| `/media` | 可移动介质(U 盘/CD),系统自动挂 | 你的机器上是空的 |
| stdout / stderr | 输出 1 / 报错 2,两个通道 | `2>/dev/null` 扔报错 |
| `2>/dev/null` | 把报错丢掉 | `du -sh /proc 2>/dev/null` |
| **数数的筛子** | 先检查你的匹配模式能不能罩住全部 | `grep -cE '^ /[a-z]+ '` 漏了 `-` |
—
## 旧知识回收(今天暴露出来的)
| 概念 | 一句话 | 出处 |
| —————————– | —————————————————————————- | ————- |
| `useradd` 不带 `-m` | **不建家目录**,只往 `/etc/passwd` 登记 | 09-17 第 6 天 |
| "登记表 ≠ 实物" | `/etc/passwd` 写着 `/home/s1tester`,但 `/home` 里没有它 | 09-17 第 6 天 |
| `-m` 是否生效看 `CREATE_HOME` | 这个开关在 `/etc/login.defs`,不是命令自带的 | 09-17 第 6 天 |
| `/etc/skel` | 家目录的**模板**,`-m` 建家时把里面的文件复制过去 | 09-17 第 6 天 |
| `usermod -G`(不带 `a`) | **顶掉**原有附加组;`man usermod`:`the user will be removed from the group` | 09-17 第 6 天 |
| `-g` / `-G` | 小写改**主组**,大写改**附加组** | 09-17 第 6 天 |
| `ls -l` 9 位权限 | 前 1 位是**类型**,后 9 位才是**权限** | 09-07 第 2 天 |
| `grep` 参数顺序 | `grep 要找的 从哪找`,反了报 `No such file` | 09-09 第 4 天 |
| 管道 `\\|` | 左边的输出当右边的输入 | 09-09 第 4 天 |
| `head -20` | 只要前 20 行 | 09-09 第 4 天 |
| `dpkg` | Debian 系底层包管理器(`apt` 是它的前端) | 今天新学 |
网硕互联帮助中心



评论前必须登录!
注册