
它真正厉害的地方,是把复杂系统资源统一成可访问的接口
学 Linux 时,你一定听过一句话:一切皆文件。
这句话很经典,也很容易误解。
很多人第一次听,会以为 Linux 里所有东西都真的是磁盘文件。后来看到 /dev/ttyS0、/proc/cpuinfo、/sys/class/net,又开始迷糊:这些东西有的明明不是普通文件,为什么还说它们是文件?
这里要先纠正一下:
“一切皆文件”不是说所有东西都是磁盘文件,而是说 Linux 尽量把系统资源抽象成类似文件的访问方式。
这个思想非常重要。因为它是 Linux 应用访问硬件、内核信息、进程信息、设备状态的基础。
在我们日常理解里,文件可能是各种各样的,比如 .txt、.jpg、.bin。但 Linux 里的“文件”概念更广。
比如:
/dev/ttyS0 | |
/dev/input/event0 | |
/proc/cpuinfo | |
/proc/meminfo | |
/sys/class | |
/dev/mmcblk0 |
这些东西有些不是磁盘上的普通文件,但你可以用类似文件的方式打开、读取、写入或控制它们。
比如你读 /proc/cpuinfo,不是在读一个提前写好的文本文件,而是在读取内核动态生成的信息。
从内核角度看,重点也不是它有没有 .txt 后缀,而是它能不能挂进统一的文件系统视图,并提供一组可调用的操作。Linux 用 VFS,也就是虚拟文件系统,把普通文件、设备节点、procfs、sysfs 等不同对象接到同一套系统调用入口上。
所谓“像文件”,核心不是都存着一串字节,而是都能以文件对象的方式被内核管理。
当应用调用 read() 时,VFS 会根据这个对象背后的类型,把请求转给磁盘文件系统、设备驱动或内核中的信息提供者。应用看到的入口相似,真正干活的代码却可以完全不同。
Linux 应用访问普通文件、设备节点或 procfs/sysfs 节点时,通常会先 open(),然后得到一个文件描述符,也就是 file descriptor,简称 fd。
fd 本身不是文件,也不是内存地址。它只是当前进程文件描述符表里的一个整数编号,比如 3。内核顺着这个编号,才能找到真正的文件对象、当前读写位置、打开方式,以及背后的操作函数。
这个文件描述符可以指向很多东西:
管道和 socket 不一定通过 open() 创建,而是由 pipe()、socket() 等系统调用直接返回 fd。但拿到 fd 以后,它们同样可以进入 read()、write()、poll()、close() 这套操作模型。
你可以把文件描述符理解成一张取号牌。应用不一定知道背后是磁盘、串口、网络还是内核对象,它拿着这张号牌,通过统一窗口办事。

这就是“一切皆文件”的工程价值:上层使用方式被尽量统一了。
但要注意,接口相似不等于能力相同。普通文件可以 lseek(),管道通常不行;某个设备支持哪些 ioctl(),取决于它的驱动;有的对象只能读,有的只能写。统一的是操作框架,不是把所有对象硬掰成完全一样。
/dev 目录对嵌入式开发特别重要。
因为很多硬件设备会以设备节点的形式出现在这里,比如:
/dev/ttyS0/dev/i2c-1/dev/spidev0.0/dev/input/event0/dev/video0应用打开这些节点,就可以和对应设备交互。
比如串口程序打开 /dev/ttyS0,摄像头应用打开 /dev/video0,按键事件读取 /dev/input/event0。你不需要在应用里直接碰寄存器,硬件细节由内核驱动处理。
设备节点本身也不是“硬件内容保存成了一个文件”。它更像一个门牌号:应用打开这个门牌,VFS 再把后续操作转给对应驱动。并且不是所有硬件都会生成 /dev 节点,网卡等设备会通过各自的内核子系统暴露能力。
这就是 Linux 驱动和用户态应用之间的分工:
驱动把硬件接进内核,设备节点把能力暴露给用户态。
/proc 和 /sys 很容易让新手误会。
它们不是“假目录”,而是分别挂载了 procfs 和 sysfs。它们确实属于文件系统,只是内容主要不持久化在磁盘上,而是由内核按需生成或接收。
/proc 更偏运行时信息,比如:
/sys 更偏设备模型和驱动信息,比如:
简单记:
/proc | |
/sys | |
/dev |
这三个目录是你调嵌入式 Linux 时非常常用的观察窗口。
还有一个细节:有些 procfs 或 sysfs 节点可写,写进去不是在修改普通文本,而是在向内核下命令。使用前要先确认节点语义,千万别把 echo 当成无害操作。
如果没有“一切皆文件”这种统一抽象,应用访问不同资源就会非常碎。
访问串口是一套接口,访问摄像头是一套接口,访问内核状态又是一套接口,访问网络又是一套接口。系统越复杂,上层应用越痛苦。
Linux 的做法是尽量统一操作模型:
当然,实际情况并没有一句话那么完美。不是所有资源都有路径,也不是每个 fd 都支持所有操作。但整体思路是一致的:先把差异收进内核和驱动,再给用户态一套尽量稳定的访问模型。
这让 Linux 应用开发非常受益。
“一切皆文件”不是一句玄学口号。
它真正想表达的是:
Linux把很多系统资源抽象成类似文件的对象,让应用可以用统一方式访问。
普通文件、设备节点、procfs、sysfs、socket、管道背后完全不同,但在用户态看来,很多都可以通过文件描述符和一组系统调用来操作。
更严谨地说,“一切皆文件”是一种设计思想,不是一条没有例外的物理定律。理解成“很多资源都能进入 fd + 系统调用这套模型”,就不会再把它误解成“所有东西都在磁盘上”。
这也是为什么嵌入式 Linux 里经常要看:
/dev/proc/sys这几个目录不是“系统杂物间”,而是你理解 Linux 设备和内核状态的重要入口。
你第一次看到 /dev、/proc、/sys 时,是觉得清晰了,还是更懵了?