
搞运维这些年面试过不少人也带过不少新人发现一个特别有意思的现象很多人能把ls、cd、grep背得滚瓜烂熟遇到服务起不来、磁盘报警也能敲一长串命令去查但你要是突然问他一句“Linux核心目录到底怎么长成这个样子的/bin和/usr/bin为什么看起来像双胞胎/tmp和/var/tmp到底有什么区别”他大概率会愣一下。这不是个别现象。说白了命令只是手目录结构才是骨架。只要你在 Linux 上干活——不管你是运维、后端开发、测试还是自己折腾服务器——对 Linux 核心目录的理解深度直接决定了你排障的速度和姿势。我见过太多人一遇到问题就在根目录下乱翻或者盲目find / -name一通扫最后把系统搞得更乱。这篇文章我就把自己这些年对 Linux 核心目录的认知、踩过的坑、总结出来的排查套路一次给你讲透。内容会涵盖目录的功能定位、关键差异、实际运维中怎么靠目录语义快速定位问题以及分区规划、扩容、备份这些和目录强相关的实操经验。不分发行版Debian 系和 RedHat 系我都照顾到适合刚接触 Linux 的入门用户也适合准备面试、想系统梳理一遍知识的开发者。1. 先建立整体认知目录不是随便起的是有一套设计逻辑的1.1 “一切皆文件”和根目录的起点接触 Linux 的第一课基本都听过一句话一切皆文件。这句话的真正含义是目录、设备、进程状态、内核参数都被抽象成了文件放在一套统一的目录树里。一切从/开始这棵树的每一个节点都有明确的职责范围不是随随便便用字母命名的。很多人学 Linux 喜欢死记目录名这是最大的误区。这套命名的背后其实是一套标准——FHSFilesystem Hierarchy Standard文件系统层次标准。FHS 最早是 Linux 社区为了统一各发行版的目录结构而制定的规范虽然现在不是每个发行版都百分百遵守但大体框架是稳定的。理解了 FHS 的设计意图你就懂了/bin放的是系统启动和用户操作必需的基础命令/sbin放的是系统管理命令/usr是系统主体程序和数据/var是经常变化的数据/etc是配置文件/home是普通用户的家/tmp是临时文件。每个字母背后都有明确的语义。这套设计解决了一个非常实际的问题不同的程序、不同的用户、不同的数据形态应该放在哪里是约定的。约定统一之后包管理器知道把东西装到哪系统管理员知道去哪儿找日志、改配置恶意软件想在系统里乱窜也会因为目录权限的设计而受到限制。所以理解目录结构不是掉书袋它是一切管理工作的地基。1.2 标准之外各家发行版的细微差异基础框架是统一的但发行版之间会做调整。以最典型的三家为例RedHat 系CentOS / RHEL / Rocky / AlmaLinux传统布局/bin、/sbin、/lib、/lib64有实体目录/usr也是独立的大区。尤其在老版本里/bin和/usr/bin是真实的不同目录RedHat 系的包管理会把命令分开放。Debian 系Debian / Ubuntu / Deepin大部分新版系统已经完成了 usrmerge/bin、/sbin、/lib都变成了指向/usr/bin、/usr/sbin、/usr/lib的符号链接。所以你ls -l /bin会看到bin - usr/bin这对用户来说完全透明路径照常访问。Arch / Manjaro同样是合并后的布局默认就是/usr/bin存命令/bin是链接。这个差异对日常使用基本没影响因为无论bin是实体目录还是软链接系统都会保证它在 PATH 里可用。但对分区分割和备份策略有影响比如你把/usr单独挂载了而系统又依赖/usr/bin里的初始化脚本时启动顺序错了就会出问题。这个细节后面讲分区的时候会细说。2. 逐个拆解核心目录的功能定位与实操要点2.1 启动与程序区/boot、/bin、/sbin、/usr、/lib这一组目录承担的是“让系统跑起来”和“让用户有工具可用”的职责。/boot存放内核和引导文件。最常见的有vmlinuz-*内核本体、initramfs-*初始内存镜像用于挂载根文件系统前加载必要驱动、grub2/或grub/引导配置。这台机器能不能正常起来很大程度看/boot是否健康。实操中要注意/boot 分区不用太大1G 完全够用CentOS 7 时代 500M 也没问题但内核多了确实会挤千万别把/boot塞满否则新内核装不上、系统重启找不着引导。/bin 和 /sbin看名字bin 是 binary二进制的缩写sbin 是 system binary系统二进制。传统分工是/bin 存所有用户都能用的基础命令ls、cat、cp、mv这些/sbin 存管理员用的系统管理命令fdisk、mount、iptables等。新合并系统里两者的内容都集中在/usr/bin和/usr/sbinbin 作为链接存在。有朋友曾经问我“为什么我在普通用户下也能用 sbin 里的命令”答案很简单能不能执行不取决于目录名取决于命令的权限和 PATH。事实上许多发行版默认把/usr/sbin也加入了普通用户的 PATH所以你敲reboot都有提示。/usr这是个大目录可以理解为“系统主体软件区”。/usr/bin存绝大多数用户命令/usr/lib存程序运行依赖的库文件/usr/share存架构无关的共享数据语言包、图标、文档等/usr/local是管理员手动编译安装软件的默认前缀又叫“本地目录”。在合并不彻底的老系统上/user是独立的但我们平时只关心/usr。有一个核心原则能用系统包管理器安装的就不要手动装到 /usr/local否则容易和系统文件打架。但手动编译的软件强烈建议放 /usr/local方便和系统自带的隔离。/lib 和 /lib64存放动态链接库的关键目录。现代系统几乎都合并到/usr/lib了。程序运行时需要通过动态链接器如 ld-linux-x86-64.so.2找到这些库。如果你发现某个命令报“cannot open shared object file”排除的第一方向就是/usr/lib或/usr/lib64里缺库文件要么用ldd /usr/bin/xxxx查依赖要么装对应包。这一组目录给我的最大经验排查“命令找不到”的时候先which确认它在哪个目录再ls -l看它是实体文件还是软链接最后检查 PATH 环境变量。很多新手一报“命令不存在”就上来重装其实多半是 PATH 没带目录。2.2 配置与可变数据区/etc、/home、/root、/var这组目录是运维天天打交道的地方。/etc纯文本配置大本营。从/etc/passwd用户账户信息、/etc/shadow密码哈希、/etc/group用户组到网络配置RHEL 系是/etc/sysconfig/network-scripts/ifcfg-*Debian 系是/etc/network/interfaces或 netplan再到应用配置Nginx 的/etc/nginx/nginx.confMysql 的/etc/my.cnf。改 /etc 之前必须备份这是铁律。我自己改过太多次配置把服务改挂后来养成了一个习惯改任何文件前先cp xxx xxx.bak.$(date %F)改完立刻验证语法或加载确认无误再删备份。/home普通用户的家目录每个用户一个子目录如/home/zhangsan。用户配置文件dotfile、工作文件都放在这里。理解 /home 语义对“新建用户”这件事很有帮助useradd创建用户时如果系统目录结构不完整或者管理员忘了-m参数用户就没有家目录登录后连自己的工作空间都没有。常见的操作是useradd -m -s /bin/bash 用户名-m表示创建 home-s指定登录 shell。/root管理员的家。千万别把 /home/root 当管理员的目录那是新手常犯的错。管理员的历史命令、ssh 密钥、脚本都放 /root。它的权限是 700普通用户不可进这是安全设计。/var全称是 variable意思是“经常变化的数据”。日志/var/log邮件/var/spool/mail临时缓存/var/cache程序状态数据/var/lib比如数据库默认路径/var/lib/mysql还有网站默认根目录/var/www/htmlDebian/Ubuntu。这里最需要关注的是/var/log经典的磁盘满就是它的锅。我处理过太多“服务器卡死”的工单一看df -h/var100%全是/var/log/access.log、/var/log/syslog这种无上限日志。处理办法后面单独讲。2.3 动态与临时区/tmp、/run、/proc、/sys、/dev这一组是 Linux 区别于 Windows 的魅力所在全是动态的、虚拟的、代表状态的目录。/tmp临时文件目录任何用户都可以写但系统重启后可能被清具体取决于发行版的 tmpwatch 或 systemd-tmpfiles 策略。很多程序会把临时文件放这里。有个小坑因为/tmp是全局可写所以也是恶意脚本、无良程序的聚集地。运维巡检时重点看这里有没有异常权限的可疑文件。另外注意区分/tmp和/var/tmp/var/tmp在系统重启后保留时间更长适合放跨重启的临时数据两者如果分区分开了空间策略也不同。/run一个 tmpfs内存文件系统存放系统运行时的动态信息。系统的 PID 文件、socket 文件都在这比如/run/nginx.pid、/run/mysqld/mysqld.sock。这类文件不能删删了服务可能就假死或者连不上 socket。/proc这就是“一切皆文件”的巅峰体现。它是一个虚拟文件系统不占用真实磁盘空间内核把进程信息、系统状态暴露成文件。/proc/meminfo看内存/proc/cpuinfo看 CPU/proc/loadavg看负载/proc/uptime看开机时间。每一个运行中的进程对应一个/proc/PID目录。很多东西可以直接 echo 写入来临时调整内核参数比如echo 1 /proc/sys/net/ipv4/ip_forward开启转发。但注意/proc/sys下的改动是临时的重启就丢要持久化得写/etc/sysctl.conf或/etc/sysctl.d/。/sys另一个虚拟文件系统比 /proc 更接近硬件和内核设备模型。它把内核里的设备、驱动、电源管理信息都暴露出来。像我在做嵌入式 Linux 时经常通过/sys/class/leds/操作 GPIO 控制的 LED 灯写brightness文件就能点亮或熄灭也可以看 CPU 调频状态/sys/devices/system/cpu/。正常运维场景不常动它但要是做硬件相关开发这个目录就是宝藏。/dev设备文件目录。磁盘/dev/sda、/dev/nvme0n1显卡/dev/dri/card0终端/dev/tty随机数设备/dev/random、/dev/urandom空设备/dev/null。这里有个操作上的重点不要对 /dev 下的文件乱做文件系统操作比如mkfs.ext4 /dev/sda1之前一定确认设备名否则一个回车整个盘的数据就没了。我见过生产事故现场就是因为把/dev/nvme0n1和/dev/nvme0n1p1看岔了把整块盘重新格式化惨烈程度不忍细说。3. 用核心目录定位真实故障四个实战案例光背目录名没意义得会在真实故障里用。下面分享四个我实际处理过的案例每一个都体现了对目录语义的理解。3.1 案例一应用“卡死”其实是 /var 目录被日志塞满某天监控告警某台业务服务器磁盘使用率 100%登录一看df -hFilesystem Size Used Avail Use% Mounted on /dev/mapper/vg-root 40G 40G 0 100% / /dev/mapper/vg-var 20G 20G 0G 100% /var你没看错根分区和 /var 分区都满了。大多数人这时候会先删日志但我习惯先定位是谁的日志在疯长。命令就三连df -h看挂载点du -sh /var/log/*按目录找大头ls -lhS /var/log/按文件大小排序找具体文件。结果发现/var/log/syslog单文件 15G明显是某个程序在疯狂写日志。tail -f /var/log/syslog一看全是同一个 Java 应用在刷 StackOverflowError。问题定位到应用层先把服务停掉把日志文件清空注意不是rm而是truncate -s 0或 /var/log/syslog因为服务还持有着文件句柄直接 rm 不会释放空间然后去排查应用内存泄漏。这里想强调一个运维基本功清日志一定要区分“释放空间”和“删除文件”。服务进程打开日志文件后即使你rm了路径空间也不会立刻释放进程还占着 inode这个时候文件大小会显示 deleted 但磁盘还是满的。正确做法通常是truncate -s 0 /var/log/xxx或 /var/log/xxx强制清空文件内容空间马上释放。等彻底解决应用问题后再配置 logrotate 做日志轮转。3.2 案例二/tmp 目录被垃圾文件占满程序莫名崩溃另一个磁盘告警案例更隐蔽根目录没满/tmp满了。半夜有前台进程往/tmp写临时文件结果写到 100%导致 Java 服务报告“No space left on device”。排查逻辑和案例一完全一致du -sh /tmp/* | sort -rh | head就能看到是哪个历史进程留下的死循环文件。清理完以后要反思为什么/tmp的分区这么小谁把这么大的临时数据往/tmp写更规范的做法是让应用把临时文件写到自己目录下的tmp子目录或者系统层面挂载 tmpfsmount -t tmpfs -o size4G,mode1777 tmpfs /tmp这样/tmp变成内存盘速度飞快重启自动清空不会产生真实的磁盘碎片。但也要注意风险空间会用内存或 swap上限如果应用的临时文件超过 4G照样报错。所以这个改动要评估业务再执行。3.3 案例三/etc 目录配置改错Nginx 起不来朋友公司一台 Ubuntu 上跑着 Nginx某天他们同事改配置把 server_name 写错了或者引用了不存在的 include 路径nginx -t直接报错 service 起不来。我的排查顺序是cd /etc/nginxls -l看看配置文件结构nginx -t测试错误提示会精确告诉你哪一行有问题。改之前把nginx.conf备份成nginx.conf.bak.20250101改完再测。这类事故的核心教训就一条所有 /etc 下的改动必须有备份、有回滚计划、有验证步骤。前几年有个段子叫“删库跑路”实际上生产环境运维连rm -rf /etc这种事都偶尔有人干出来。真碰上rm -rf /etc系统多数命令会失效PATH 里很多命令软链指向的库还在但配置全丢了这种事故的恢复手段只剩使用备份或重新配置。所以重要配置一定多副本备份备份不仅是放别的分区还要异地或者对象存储里留一份。3.4 案例四/proc、/sys 误操作引发的“诡异”现象某次出差客户现场一台数据库服务器日志级别被不知哪个“懂王”改低到 debug导致 /var/log 暴涨。这还算好的。更夸张的是有人echo 0 /proc/sys/kernel/panic想关掉 kernel panic然后把生产服务器跑挂了结果不会自动重启了。还有人在/sys/block/sda/device/delete下没事敲 echo把磁盘在线给删了。这里必须明确/proc 和 /sys 是内核的实时接口所有对它下层的写入都要理解为“在内核层操作硬件和系统参数”不是普通文件没有回收站机制。排查这类问题时习惯性先mount | grep proc看这个目录挂载的是不是 proc 文件系统确认它确实不是普通文件。4. 目录与分区规划拆分、扩容、备份策略4.1 分区规划的核心原则把“变动快的”分出去装系统或者规划服务器时磁盘分区是个很有讲究的活儿。我的原则很简单把变化快、可能疯长的目录单独分区把不常变化的目录合并到根分区。新手装 Linux 喜欢搞一堆分区/boot500M、/20G、/home10G、/var10G……结果用着用着/var满了、/tmp满了天天扩容。更好的实践是/boot单独分区500M - 1G 就够防止根分区满导致内核更新失败。/根分区尽量大把/bin、/usr、/etc、/lib这些“静态区”全放在里面。/var单独分区这是日志和程序状态的重灾区单独分区的好处是日志把 /var 塞满时系统其他目录比如 /tmp 和 /usr还能正常工作不至于整个系统卡死。/home可选如果用户多、个人文件多单独分也没问题好处是重装系统时保留 /home 不动。有个容易被忽略的点如果把/usr单独分区就会给 initramfs 带来额外压力因为启动阶段挂载根分区之后还得再挂 /usr。因此 RedHat 系安装器都默认不把 /usr 单独分区。所以建议别单独分 /usr。4.2 用 Bind Mount 解决分区不足问题和目录重定位实际运转中分区规划难免失算盘不够了就得扩容或迁移。Linux 有 bind mount 这个好东西可以把一个目录“绑定”到另一个挂载点而文件内容不变。典型场景/var分区被日志写满了但根分区还有大量空间。此时可以# 先停掉关键服务或至少暂停写日志 systemctl stop rsyslog mkdir -p /data/var cp -a /var/log/* /data/var/ mount --bind /data/var /var/log systemctl start rsyslog之后写入/var/log的所有内容就去/data/var了。这个操作的好处是不破坏原有目录结构对应用透明甚至不用改 fstab重启后失效配合/etc/fstab里写一行 bind 就能持久化。另一个常见操作是把网站目录从系统盘迁移到数据盘数据盘挂载到/data然后mount --bind /data/www /var/www/html实现迁移。注意bind mount 要求源和目标目录都存在操作前先建目录并且copy -a时保留属主和权限否则迁移后应用可能权限出错。4.3 备份策略里的目录优先级分区规划完善了备份也要讲优先级。根据目录语义不同目录的价值天差地别必须备份/etc配置服务器恢复时靠它、/home和/root用户数据、/var/lib数据库、程序状态数据、/var/www或站点目录业务数据、/opt有些软件的安装数据。还有/var/spool/cron或/etc/crontab用户计划任务。不用备份/proc、/sys、/dev、/run、/tmp全是临时或动态的重启自动重建。选择性备份/usr、/lib、/bin这些理论上能靠重装系统恢复不需要作为业务数据备份。但如果你手动改过 /usr/local 下的软件这个目录需要额外备份。我用过一个很笨但很稳的脚本逻辑每晚tar打包/etc、家目录和重要数据用循环遍历目录树排除/proc|/sys|/dev|/run|/tmp|/var/cache等目标再传到异地。这套逻辑之所以稳定核心就是基于目录语义做排除而不是一个个手敲路径。5. 常见问题排查与核心命令速查表5.1 典型问题与排查思路新手甚至老手在目录上踩的坑多数集中在权限、路径、挂载点三件事上。我把高频问题整理成一张速查表方便你定位。现象关键目录/命令排查思路命令找不到PATH、/usr/bin、/usr/local/binwhich看命令归属echo $PATH确认路径必要时软链接或加 PATH磁盘空间满了但不知道谁占的df -h、du -shdf -h看哪个挂载点满du -sh /路径/*逐层定位注意释放空间用 truncate 而非 rm服务起不来/var/log看journalctl -xe或对应服务日志日志目录通常就在 /var/log/服务名找不到配置文件/etc先dpkg -L 包名或rpm -ql 包名查包文件列表找到配置文件位置权限拒绝Permission deniedls -l、chmod、chown查目录权限x 权限决定了能否进入确认属主属组注意rwx里的x删除文件后空间没释放lsof进程保留句柄用lsof L1找 deleted 文件找到进程并重启或 kill数据库连接不上、socket 文件丢失/run、/var/runsocket 文件缺失多半是服务没起来或权限问题别手动创建/run/mysqld/xxx.sock应该启动服务5.2 我在实际使用中高频用到的目录操作命令把目录理解透了命令自然用得溜。分享几个我几乎每天都会用到的df -hT查看各文件系统类型、大小、剩余空间比df -h多一列文件系统类型一眼看出挂载的是 xfs、ext4 还是 tmpfs。du -h --max-depth1 /var只展示 /var 下一级目录占用比du -sh *更清晰特别适合排查谁把 /var 吃光了。lsblk查看块设备、分区、挂载点树状关系。分区扩容、加盘时核心第一步就是 lsblk。find /var/log -type f -size 100M按大小快速找可疑大文件排障利器。lsof L1列出已被删除但仍被进程占用的文件解决“删了没释放空间”的绝招。readlink -f /bin看软链接最终指向哪判断目录是不是 usrmerge 合并布局。tree -L 2 /etc批量演示目录结构时用平时排查也能快速了解配置树的组织。5.3 新手最容易犯的三个安全级别错误第一个是在根目录下rm -rf时手滑多打了个空格或斜杠。rm -rf / home/user和rm -rf /home/user是两条完全不同的命令前者会把根目录删掉。我见过不止一次事故。解决办法很简单重要删除操作绝对不带*路径写完整写绝对路径命令执行前先ls确认正在删什么。第二个是犯低级权限错误新创建用户后忘了给家目录设权限结果其他用户能随意翻。useradd -m默认创建目录并设置 755 权限家目录权限应该是 700 或者至少不让 group/others 可读新用户创建完成后建议直接chmod 700 /home/用户名。第三个是不知道哪些目录绝对不能动/proc下的运行时文件不能乱删/sys下节点不能乱 echo/run下面的 pid、socket 文件不能手动删掉删了服务就假死了。这些知识不看目录语义只背命令是永远学不到的。最后分享一点自己的体会说句掏心窝的话Linux 核心目录这套设计可以说是“几十年前的人为几十年后的维护者省的心”。你越了解它就越觉得它合理日志归日志、配置归配置、动态归动态、设备归设备。很多所谓的高深技能——系统调优、容器镜像制作、故障排查——归根结底都是对这套目录哲学的延伸。我建议刚入门的朋友别急着刷一堆面试题先在自己电脑的 Linux 虚拟机里cd /然后把每个目录都ls一遍对照 FHS 文档用df -h和du观察每个目录的增长趋势把虚拟机快照搞坏几次再手动恢复几回。这一套流程走下来你对 Linux 的理解绝对比背 100 个快捷键深刻得多。等你哪天遇到服务器故障不用翻文档自己下意识就能按“看 /var/log、查 /etc、查挂载点”的顺序排除问题那你就算真正把 Linux 核心目录这一课学进去了。