很多人背过 Linux 目录结构,但背完就忘,因为只知道"是什么",不知道"为什么"。这篇从 SRE 视角重新梳理一遍,你会发现这套目录设计其实是一套严密的工程哲学。
刚接触 Linux 的人,第一反应通常是:这玩意为什么这么复杂?
Windows 下,你装个软件,双击安装包,程序文件、配置、快捷方式,全都在 C:\Program Files\xxx 下,整整齐齐一个文件夹。
Linux 不是这样的。一个程序装完,可执行文件跑到 /usr/bin,配置文件丢在 /etc,日志写进 /var/log,库文件散落在 /usr/lib,数据存在 /var 某个角落。
这不是乱,这是刻意设计的结果。
背后的逻辑叫做 FHS(Filesystem Hierarchy Standard,文件系统层次结构标准)。
理解这套逻辑,是真正入门 Linux 系统运维的第一道坎。
/这个斜杠,就是整个 Linux 文件系统的起点。
没有 C 盘、D 盘,没有盘符的概念。所有的磁盘、网络存储、虚拟文件系统,都挂载在这棵树的某个节点上。
一个典型的 CentOS 7 根目录下,你会看到:
bin boot dev etc home lib lib64 lost+found
media mnt opt proc root run srv sys tmp usr var
看起来杂,实际上每个目录都有明确的边界和职责。
整个目录结构可以按两个维度来拆分:
维度一:谁来用?
普通用户用的 → /bin、/home
系统管理员(root)专用 → /sbin、/root
维度二:内容会不会变?
静态不变的 → /bin、/lib、/usr
动态经常变的 → /var、/tmp、/run
理解这两个维度,整个目录体系就清晰了。
/bin 和 /sbin:命令从哪来/bin 是 Binary 的缩写,存放所有用户都能用的基础命令:ls、cp、mv、cat、echo……
/sbin 里是系统管理命令,s 代表 Super User:ifconfig、iptables、fdisk、fsck……普通用户通常没有执行权限。
一个容易混淆的点:
你可能还见过 /usr/bin 和 /usr/local/bin,它们的区别是:
| 目录 | 说明 |
|---|---|
/bin | 系统启动所必需的基础命令,早期单独分区时必须可用 |
/usr/bin | 大部分用户程序的可执行文件,系统启动不依赖它 |
/usr/local/bin | 系统管理员手动编译安装的程序,优先级最高 |
SRE 日常踩坑: 手动编译安装一个工具,装完发现跑的还是旧版本。原因十有八九是 /usr/local/bin 没有排在 $PATH 的前面。
验证方式:
echo$PATH
# 输出类似:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
# /usr/local/bin 要排在最前面才生效
/etc:配置的大本营/etc 这个名字历史上来自 "et cetera"(等等),现在约定俗成地专门放系统配置文件。
几个必须记住的路径:
/etc/passwd # 用户账号信息(不含密码,密码在 shadow)
/etc/shadow # 加密后的用户密码
/etc/group # 用户组信息
/etc/hosts # 静态 DNS 解析,优先于 DNS 服务器
/etc/resolv.conf # DNS 服务器配置
/etc/fstab # 开机自动挂载的分区表
/etc/crontab # 系统级定时任务
/etc/ssh/sshd_config # SSH 服务配置
/etc/sudoers # sudo 权限配置(建议用 visudo 编辑)
SRE 经验:/etc/hosts 是排查内网 DNS 故障时最先检查的地方。很多"奇怪的连接问题",根子在这里写了一条错误的解析记录。
还有一个经常被忽略的:/etc/fstab 写错了,机器重启之后可能直接进不去。改 fstab 之前一定备份,一定备份,一定备份。
/var:运维的日常战场/var 是 Variable 的缩写,存放频繁变化的数据。
这是 SRE 日常打交道最多的目录:
/var/log/ # 日志根目录,排障起点
/var/log/messages # CentOS 系统通用日志
/var/log/secure # 认证和权限相关日志(SSH 登录记录在这)
/var/log/dmesg # 内核启动日志
/var/log/nginx/ # Nginx 日志(access.log、error.log)
/var/cache/ # 软件包管理器缓存(yum/apt 的下载缓存)
/var/spool/cron/ # 用户的 crontab 文件
/var/lib/ # 程序的持久化状态数据(MySQL 数据库默认在 /var/lib/mysql)
一个真实的故障场景:
某天凌晨,业务告警,服务写入失败。排查一圈,发现是磁盘写满了。df -h 一看,/ 分区 100%。
然后 du -sh /var/log/* 扫一遍,发现某个服务的 debug 日志没有做 rotate,三个月积累了 80G。
/var 目录最容易出现磁盘打满的情况,合理的日志轮转策略(logrotate)是基本功,不是可选项。
/proc 和 /sys:内核的窗口这两个目录,是真正理解 Linux 的关键。
/proc 是内存的映射,不是真实存在于磁盘上的文件。
cat /proc/cpuinfo # 查看 CPU 信息
cat /proc/meminfo # 查看内存使用情况
cat /proc/loadavg # 查看系统负载
cat /proc/net/dev # 查看网络接口流量统计
ls /proc/1234/ # 查看 PID 为 1234 的进程信息
cat /proc/sys/net/ipv4/ip_forward # 查看 IP 转发是否开启
/sys 提供对内核参数和硬件设备的控制接口(sysfs)。
# 临时调整内核参数(重启失效)
echo1 > /proc/sys/net/ipv4/ip_forward
# 持久化调整,写入 /etc/sysctl.conf
net.ipv4.ip_forward =1
sysctl -p# 让配置生效
SRE 实战场景:
线上服务出现大量 TIME_WAIT 连接,导致端口耗尽:
# 查看当前 TIME_WAIT 数量
ss -ant | grep TIME-WAIT | wc-l
# 通过 /proc 调整内核参数,快速缓解
echo30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo1 > /proc/sys/net/ipv4/tcp_tw_reuse
这些参数调整,底层都是在操作 /proc 和 /sys 下的虚拟文件。
/dev:一切皆文件的极致体现Linux 的核心哲学之一:一切皆文件。
硬件设备也不例外,全部以文件形式存在于 /dev 目录下:
/dev/sda # 第一块 SATA/SCSI 硬盘
/dev/sda1 # 第一块硬盘的第一个分区
/dev/nvme0n1 # NVMe SSD
/dev/tty1 # 第一个虚拟终端
/dev/null # 黑洞,写入的数据全部丢弃
/dev/zero # 无限输出零字节
/dev/random # 随机数生成器(会阻塞)
/dev/urandom # 非阻塞随机数生成器
/dev/mem # 物理内存的映射
几个高频用法:
# 把错误信息扔进黑洞,只保留标准输出
command 2>/dev/null
# 用 dd 测试磁盘写速度
dd if=/dev/zero of=/tmp/test bs=1M count=1000oflag=direct
# 用 dd 备份整块磁盘
dd if=/dev/sda of=/backup/sda.img bs=4M status=progress
# 生成随机密码
cat /dev/urandom | tr -dc'a-zA-Z0-9' | head -c16
/home 和 /root:用户的地盘/home 下面是每个普通用户的主目录,格式为 /home/username。
/root 是 root 用户的主目录,单独放在根目录下,而不是 /home/root,这是刻意的设计——即使 /home 所在的分区挂载失败,root 也能正常登录。
SSH 密钥认证的配置文件就在这里:
~/.ssh/authorized_keys # 允许登录的公钥列表
~/.ssh/id_rsa # 私钥(权限必须是 600,否则 SSH 拒绝使用)
~/.ssh/config # SSH 客户端配置(可配置跳板机、别名等)
一个安全提醒:/root/.ssh/authorized_keys 里的内容,决定了谁能免密登录服务器。定期审计这个文件,是基本的安全卫生。
/usr:系统的主体/usr 存放的是大多数用户级程序和只读数据,是 Linux 文件系统体积最大的目录之一。
/usr/bin # 大多数用户命令
/usr/sbin # 大多数系统管理命令
/usr/lib # 共享库文件
/usr/include # C/C++ 头文件
/usr/share # 架构无关的共享数据(man 手册、图标、时区等)
/usr/src # 内核源码(如果安装了的话)
/usr/local # 本地手动安装的软件(优先级高于 /usr)
/usr/local 是手动编译安装软件的标准落地位置。 比如你从源码编译了一个新版 Nginx,默认安装路径就是:
/usr/local/nginx/sbin/nginx # 可执行文件
/usr/local/nginx/conf/ # 配置文件
/usr/local/nginx/logs/ # 日志文件
/tmp:临时文件,别存重要数据/tmp 是临时文件目录,系统重启后通常会清空。很多程序在运行时把临时文件写到这里。
有个坑: 某些系统(特别是 systemd 管理的系统)对 /tmp 启用了 tmpfs,也就是说 /tmp 是挂载在内存里的。临时文件过大,会直接吃内存。
检查方式:
df -h /tmp
# 如果 Filesystem 显示 tmpfs,那就是内存挂载的
/mnt 和 /media:挂载外部存储/mnt 是管理员手动挂载文件系统的约定位置:
# 挂载一个数据盘
mount /dev/sdb1 /mnt/data
# 挂载 NFS 网络存储
mount -t nfs 192.168.1.100:/share /mnt/nfs
/media 是系统自动挂载可移动设备(U 盘、光驱)的位置,在桌面环境下更常见。
/opt:大型第三方软件的家/opt 是 Optional 的缩写,专门给第三方大型软件用的。
典型的:
/opt/jdk/ # JDK 安装目录
/opt/elasticsearch/ # Elasticsearch
/opt/kafka/ # Kafka
/opt/grafana/ # Grafana
这些软件通常把所有相关文件(二进制、配置、数据、日志)都放在自己的子目录里,不散落到系统目录,卸载时直接删文件夹就完事了。
/boot:别动,真的别动/boot 里存放的是内核镜像、initramfs 和引导加载程序(GRUB)的配置:
/boot/vmlinuz-* # Linux 内核文件
/boot/initrd.img-* # 初始化内存盘
/boot/grub/grub.cfg # GRUB 引导配置
这个目录通常是独立分区,大小一般是 500MB 到 1GB。
踩过的坑:/boot 分区满了,yum update 或 apt upgrade 更新内核会失败。需要手动清理旧内核:
# 查看当前所有内核
rpm -qa | grep kernel # CentOS
dpkg --list | grep linux-image # Ubuntu
# CentOS 保留最近两个内核,删除旧的
package-cleanup --oldkernels--count=2
/lost+found:文件系统的急救站这个目录在每个 ext2/ext3/ext4 文件系统的挂载点下都会存在。
当系统崩溃、断电导致文件系统损坏时,fsck(文件系统检查工具)在修复过程中可能会找到一些"无家可归"的文件或数据块——它们无法被关联到任何目录,就会被丢进 /lost+found,供管理员手动检查。
正常情况下这个目录应该是空的。 如果你在里面发现了文件,说明系统之前发生过非正常关机或磁盘故障,需要仔细排查原因。
| 目录 | 日常用途 | 注意事项 |
|---|---|---|
/etc | 查改配置文件 | 修改前备份,fstab 改错会导致无法启动 |
/var/log | 排障看日志 | 做好 logrotate,防止磁盘打满 |
/proc | 查看系统状态 | 虚拟文件系统,不占磁盘空间 |
/sys | 调整内核参数 | 重启失效,持久化需写 sysctl.conf |
/tmp | 临时文件 | 可能是 tmpfs,别存大文件 |
/home//root | 用户配置 | 定期审计 .ssh/authorized_keys |
/boot | 引导相关 | 独立分区,注意空间,清理旧内核 |
/dev/null | 丢弃输出 | 重定向错误信息的常用手段 |
/usr/local | 手动安装软件 | 确保在 $PATH 前面 |
/opt | 第三方大型软件 | 自包含结构,便于管理和卸载 |
Linux 目录结构背后有一套一致的设计哲学:职责分离、变化隔离、权限边界清晰。
理解这套哲学,你才能在磁盘告警时知道去哪找元凶,在配置修改时知道边界在哪,在服务崩溃时知道日志在哪里等着你。
这不是死记硬背的知识,是用出来的肌肉记忆。