前两天,我一个后端的同事跑过来问了我一个特别基础但又让人一时语塞的问题:新装的一台 Linux 机器上,根目录里那几个dev、sys、proc到底是不是真的文件夹?他说用du -sh /proc看一眼占用不到 1M,但里面文件又多得离谱,这数据结构难道是硬盘上真实存在的吗?
这个问题问得挺好的。虽然我们天天在 Linux 上敲命令,但真正被问到dev、sys、proc的底层原理时,很多人会卡壳。这不能怪大家基础不扎实,而是这三个目录确实“反直觉”——它们看起来像普通目录,实际上根本不在磁盘上。这篇文章我就把这些年的实战经验和踩过的坑掰开揉碎讲清楚,读完你不仅能回答“它们是什么”,还能知道“它们能用来干什么”,更重要的是搞懂“为什么 Linux 要这么设计”。
先说结论:dev、sys、proc都是挂载在根文件系统里的虚拟文件系统,它们由内核在内存中动态生成,不占磁盘空间,是内核与用户态进程打交道的关键桥梁。理解它们,你才算是真正入了 Linux 运维和开发的门。
1. 为什么要搞懂这三个目录:核心思路与整体设计
Linux 的设计哲学里有一句名言:“一切皆文件”。这句口号听着很爽,但只凭它是理解不了这三个目录的。真正的理解点在于:用户态进程不能直接访问内核内存,内核也不能把数据随便丢给用户态程序,因为存在权限隔离。那么两者之间怎么通信?总得有某种约定好的接口。procfs、sysfs、devtmpfs就是内核为这种通信专门设计的“中间人”。
打个生活化的比喻:你在一家餐厅吃饭,厨房是内核,客人是用户态进程。客人不能直接冲进厨房看菜切好了没有,于是餐厅设置了一个出菜口。procfs、sysfs、devtmpfs就是不同类型的出菜口——有给客人看菜品进度的窗口(proc),有给餐厅管理电脑查看设备状态的窗口(sys),有让客人直接取餐具和调料的窗口(dev)。它们都是虚拟出来的“通信窗口”,窗口背后的厨房本身并没有变。
这三个目录在系统里的角色可以分成这么几层:
proc:以进程为中心,把进程信息、系统统计信息、内核参数暴露出来,强调“运行时快照”。sys:以设备为中心,把内核设备模型、总线、驱动、类别的层级关系暴露出来,强调“设备拓扑”。dev:以文件接口为中心,把字符设备、块设备映射成文件节点,强调“访问入口”。
1.1 三个目录的定位差异
很多老手也会把这三个目录搞混,尤其是proc和sys,总觉得都是只读文件、都能看内核信息。但实际上它们的“服务对象”完全不同。
procfs最早诞生,目的很单纯:让用户态进程能看到自己和其他进程的信息。后来功能越加越多,什么内存使用、CPU 统计、网络连接、内核参数全塞进去了,逐渐成了个“杂物间”。而sysfs是为了解决设备管理问题被引入的,它的核心逻辑不是“按进程组织”,而是“按设备类型组织”,把设备和驱动程序的层次关系用目录树展示出来,让用户态可以按设备拓扑自由查找。
devfs则走的是另一条路线:它把硬件设备统一抽象成“文件节点”,内核自动创建设备文件,用户态通过 open/read/write 直接操作。早期 Linux 里/dev下的节点要么靠静态makedev脚本生成,要么靠devfs,但后来统一到了devtmpfs+udev的配合模式。这个演进过程我在第 4 节详细讲。
1.2 两个底层机制决定了一切
这三个目录能“以文件形式呈现内核数据”,靠的是两个底层机制:VFS 虚拟文件系统层和文件操作回调函数。
VFS 是 Linux 文件系统面向用户态进程的“统一门面”。不管底层是 ext4、XFS 还是内存里的伪文件系统,只要实现了 VFS 规定的file_operations接口(比如.read、.write、.open、.release),用户态就能用最基本的read()、write()系统调用来访问。procfs、sysfs本质上就是一组实现了这些回调函数的内核对象,每次你cat /proc/meminfo时,VFS 会调用 procfs 注册的.read回调,内核在该回调里现场拼出/proc/meminfo的最新内容返回给你。
明白了这两个机制,你就能自然推理出很多结论:
- 你看到的内容是动态生成的,不是磁盘上某个静态文件。所以每次
cat内容都可能不一样。 - 文件大小对不上是正常的。普通文件 ls 显示大小就是实际占用,而伪文件系统里的文件大小往往是 0 或假报的数字,因为数据是即时计算的。
- 写入能生效不是“改写文件”。你
echo 1 > /proc/sys/vm/drop_caches时,内核的.write回调会解析输入的数字并执行对应行为,而不是真的把“1”这个字符串存进去。
这三个目录的设计其实解决了一个所有操作系统都绕不开的问题:内核状态的可观测性和可控制性。没有它们,你连 CPU 占用率都看不见,更别提动态调整内核参数了。
2. proc 目录:系统的实时体检单
proc目录在绝大多数发行版里都挂在/proc,类型是procfs。它给你的第一感觉是“文件太多太杂”,但只要你掌握了里面的组织逻辑,它就是系统排障的第一站,作用好比一份实时变化的体检单。
2.1 关键的运行时信息文件
/proc根目录下最显眼的是一堆进程数字目录,每个数字对应一个活着的进程的 PID,比如/proc/1234/。这是 procfs 最初的核心用途。每个进程目录下面又有一批标准文件:cmdline是该进程的启动命令,environ是环境变量,cwd是指向工作目录的软链接,exe是指向可执行文件的软链接,fd/目录里是这个进程打开的所有文件描述符,status和stat则给出了进程状态、内存占用、父进程 PID 等基础信息。
举个例子,你想知道一个进程到底启动时带了什么参数,不需要翻 systemd 单元文件,直接:
cat /proc/1234/cmdline | tr '\0' ' '输出里的空字节会被转成空格,就能还原完整的启动命令了。这个方法在排查“这到底是什么进程”时极其好用。
除了进程目录,/proc根目录下的其他文件也是高频使用的宝贝:
| 文件路径 | 作用 | 我的实际用法 |
|---|---|---|
/proc/meminfo | 内存统计,含 MemTotal、MemFree、Buffers、Cached 等 | 写监控脚本时第一抓取目标 |
/proc/cpuinfo | CPU 型号、核心数、标志位 | 确认 CPU 型号和扩展指令集 |
/proc/loadavg | 1/5/15 分钟平均负载 | 快速判断系统是否繁忙 |
/proc/uptime | 系统运行时间和空闲时间 | 计算 CPU 使用率 |
/proc/net/dev | 每个网卡的收发字节、包数和错误数 | 排查网络丢包 |
/proc/interrupts | 各 CPU 上的中断分布 | 调优网卡多队列中断绑定 |
/proc/zoneinfo | 内存区域详情 | 排查内存碎片化问题 |
这些文件没人维护会过时吗?不会,因为它们不存数据,每次读取都是内核现场“画”出来的。/proc/loadavg每次 cat 都是当时的最新状态,这个是它和普通日志文件最大的不同。
2.2 /proc/sys 内核参数调整
/proc/sys是整个 procfs 里最“危险”也最“有用”的一层。它下面的子目录按子系统划分,比如net/、vm/、kernel/、fs/,每个文件对应当前运行中的内核参数。比如最常见的网络转发开关:
cat /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/ip_forwardecho 1 >的瞬间,内核的ip_forward参数就变成了 1,无需重启、无需重载服务。这就是 procfs 的设计初衷——把内核参数暴露为可读写文件,让系统管理员可以在运行中调整。
不过这里我用过的最高频参数还有几个值得单独提:
vm.swappiness(/proc/sys/vm/swappiness):控制内核使用 swap 的倾向程度,测试环境调成 0 或 10 很常见。vm.max_map_count:进程能拥有的最大内存映射区域数,某些 Java 或 Elasticsearch 程序容易因默认值偏小崩掉,我调过很多次。net.ipv4.tcp_tw_reuse:TCP 连接 TIME_WAIT 复用开关,高并发短连接场景下经常需要调。kernel.sysrq:紧急系统请求键功能,出问题时能帮上大忙。
但要提醒你,直接 echo 写的改动只对当前运行状态生效,重启后就会丢。想固化到配置文件,得写到/etc/sysctl.conf或/etc/sysctl.d/下,再执行sysctl -p加载。我的习惯是先在命令行临时调,确认效果稳定再固化,避免“调坏了回不去”的尴尬。
2.3 实用的排查技巧
procfs 的排障价值远不止看几个数值,它还是追踪问题的路标。
先说进程不可删除的问题。有时候一个文件被进程占用,rm -rf删不掉,会提示“Device or resource busy”。这时候去/proc/<pid>/fd/目录看看:
ls -l /proc/1234/fd/ | grep deleted系统里被删但仍被进程持有的文件会标注(deleted),根据路径定位到具体进程后,重启或让进程释放文件描述符,磁盘空间才能真正释放。我遇到过多次“磁盘明明没满 df 却 100%”的情况,最后全靠/proc/*/fd/找到罪魁祸首。
再看进程内存诊断。/proc/<pid>/status里的VmRSS是常驻物理内存,VmSize是虚拟内存总量。如果进程虚拟内存高得离谱,别急着判定内存泄漏——先看/proc/<pid>/maps,这个文件列举了进程的全部虚拟内存映射区域,能区分是共享库占用、堆内存膨胀还是匿名映射过多,避免监控误判。
顺带分享一个我压箱底的经验:排查频繁的systemd-coredump或 OOM Killer 问题时,优先去/proc/sys/kernel/panic_on_oom、/proc/sys/vm/panic_on_oom看配置,再做调整,不要盲目以为调大内存就行。
3. sys 目录:内核的设备管理中枢
如果说/proc是个“按进程和子系统分类”的杂货铺,那/sys就是一个按设备拓扑整理的仓库。它挂载类型叫sysfs,在内核 2.6 时期引入,设计目的很明确:把内核的设备模型完整暴露给用户空间,同时让用户空间有能力对设备做细粒度的配置。
3.1 sysfs 与 procfs 的分工
很多新人对sysfs和procfs的边界感到模糊。我的理解是:procfs回答“现在怎么了”,sysfs回答“设备长什么样、该怎么配”。
/proc给你的是瞬时状态和统计值,比如 CPU 使用率、内存余量、网络吞吐;而/sys给你的是设备本身的属性,比如磁盘的厂商型号、几号总线、支持哪些队列、在线还是离线。运行时的“读仪表盘”找proc,做“设备管理和配置”找sys,这个方向基本不会错。
比如说网卡,/proc/net/dev给你的是收发字节数、丢包数,这是流量统计;而/sys/class/net/eth0/下面则是网卡的速度、MAC 地址、队列数量,这是网卡属性。两者配合起来,才能完整判断一个网卡的健康状况。
3.2 设备模型与树形结构
sysfs 最重要的设计,是把内核的设备模型搬到了目录树里。你进入/sys/bus/、/sys/class/、/sys/devices/、/sys/block/就能感受到这套结构。
/sys/devices/是真实设备的物理拓扑,按照总线、控制器、插槽号逐级往下排。/sys/bus/按总线类型(如pci、usb、i2c、platform)组织,每条总线下面有devices/和drivers/,能看到驱动和设备的绑定关系。/sys/class/按设备功能分类,比如net表示网络设备,block表示块设备,gpio表示 GPIO 控制器,thermal表示温控。/sys/block/则是块设备的独立入口,像/sys/block/sda/、/sys/block/nvme0n1/。
这套树状结构不是拍脑袋定的,它直接映射了 Linux 内核的kobject层级关系。每个内核对象在 sysfs 里都是一个目录,对象的属性则是文件。设备驱动只要注册了kobj_type和属性组,sysfs 就会自动生成对应文件,无需每个驱动单独实现文件系统操作。这也是为什么你插入一个 USB 设备后,/sys/bus/usb/devices/下会立刻多出一个目录——内核的热插拔事件自动更新了 sysfs。
3.3 常见运维调整示例
sysfs 的创新不只体现在“看设备”,更在于“调设备”。很多硬件配置不需要厂商专用工具,直接对/sys下的文件读改写就能完成。
最经典的是调整磁盘队列的调度算法。你可以先读当前调度策略:
cat /sys/block/sda/queue/scheduler如果输出[mq-deadline] none,表示当前用的是 mq-deadline。想切换到 none(完全直通模式,适合 NVMe SSD 场景)可以这样:
echo none > /sys/block/nvme0n1/queue/scheduler某些高并发随机读场景下,这个调整能让延迟更好看。但要注意,/sys/block/sda/queue/下的文件只代表当前设备的队列配置,重启后同样会重置,要固化就得写到 udev 规则里。
再举一个 CPU 调频的例子。笔记本或低功耗服务器默认会跑在省电策略,你要全速跑任务时可以按 CPU 设置调速器:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor想对所有 CPU 一致调整,用循环配合for语法即可。
还有个运维高频操作是查看和修改中断的 CPU 亲和性。中断信息在/proc/interrupts,但对应 IRQ 的可配置文件在/proc/irq/<irq>/smp_affinity。调整前先看 CPU 分布,再写十六进制掩码,比如让 IRQ 78 只绑到 CPU2:
echo 4 > /proc/irq/78/smp_affinity这套组合拳在网卡多队列调优时非常实用。
4. dev 目录:设备访问的入口
很多入门的文章爱把/dev说成“设备文件目录”,但它到底是怎么来的、和sys、proc有什么关系,基本都不细讲。我这里把从静态设备节点到现代设备管理的演变过程说清楚。
4.1 字符设备与块设备
Linux 里设备文件主要分两大类:字符设备和块设备。字符设备按字节流读写,适合串口、终端、键盘这类设备;块设备按固定大小的块读写,支持随机访问,比如磁盘和 SSD。
ls -l /dev时,第一列开头的字符能快速区分它们:
c开头就是字符设备,比如/dev/null、/dev/ttyS0。b开头就是块设备,比如/dev/sda。
两类设备访问方式不同,所以设备文件也必须区分。你不可能用读字符串的方式去读一个磁盘块设备,设备节点类型定错了会直接报错。
4.2 设备节点的由来
在很早期的 Linux 系统中,/dev下的节点是预先静态生成的,系统安装时就有人把一堆设备文件用mknod创建好。这样做的问题很明显:你永远没法预知用户之后会插什么新硬件,新设备插上去还得手动mknod,静态文件也容易和真实设备失配。
后来内核引入了devfs,由内核自己维护设备节点,插入硬件时自动生成文件,看起来解决了问题。但 devfs 有不少设计缺陷,比如命名不确定、无法用户定制权限,于是又被devtmpfs取代。
现代 Linux 的做法是组合拳:内核启动早期挂载devtmpfs到/dev,内核每探测到一个设备就在该文件系统里自动创建对应的设备节点;用户态再由 udev(现在通常是systemd-udevd)根据规则做符号链接、设置权限、加载固件。
所以你在/dev/disk/by-uuid/里看到的那些软链接,并不是内核生成的,而是 udev 根据设备属性生成的。内核只保证/dev/sda这种基础节点存在,业务友好的路径名由 udev 来补全。
4.3 设备号与节点的关系
设备节点本身不占空间,它记录的只是一对主设备号和次设备号。主设备号说明这个设备绑定了哪个驱动,次设备号说明是同一类驱动下的第几个设备。举个直观例子:
ls -l /dev/null输出类似:
crw-rw-rw- 1 root root 1, 3 Jan 1 00:00 /dev/null这里的1, 3就是主设备号 1、次设备号 3。主设备号 1 代表字符设备组mem,次设备号 3 代表 null。
如果你好奇/dev/sda的编号,执行ls -l /dev/sda,会看到8, 0。主设备号 8 被分配给 SCSI 磁盘类驱动,不同的次设备号映射到不同的物理盘或分区。
理解设备号后,你就能看懂mknod命令有什么用——它本质上就是手工创建一个设备节点,告诉内核“把某对设备号对应到设备路径上”:
mknod /tmp/mydisk b 8 0这样/tmp/mydisk就指向了主设备号 8、次设备号 0 的块设备。但说实话,现代系统里几乎不需要手工执行mknod,除非你在做内核驱动开发或者修复一个坏掉的 /dev。出了这种事故,优先用的还是udevadm trigger让内核重新生成节点,而不是自己硬造。
5. 三者如何协同运作:实操过程与关键环节实现
理解了三个目录各自的分工,最难但最值钱的问题是:它们三个是怎么配合起来干活的?我挑选几个真实场景,把协同链路完整走一遍,你会发现它们从来不是孤立的。
5.1 排查网络丢包:proc 看统计、sys 看队列、dev 看接口
有一次我在一个负责高并发网关的机器上发现数据包偶尔丢失,抓包看不出问题,但上层接口监控确确实实报错。排查时我先打开/proc/net/dev,发现eth0的rx_dropped计数在增长,说明内核确实丢弃了收包。但具体丢在哪一环节呢?我又去/sys/class/net/eth0/statistics/里面对比rx_dropped、rx_missed_errors和rx_fifo_errors,从而锁定是环形缓冲区溢出导致丢包。最后调整的是ethtool -G eth0 rx 4096,再回/proc/net/dev观察计数是否还在涨。整个过程proc、sys、dev三处轮转,少了任何一个都不好定位。
从文件系统视角看:/proc/net/dev是 procfs 内核统计导出的典型;/sys/class/net/是 sysfs 设备模型入口的典型;ethtool命令本身则是通过 ioctl 直接控制设备驱动读写设备节点或 sysfs 属性。要说哪个目录更重要,真说不出来——缺一环排查链路就断了。
5.2 动态加载驱动并生成设备节点
假设你给一台机器加了一张新网卡或者别的 PCIe 扩展卡,系统没有立刻出现对应的/dev节点或/sys属性。此时你打开/sys/bus/pci/devices/,能看到这个设备的 PCI 地址和 vendor/device ID,但没有对应驱动目录。
这时你怎么知道该绑定哪个驱动?去/sys/bus/pci/drivers/下列出已注册的驱动,找到匹配项后手动绑定:
echo "0000:03:00.0" > /sys/bus/pci/drivers/vendor_driver/bind绑定成功后,内核会自动触发设备模型更新,随后 udev 会检测到新设备并创建/dev下对应的节点。整个过程里,你先是靠sysfs读取设备拓扑,再通过写入 sysfs 控制驱动绑定,最后设备节点出现在devtmpfs里。这一步能否顺利,取决于内核配置、设备驱动是否齐全和 udev 规则是否正确。
如果设备节点确实没生成,快速判断方法是用udevadm monitor看内核发出的 uevent 事件流。内核检测到设备变化时,会把add、remove、change等事件通过 netlink 发给用户态的 udev,udevadm monitor能把这些事件实时打出来,帮你看清 udev 是否收到了设备事件。
5.3 容器场景下的协同与隔离
现在很多人的服务跑在容器里,而容器对/proc、/sys、/dev的处理天然带着“隔离”需求,但又不能彻底隔离。容器里的/proc大多只展示容器内进程,比如 top 在容器里默认只能看到容器自己的进程;但/proc/sys下的很多文件仍然直接指向宿主机的内核变量,你在容器里echo 1 > /proc/sys/net/ipv4/ip_forward是有可能直接影响宿主机内核参数的,不处理权限就会成为风险点。
如果你运行特权容器,或者给容器加了CAP_SYS_ADMIN权限,那么挂载进去的/sys和/proc会映射到宿主机内核,写入就必须格外小心。我给团队定的规矩是:容器内默认只读查看/proc和/sys,要改内核参数一定走宿主机执行,并且先在测试机验证。
/dev在容器里少得多,容器通常只有null、zero、random、urandom和tty等少数几个节点。需要给容器直通 GPU 或 USB 设备时,必须在创建容器时显式挂载对应设备节点,比如 Docker 的--device /dev/nvidia0:/dev/nvidia0,本质就是把宿主机的设备节点映射进容器。这也解释了为什么给你的容器加--device参数不指定设备时,容器里压根看不到那些硬件——因为/dev目录不是自动全量映射的。
5.4 三者的协同总结
经历过的几个案例让我形成一个很实用的习惯:排查任何设备相关的问题,都会按“先在/dev确认节点存在和类型,再进/sys看设备属性和驱动绑定,最后去/proc看运行时统计”的顺序过一遍。这个顺序本质上是沿着“设备存在—设备状态—设备性能”的链路走的。
如果上面的顺序反过来,效率反而低。你都不知道设备节点存在与否,就急着看统计,很容易被误导。
6. 常见问题与排查技巧实录
下面这几个问题都是我或身边同事实际踩过的坑,整理成速查表方便你对照排查。
| 现象 | 排查方向 | 解决方案 |
|---|---|---|
du -sh /proc占用极小,但ls -l /proc文件成千上万 | 伪文件系统不占磁盘空间,文件大小无意义 | 正常现象,不要试图清理 /proc 下的文件 |
| 删除文件后 df 显示空间没释放 | 进程仍持有已删除文件的 fd | 用 `lsof |
| 容器里 echo 修改内核参数失败,或意外改动宿主机 | 容器权限不足,或容器内/proc/sys映射宿主机 | 在宿主机执行修改,或用特权容器并严格确认目标 |
| 设备节点存在但读写报 ENODEV 或找不到设备名 | 设备未正确绑定驱动,或设备号不匹配 | 用dmesg看内核日志,检查/sys/bus/<bus>/drivers/并手动 bind |
查看/sys/class/net/eth0/statistics/rx_dropped数值一直涨 | 网络收包队列溢出 | 先ethtool -S eth0确认丢包类型,再调整ethtool -G环形缓冲区 |
/proc/interrupts里某个中断集中在一个 CPU,性能不均 | 中断亲和性未配置或配置不当 | 改/proc/irq/<irq>/smp_affinity并固化到启动脚本 |
/dev/disk/by-uuid/xxx符号链接失效 | 块设备 UUID 改变或 udev 规则被改写 | 用blkid重新确认 UUID,检查/etc/udev/rules.d/规则 |
写入/sys或/proc文件报 Permission denied | 文件只读,或缺少 CAP 权限 | 确认属性是否可写、当前用户权限、容器 capability |
6.1 du 命令看伪文件系统没用
伪文件系统会让人误判磁盘空间,因为du -sh /proc可能显示不到 1MB,而里面的文件数却是海量。原因很简单:这些文件内容是通过内核代码现场生成的,没有磁盘块真正存储它们。所以你千万别想“把 /proc 里的文件删了减负”,这些文件删掉会有不可预期的影响。
比如有人试图rm /proc/uptime来“清零开机时间”,结果直接把系统搞不稳定了。伪文件系统节点不是普通文件,它背后关联着内核数据结构和函数。你要“清理”它,只能调整内核参数或重启相关子系统,不能把它当普通日志删。
6.2 读大量 proc 文件有 CPU 开销
虽然这些文件不占磁盘空间,但每次读取都要内核现场“攒”数据,频繁读取仍会消耗 CPU。尤其在写监控脚本时,如果你用了个笨方法,每秒钟循环读取/proc下几千个进程的所有文件,系统负载会肉眼可见地升高。
我的建议是:进程信息按需抓取,不要全量扫描;如果真需要全量进程快照,用ps aux或top -b -n 1这类封装好的工具,它们底层做了优化;监控系统优先使用node_exporter、prometheus这类成熟采集器,别自己造轮子轮询/proc。
6.3 内核文档和源码是终极查询文档
当你在/sys里看到一个不知道意思的属性文件,最可靠的方法不是上网搜索,而是查内核文档。目录Documentation/里有 sysfs 和 procfs 的说明文档,不同发行版可能在/usr/share/doc/kernel-doc*下,也可以直接去内核源码仓库在线阅读。除了文档,/sys下的很多属性还有uevent、modalias这类只读接口,它们本身就能告诉你设备的模块别名和总线信息。
实战里我最常用的“找规律”方法是:把/sys/bus/<bus>/devices/<device>/和/sys/class/<class>/对比看。前者是从总线视角看设备,后者是从功能视角看设备,两个视角一交叉,属性归属和用途就清晰了。
6.4 趁手的工具补充
查设备、看事件、核参数,除了直接操作文件,我还习惯搭配几个工具:
lshw:能给出完整的硬件树,输出会从 sysfs 读取数据。lsblk:快速查看块设备拓扑和挂载关系,底层信息主要来自/sys/block/。lspci -v/lsusb -v:读取/sys/bus/pci/devices等目录信息,直观展示设备和驱动。udevadm info:查看设备属性、规则匹配情况,是调试 udev 规则的神器。sysctl:封装/proc/sys和/etc/sysctl.conf的高层工具,临时和永久修改都靠它。
这些工具本质上还是在读这三个虚拟文件系统的数据,但输出更人性化。我在生产环境排查时通常先跑它们拿大图,再进具体目录确认细节,效率比直接find /sys高得多。
写在最后:一点心得和提醒
这三个目录的深层价值不在于“它们是文件系统”这个事实,而在于它们把内核的实时状态和控制接口,以统一的方式暴露给了用户空间。我刚开始接触 Linux 时,总觉得内核像黑盒,出了问题只能重启。后来学会看/proc、调/sys、认/dev,系统才变得“透明”起来。再后来搞内核驱动开发,更是离不开这三个目录——调试时每一处节点对应的内核代码我都翻过。
最后分享一个我自己的小习惯:新拿到一台机器,我会先花几分钟把/proc/meminfo、/proc/cpuinfo、/sys/block/*/queue/scheduler、/sys/class/net/*/statistics/这几个关键文件扫一遍,心里有个基线。之后系统出现了异常,对比基线就能快速发现变化。这个习惯帮我节省了大量排障时间,也让我对内核的运行规律有了更直观的感知。你在学习和实操中如果遇到奇怪现象,千万别只盯着应用日志,多去这三个目录里转一转,答案往往就在那些“虚拟文件”里写着呢。