文件系统与目录结构
问题
请介绍 Linux 文件系统的核心概念,包括 FHS 标准、inode 机制、文件类型和挂载。
答案
FHS 文件系统层次标准
FHS(Filesystem Hierarchy Standard)定义了 Linux 目录结构的标准,所有主流发行版都遵循:
重要目录详解
| 目录 | 用途 | 运维常用场景 |
|---|---|---|
/etc | 系统配置 | 修改 nginx.conf、sshd_config、fstab |
/var/log | 系统日志 | 查看 syslog、messages、secure、nginx 日志 |
/proc | 内核信息(虚拟) | cat /proc/cpuinfo、/proc/meminfo、/proc/[pid]/ |
/sys | 设备信息(虚拟) | 查看/修改设备属性、内核参数 |
/dev | 设备文件 | /dev/sda(磁盘)、/dev/null、/dev/zero |
/tmp | 临时文件 | 默认 10 天清理(systemd-tmpfiles) |
/opt | 第三方软件 | 安装 Java、Elasticsearch 等 |
/usr/local | 本地编译安装 | ./configure --prefix=/usr/local/xxx |
/proc 的常用文件
# CPU 信息
cat /proc/cpuinfo
# 内存信息
cat /proc/meminfo
# 系统负载
cat /proc/loadavg
# 内核版本
cat /proc/version
# 网络连接
cat /proc/net/tcp
# 进程信息
ls /proc/1/ # PID 为 1 的进程(通常是 systemd)
cat /proc/1/cmdline
cat /proc/1/status
cat /proc/1/fd/ # 文件描述符
inode 机制
inode(Index Node)是 Linux 文件系统的核心数据结构,存储文件的元数据:
inode 的关键特性
# 查看文件的 inode 信息
stat /etc/passwd
# 输出:
# File: /etc/passwd
# Size: 2654 Blocks: 8 IO Block: 4096 regular file
# Device: fd00h/64768d Inode: 67134976 Links: 1
# Access: (0644/-rw-r--r--) Uid: (0/root) Gid: (0/root)
# Access: 2026-03-15 10:00:00
# Modify: 2026-03-10 08:30:00
# Change: 2026-03-10 08:30:00
# 查看 inode 号
ls -i /etc/passwd
# 查看 inode 使用情况
df -i
inode 耗尽问题
磁盘空间充足但无法创建文件?很可能是 inode 耗尽。常见原因:大量小文件(如邮件队列、session 文件)。
# 检查 inode 使用率
df -i
# 查找 inode 最多的目录
find / -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -20
硬链接 vs 软链接
| 特性 | 硬链接 | 软链接(符号链接) |
|---|---|---|
| 创建方式 | ln source link | ln -s source link |
| inode | 相同(共享 inode) | 不同(新 inode) |
| 跨文件系统 | 不可以 | 可以 |
| 链接目录 | 不可以(除 . 和 ..) | 可以 |
| 源文件删除 | 不受影响(引用计数减 1) | 链接失效(悬空链接) |
| 文件大小 | 与原文件相同 | 存储路径字符串的长度 |
# 创建硬链接
ln /etc/passwd /tmp/passwd_hard
# 两者 inode 号相同
ls -i /etc/passwd /tmp/passwd_hard
# 创建软链接
ln -s /etc/passwd /tmp/passwd_soft
# inode 号不同
ls -i /etc/passwd /tmp/passwd_soft
# 查看链接指向
readlink /tmp/passwd_soft
文件类型
Linux 有 7 种文件类型:
| 标识 | 类型 | 说明 | 示例 |
|---|---|---|---|
- | 普通文件 | 文本、二进制、脚本等 | /etc/passwd |
d | 目录 | 包含文件名到 inode 的映射 | /home |
l | 符号链接 | 指向另一个文件 | /usr/bin/python → python3 |
b | 块设备 | 按块读写(磁盘) | /dev/sda |
c | 字符设备 | 按字符读写(终端) | /dev/tty |
p | 命名管道 | 进程间通信 | FIFO |
s | Socket | 进程间通信 | /var/run/docker.sock |
# 查看文件类型
file /etc/passwd # ASCII text
file /bin/ls # ELF 64-bit LSB executable
file /dev/sda # block special
# ls -l 第一个字符就是文件类型
ls -l /dev/sda # brw-rw---- (b = 块设备)
ls -l /etc/passwd # -rw-r--r-- (- = 普通文件)
挂载机制
Linux 通过**挂载(mount)**将存储设备连接到目录树:
# 查看当前挂载
mount
df -hT
# 手动挂载
mount /dev/sdb1 /mnt/data
mount -t nfs 192.168.1.100:/shared /mnt/nfs
# 卸载
umount /mnt/data
# 查看设备信息
lsblk
blkid
/etc/fstab 永久挂载
/etc/fstab
# <设备> <挂载点> <类型> <选项> <dump> <fsck>
UUID=xxxx-xxxx / ext4 defaults 1 1
UUID=yyyy-yyyy /home ext4 defaults 1 2
/dev/sdb1 /data xfs defaults,noatime 0 0
192.168.1.100:/shared /mnt/nfs nfs defaults 0 0
tmpfs /tmp tmpfs defaults,size=2G 0 0
fstab 写错可能导致系统无法启动
修改 /etc/fstab 后,务必执行 mount -a 测试。如果配置有误导致系统无法启动,需要进入单用户模式或使用 Live CD 修复。
推荐使用 UUID 而非设备名(如 /dev/sdb1),因为设备名可能因硬件变化而改变。
常见文件系统对比
| 文件系统 | 最大文件 | 最大分区 | 特性 | 适用场景 |
|---|---|---|---|---|
| ext4 | 16 TB | 1 EB | 成熟稳定、默认选择 | 通用 |
| XFS | 8 EB | 8 EB | 高性能、大文件友好 | 数据库、大文件 |
| Btrfs | 16 EB | 16 EB | 快照、压缩、RAID | 需要高级特性 |
| tmpfs | - | - | 内存文件系统 | /tmp、/run |
常见面试问题
Q1: Linux 中一切皆文件是什么意思?
答案:
Linux 将几乎所有资源都抽象为文件,通过统一的文件操作接口(open/read/write/close)进行访问:
- 普通文件:文本、二进制
- 目录:特殊文件,存储文件名到 inode 的映射
- 设备:
/dev/sda(块设备)、/dev/tty(字符设备) - 进程信息:
/proc/[pid]/下的虚拟文件 - 网络 Socket:
/var/run/docker.sock - 管道:命名管道 FIFO
这种设计简化了系统编程,所有 I/O 都可以用相同的系统调用处理。
Q2: 硬链接和软链接的区别?能否对目录创建硬链接?
答案:
核心区别:硬链接共享同一个 inode,软链接有独立的 inode 指向目标路径。
- 硬链接:删除源文件不受影响(引用计数机制),不可跨文件系统,不可对目录创建(避免形成环路,
.和..是内核维护的例外) - 软链接:源文件删除后成为悬空链接,可跨文件系统,可链接目录
Q3: inode 耗尽怎么排查和解决?
答案:
# 1. 确认 inode 使用情况
df -i
# 如果 IUse% 接近 100%
# 2. 定位大量小文件的目录
find / -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -10
# 3. 常见原因及解决
# - 邮件队列堆积:清理 /var/spool/mail
# - session 文件:清理 /tmp 或 session 目录
# - 日志碎片:清理过期日志
# - 容器遗留:清理已停止的容器层
# 4. 预防措施
# - 监控 inode 使用率
# - 设置 tmpwatch/systemd-tmpfiles 自动清理
# - 创建文件系统时合理设置 inode 数量(mkfs -N)
Q4: /proc 和 /sys 的区别?
答案:
/proc:进程信息文件系统(procfs),提供进程和内核状态信息,如/proc/cpuinfo、/proc/meminfo、/proc/[pid]//sys:设备信息文件系统(sysfs),提供设备和驱动信息,如/sys/class/net/eth0/、/sys/block/sda/
两者都是虚拟文件系统,数据由内核动态生成,不占磁盘空间。/sys 更结构化且可写(可修改设备属性),/proc 主要用于读取信息。
Q5: ext4 和 XFS 的选择?
答案:
| 方面 | ext4 | XFS |
|---|---|---|
| 成熟度 | 非常成熟,默认选择 | 成熟,RHEL 7+ 默认 |
| 小文件性能 | 较好 | 一般 |
| 大文件性能 | 一般 | 优秀(延迟分配) |
| 缩容 | 支持 | 不支持 |
| 碎片整理 | 支持 | 支持(xfs_fsr) |
| 修复速度 | e2fsck 较慢 | xfs_repair 较快 |
建议:通用场景用 ext4,大文件/高 I/O 场景(数据库、视频存储)用 XFS。
Q6: 如何查看某个进程打开了哪些文件?
答案:
# 方法 1:lsof
lsof -p <PID>
# 方法 2:/proc 文件系统
ls -la /proc/<PID>/fd/
# 方法 3:查看文件描述符数量
ls /proc/<PID>/fd/ | wc -l
# 查看进程的文件描述符限制
cat /proc/<PID>/limits | grep "open files"