news 2026/10/20 3:13:24

Linux核心目录详解:从根目录到实战排查的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux核心目录详解:从根目录到实战排查的完整指南

第一次在服务器上敲下ls /的时候,我盯着满屏的英文缩写愣了好一会儿。etc到底是什么意思?usr是不是 user 的缩写?tmp为什么能放在根目录下?后来在线上环境踩了大大小小的坑,才慢慢明白这套看似凌乱的结构,其实是 Linux 最讲究的地方。这篇文章就把 Linux 核心目录从头到尾拆开讲一遍,不仅说明白每个目录是干什么的,还会讲讲实际维护中哪些目录最容易出问题、出了问题怎么从目录入手排查。对刚接触 Linux 的初学者,以及那些已经会敲命令但还没把目录体系串成整体认知的开发者,应该都有一点参考价值。

1. 先理解Linux目录的底层逻辑

1.1 单根树状结构:所有东西都从/开始

Windows 用户习惯了一堆盘符,C 盘装系统,D 盘放软件,E 盘塞数据。Linux 完全不同,整台机器只有一个根,就是/,所有目录、文件、设备、进程状态全都被挂在这棵树下。

打个比方:Windows 像一栋有很多出入口的楼房,每个盘符是一个独立入口;Linux 像一棵大树,树干是/,所有分支都从树干长出来,新设备插进来不是另开一个门,而是作为一根新树枝挂到某个节点上。U 盘插上去,你会在/media或者/mnt下看到它,它不是一个新盘符,而是一个目录。这是理解 Linux 目录的第一步:目录不只是存放文件的文件夹,还是设备和系统资源的挂载点。

系统启动时,内核先挂载根文件系统,然后根据/etc/fstab的配置把/home、/boot、/data这些分区依次挂载到位。所以你会看到整台机器的存储可能被分成好多块,但用户的视角里永远只有一个连续的目录树。这个设计有个好处:应用不需要关心数据物理上在哪个硬盘,只要路径对,系统会处理背后的一切。

1.2 系统目录与用户数据的边界

合上ls /的输出,我后来意识到一个更重要的规律:这些目录其实分成两大阵营,一部分属于“系统”,一部分属于“用户数据”。

/etc、/usr、/var、/bin、/sbin、/lib这些是系统自己的地盘,普通用户通常没有写权限,只有系统管理员能改动;/home、/tmp是用户活动和临时数据的空间,用户在这里有充分的自主权。这个边界不是随便划的,它背后是 Linux 的多用户设计:一台机器可能同时服务几十个人,如果所有人都能随便改/etc,系统早就乱套了。

这个划分对运维有一个直接指导意义:重装系统、升级发行版时,系统目录会被覆盖,但/home下的用户数据会保留;反过来,如果你把重要数据放在/var下的某个应用目录里(比如默认的数据库数据目录),重装系统时忘了备份,格式化分区后数据就没了。我一直建议新手养成一个习惯:动手前先问自己一句,我要碰的目录是系统的还是我自己的?这个判断能避免很多灾难性的误操作。

2. 根目录与第一层目录:整体骨架

2.1 FHS 标准与/下的规范布局

根目录下这一层目录的布局并不是谁心血来潮定的,而是有一套叫 FHS(文件系统层级标准)的规范在约束。FHS 规定了系统安装后哪些目录必须存在、每个目录的职责范围。当然,不同发行版会有细微差别,比如有的把用户家目录放在/home,有的嵌入式系统直接省掉很多目录,但大体框架是一致的。

这里有个非常容易让新手误解的点:/usr不是 user 的缩写(更不是用户目录),它最初是 UNIX System Resources 的意思,存放系统主要的程序、库和文档。现在主流发行版也在做 usrmerge,把/bin、/sbin、/lib、/lib64全部合并进/usr下的对应目录,根目录里只留软链接做兼容。

这次合并的意义在于:系统的基础程序全部集中到/usr,根文件系统可以做得更轻巧,甚至以只读方式挂载,升级时对根分区写操作的要求降到最低,整体的可恢复性和原子性都更强了。

2.2 第一层目录职责总表

我整理了一个核对表,基本覆盖了根目录下主要目录的职责和典型内容。刚开始不熟的时候,遇到路径问题回来查这张表就够了。

目录核心职责典型内容常见误区
/etc配置文件passwd、fstab、hostname、ssh/sshd_config以为改完立即生效,大部分需要重启服务
/usr系统程序与库/usr/bin、/usr/lib、/usr/share以为是用户目录,往里乱放东西
/var运行期变化的数据/var/log、/var/spool、/var/lib长时间不清理导致磁盘满
/tmp临时文件各种程序运行时产生的临时数据放重要文件,重启后可能被清空
/home普通用户家目录每个用户一个子目录权限过松导致隐私泄露
/root系统管理员的家目录管理员的个人配置和脚本和/混淆,以为就是根目录本身
/proc内核与进程的虚拟视图cpuinfo、meminfo、[pid]/fd直接往里写文件,忽略它只是内存映射
/dev设备节点/dev/sda、/dev/null、/dev/shm不理解设备即文件,看不懂磁盘命名
/sys内核与硬件的配置接口/sys/class/net、/sys/block和/proc分不清,不知道哪个该读哪个该写
/boot启动文件内核镜像、引导配置空间不足时内核升级失败
/opt第三方独立软件商业闭源程序、自解压软件包和/usr/local混用,不遵守分离惯例
/srv服务提供的数据FTP、HTTP 服务的站点文件用得很少,很多系统里默认是空的
/mnt/media挂载点手动挂载的磁盘、移动设备随意挂载后不卸载,造成数据访问异常

这张表不是背的,是用的。碰到路径问题先查目录职责,再判断这个目录下的异常是正常现象还是故障。

3. 高频使用的核心目录逐个拆解

3.1/etc:整台机器的配置中心

/etc是我日常操作最频繁的目录,没有之一。几乎所有核心服务的配置都在这。改系统主机名改/etc/hostname,改 DNS 客户端配置改/etc/resolv.conf,改用户认证信息用passwd命令然后更新/etc/passwd和/etc/shadow。

注意一个高频坑:改完配置不等于马上生效。我见过很多次,同事改完sshd_config说配置不生效,一问才发现根本没有重启 sshd 服务。行规是:修改配置文件后,根据服务类型选择 restart 或 reload。语法检查先做,比如sshd -t检查 sshd 配置语法,nginx -t检查 nginx 配置,语法通过再 reload。

另一个实操建议:改配置前先备份。不要只靠复制粘贴,用cp /etc/foo.conf /etc/foo.conf.bak.20250301这种带日期的备份。尤其是改sudoers这种文件,强烈建议用visudo命令,因为它带语法校验。语法一旦错了,所有 sudo 都会失效,到时候你可就真的叫天不应叫地不灵,只能靠物理控制台救场了。

3.2/var:运行期间不断变化的数据

/var里最醒目的就是/var/log,系统日志和大部分应用日志都汇聚在这里。排查问题的时候,我会先看/var/log/syslog或/var/log/messages看系统整体情况,再看具体应用的日志目录,比如/var/log/nginx/access.log。

/var还藏着两个容量杀手。第一个是/var/log本身,日志不会自己删除,长时间不轮转能把磁盘写满。第二个是/var/spool,特别是邮件队列。我在某公司实习时遇到过一台服务器磁盘莫名其妙满了,du一看,/var/spool/mail占了 40 多 GB,原因是某个 cron 任务每次执行输出的结果都被系统当作邮件发给 root,日积月累堆满了。

清理日志有个非常隐蔽的坑:不要对正在写入的日志文件直接rm。因为文件被进程打开后,即使删除了,空间也不会立刻释放,反倒让你陷入“删了文件但磁盘还是满”的困惑。正确做法是truncate -s 0 /var/log/xxx.log,把文件截断,进程还能继续写,空间立刻释放。

3.3/usr与/opt:程序的正确归属

/usr是整个系统文件的主体,正常情况下我们不去手动改/usr/bin里的文件,这些都是发行版包管理器在管。自己手动编译安装的软件,默认情况下很多会装到/usr/local,/usr/local/bin、/usr/local/lib、/usr/local/etc都有自己独立的目录,与系统自带的/usr互不干扰。

这里要说清楚为什么推荐把手动编译的软件放到/usr/local而不是直接塞进/usr。系统升级的时候,/usr下的文件可能被包管理器整体替换,你手动装的东西很可能被覆盖或删除,或者和系统自带的同名工具产生冲突。而/usr/local是 convention 允许的本地扩展区域,基本不受升级影响,想卸载的时候把整个软件目录删掉,或执行make uninstall就行。

/opt的定位则是第三方独立软件,尤其那些自带完整目录结构的闭源商业程序,一般压缩包解压后整个扔进/opt/某个软件名,然后在/usr/local/bin或/usr/bin里建一个软链接指向它的可执行文件。这种做法的好处是软件的所有文件都在一个目录下,清理时删目录即可,不会把文件散落到系统各处。

3.4/home与/root:用户数据的隔离

/home下每个用户一个目录,目录权限默认 750 或 700,只有本人和管理员能进。用户在自己的家目录里可以随意放置文件、配置环境,这些文件的权限是用户自己掌控的。

家目录里有一堆点开头的文件,最常用的是.bashrc和.bash_profile。很多人分不清它们,其实记住一个原则就够了:.bash_profile是登录 shell 启动时执行,.bashrc是每次打开新的交互式 shell 时执行。服务器上通常没有图形登录界面,我一般把环境变量、别名这些放.bash_profile里,再让它 source 一下.bashrc,保证不管是登录还是开子 shell 都有一致的环境。

/root是系统管理员的家目录,普通用户默认没有权限访问,这也是系统的自我保护机制。管理员的个人脚本、备份文件、SSH 密钥经常放在这里,所以它的权限控制比普通家目录更严格。有些人图省事直接chmod 777 /root,等于把家门钥匙发给所有人,是极其危险的做法。

3.5/tmp与粘滞位:临时文件的安全约定

/tmp是所有人都能写的地方,但如果谁都能删别人的文件,那系统就乱了。Linux 的解决办法叫粘滞位(sticky bit),你可以在/tmp的权限位上看一个t字符。粘滞位保证在这个目录下,只有文件的所有者(或者管理员)才能删除或重命名文件,普通用户之间互相不能乱动对方文件。

看权限的时候,drwxrwxrwt中的t就是粘滞位。这个设计在共享目录场景下特别重要,比如公司服务器上团队共用的/shared目录,也常常设置粘滞位。

临时文件还有一个安全问题:不要用固定路径名。比如脚本里写/tmp/backup.tar.gz,容易被别人恶意预创建文件或软链接,把内容导向别处。安全做法是用mktemp -d生成一个随机目录名,用完全再删掉。我见过不止一次因为这个疏忽被黑的案例,所以现在自己写脚本涉及临时文件,一律mktemp。

4. 虚拟目录:/proc、/dev、/sys背后的内核通信机制

4.1/proc:内核和进程的实时视图

/proc是最颠覆直觉的目录,它里面的文件不占磁盘空间,是内核实时生成的一张“状态面板”。你cat /proc/cpuinfo看 CPU 信息,cat /proc/meminfo看内存信息,cat /proc/loadavg看系统负载,全都是内核直接输出的实时数据。

/proc下那些数字目录是进程 PID。某个程序出问题的时候,我会去看/proc/PID/fd,这里列出了进程打开的所有文件描述符。经典的排查场景是:磁盘空间显示被占用,但du找不到任何大文件,这时候lsof | grep deleted能发现进程拿着已经删除文件的句柄不释放,找到对应 PID,在/proc/PID下能看到它的真实路径,重启这个进程空间就回来了。

另外/proc/sys是可以写的,内核参数sysctl就是通过这里的虚拟文件调整的。比如临时开启 IP 转发,可以写/proc/sys/net/ipv4/ip_forward,不过系统重启后就恢复默认,需要持久化就写进/etc/sysctl.conf。

4.2/dev:设备即文件的具体体现

Linux 的设备都被抽象成文件放在/dev。硬盘叫/dev/sda、/dev/sdb,分区叫/dev/sda1,这些都是块设备;键盘鼠标串口属于字符设备;还有一些特殊用途的虚拟设备,比如/dev/null这个无底洞,任何写进去的东西都被丢弃。

/dev/shm也值得特别关注。它是一块共享内存,默认大小是物理内存的一半,属于 tmpfs 类型,存这里的数据在内存里,速度极快,但重启就没了。有些高并发程序会故意把缓存或临时文件放在这里换取性能。我遇到过有人把大文件拷进/dev/shm导致内存耗尽系统卡死,所以要记住:把这个目录当普通磁盘用是可行的,但是要清楚它消耗的是 RAM。

4.3/sys:内核与硬件的动态配置接口

/sys和/proc很容易被混在一起,但它们的定位不同。/proc更多反映进程和内核的运行时状态,/sys主要暴露设备和内核驱动的层次关系,而且提供了不少可写的配置项。

比如网卡调优时,看/sys/class/net/eth0/下面的speed、duplex、tx_queue_len,有些参数可以 echo 进去即时生效。还有/sys/block/sda/queue/scheduler是查看和切换磁盘 IO 调度器的入口。运维调优的时候,这里就是一个实时配置面板,但同样需要注意重启丢失的问题,持久化要落到对应的配置文件或 systemd 单元里。

/proc和/sys虽然看起来像普通目录,但千万别下意识往里存文件。数据大小是零,写入也只是被内核当作指令解析。把这两个目录当作 Linux 的“控制面板”来理解,比当作文件夹来理解要准确得多。

5. 排查问题的实战路线:从目录学起的排错方法论

5.1 磁盘满时按目录逐层看空间

磁盘满是最常见的线上事故之一,处理起来却最考验对目录的理解。我先说一套通用流程:

首先df -h确认哪个挂载点满了,比如根分区/显示 100%。然后进入根目录,执行du -xsh /* 2>/dev/null | sort -h,这个命令列出第一层目录各自占用的空间并排序。注意我加了-x参数,表示只统计当前文件系统,不跨越挂载点,否则外挂数据盘也会被统计进来,干扰判断。

看到是/var占大头,就继续du -xsh /var/* | sort -h往下一层层钻,直到定位到具体的日志目录或临时目录。这个过程就像剥洋葱,但每一层的du结果都直接指向下一步的方向。

定位到具体文件后,先确认它是否还被进程打开。如果被删除但进程还占用,前面说的lsof | grep deleted就能派上用场。如果没有进程占用,直接清空。需要说明的是,日志类文件强烈建议配置 logrotate 日志轮转,让系统按天或按大小自动切割压缩,而不是等到满了再手动清。这一套流程走下来,基本能覆盖绝大多数磁盘满的故障。

5.2 服务起不来时优先看的四个地方

服务启动失败的排查,也可以顺着目录的线索逐步收窄。我的固定顺序是四步:

第一步,systemctl status 服务名。这一步能告诉你服务当前状态、主进程 PID、最近几条日志,很多问题看到这里就已经清楚了。

第二步,journalctl -u 服务名 --since "5 minutes ago"。systemd 会把服务输出收集到日志里,这里经常藏着真正的报错堆栈。

第三步,dmesg | tail。如果服务是因为内存不足被 OOM killer 杀掉,或者段错误崩溃,内核会在这里留下记录。

第四步,去/var/log目录下找服务自己的日志文件。不是所有服务都走 journald,很多传统软件依然往/var/log下写文件,比如/var/log/nginx/、/var/log/mysql/。

举个我实际遇到的例子:某台服务器上 nginx 突然启动失败,systemctl status nginx只显示 failed,看不到明确原因。journalctl -u nginx看到bind() to 0.0.0.0:80 failed,马上意识到端口被占。接着ss -lntp | grep :80发现是一个残留的旧进程占着端口,kill掉旧进程后再启动,服务立即恢复正常。整个过程不到两分钟,靠的就是这个固定排查路径。

5.3 PATH 与目录顺序的关系

PATH环境的坑,属于那种不懂目录就特别容易栽跟头的问题。echo $PATH会看到一串用冒号分隔的目录,系统执行命令时按顺序从这些目录里查找同名可执行文件,先找到先用。

具体场景:系统自带 Python 在/usr/bin/python3,某开发者自己编译了一个新版 Python 并安装到/usr/local/bin/python3,这时终端里执行python3,实际执行的是谁?答案是看你 PATH 中/usr/local/bin和/usr/bin谁在前面。因为/usr/local/bin通常排在前面,所以一般是新版本生效。

排查这类问题用which -a会列出所有匹配的路径,type能告诉你最终会用哪一个以及为什么。我有一次排查某个项目一直调不到预期版本,就是靠type python3发现还是系统的旧版本在生效,原来那个开发者把新版装到了/usr/local/bin,但 PATH 里/usr/local/bin根本没配。目录权限、PATH 顺序、实际生效版本,这三者之间存在着微妙的关联,排查的时候缺一不可。

6. 我长期维护Linux目录的几个习惯

6.1 给/etc做版本管理

手动改动配置文件越多,越需要一个回溯机制。我的做法是把/etc变成一个 git 仓库,初始化账号信息、提交全部配置文件作为基线,之后每次修改之前先看git diff,改完确认没问题再提交。

实操命令很直观:

cd /etc git init git add . git commit -m "initial baseline"

之后每次改动前git diff看差异,改动后带上明确的提交信息,比如commit -m "update nginx worker_processes to 4"。某次把配置改坏了,直接git log找到上一次正常提交,用git checkout -- /etc/nginx/nginx.conf回滚单个文件就行。

这里有两个细节:一是把/etc/ssh/ssh_host_*、/etc/shadow这类敏感文件和临时生成的 socket 放到.gitignore里,避免密钥泄露;二是仓库只跟踪文本配置文件,二进制文件和运行期变化的数据不要纳入版本库。用/etc自己的 git 仓库记录每一次配置的来龙去脉,比任何运维笔记都可靠。

6.2 系统目录与数据目录分离

维护的机器多了之后,我强烈建议在安装系统时或部署应用前,就把系统盘和数据盘分开。系统目录/、/usr、/var单独一个分区,应用的数据放在独立挂载点,比如/data或/home。

这么做最直接的好处是隔离故障。系统分区被日志写满时,数据分区不受影响,服务可能还能继续运行,给你留出处理时间;反过来数据盘故障时,系统也能保持基本响应。而且升级系统、重装系统时,只要不格式化数据分区,业务数据就安然无恙。如果分区规划不合理,所有数据堆在一个根分区里,一次日志爆炸就能拖垮整个应用,这在我见过的事故里占了相当高的比例。

6.3 别让/usr/local沦陷

手动编译安装软件时,/usr/local是默认的 prefix,但我见过很多人的/usr/local/bin慢慢变成一锅粥,装的东西没有统一管理,想卸载不知道从哪入手,项目之间还互相覆盖依赖。

我的做法是给每个手动安装的软件建立独立的安装目录,典型路径是/usr/local/软件名-版本号,然后用软链接把可执行文件暴露到/usr/local/bin里。比如安装某个自编译工具,configure 时指定--prefix=/usr/local/工具名-2.1,编译安装完成后执行ln -s /usr/local/工具名-2.1/bin/工具名 /usr/local/bin/工具名。升级时装新版本目录,切换软链接指向即可;回滚时改软链接指向旧版本;彻底卸载时删目录和软链接,干净利落。

这套目录格局看得久了会发现,Linux 的目录体系就是在系统、用户、临时数据、虚拟接口之间划清了边界。边界清晰了,维护就有章法可循。我习惯把每次手动安装的过程和理由写成简短说明放在安装目录下,下次想卸载时看一眼就明白当时为什么装它。系统不怕复杂,就怕没有人说得清它为什么会变成这样。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 12:50:55

实时分析系统设计实战:从数据采集到查询优化的完整链路

1. 从“rea”这个标题说起:一个被低估的缩写背后藏着什么第一次看到“rea”这个标题的时候,我承认自己愣了几秒。三个字母,没有上下文,没有说明,放在任何一个技术社区里都像是某种暗号。但恰恰是这种极简的命名方式&am…

作者头像 李华
网站建设 2026/10/19 10:40:24

计算机系统四层数据流模型:从物理约束到协同机制

1. 这不是教科书翻页,而是系统级认知重建“计算机组成原理”这门课,对很多人来说,是考研路上一道绕不开的坎,也是技术面试中高频出现的“压力测试题”。但你有没有发现,哪怕把教材从头背到尾,一遇到“为什么…

作者头像 李华
网站建设 2026/10/18 9:08:49

远程控制PS5实战:AnyPS5串流、端口映射与网络优化指南

1. 从"躺在沙发上想玩主机游戏"说起:AnyPS5到底解决了什么事情是这样的。某天我加班到晚上十点,拖着疲惫的身体回到家,突然特别想玩一会刚买的PS5游戏,但人已经躺床上了,实在不想再爬起来走到客厅去开机器。…

作者头像 李华
网站建设 2026/10/19 0:05:36

批量清除脚本中的emoji:Python文本清洗与编码实战

前阵子我接手了一批跑了很多年的历史脚本,翻文件的时候头都大了:注释里、日志模板里、甚至临时变量命名后面,到处躺着表情符号。有些符号在当时那台机器上没事,换一台服务器就变成一串乱码,日志监控的关键词匹配也跟着…

作者头像 李华
网站建设 2026/10/19 15:18:16

AirLLM:内存映射与逐层调度,让超大语言模型在普通硬件上跑起来

1. 先说清楚:AirLLM是做什么的1.1 本地推理的第一道坎,永远是显存如果你最近折腾过本地大模型推理,大概率已经体验过被显存支配的感觉。稍微像样一点的对话模型,权重动辄几十GB,一张主流消费级显卡的显存根本塞不下。真…

作者头像 李华
网站建设 2026/10/19 3:08:28

基于Spring Boot+Vue的校园求职招聘系统设计与实现

每年到这个时间点,总能看到一批又一批的应届生在各种群里问:"有没有适合做毕设的题目?最好能兼顾简历和实用性的。" 说实话,每年被问到这种问题时,我通常都会推荐"校园求职招聘"这个方向。原因很简…

作者头像 李华