bin、sbin 与 usr/bin、usr/sbin 目录的区别和由来

很多人第一次看到根目录都会懵:

复制代码
/bin
/sbin
/usr/bin
/usr/sbin

直觉会觉得:这肯定是精心设计 过的分层结构。

系统命令、用户命令、管理命令、扩展命令......听起来很合理。

但真正的答案是:

这不是设计,这是 50 年历史叠加出来的"化石结构"。

而这个真相,来自 BusyBox 核心开发者 Rob Landley 在 2010 年邮件列表里的一段吐槽。


一个连 BusyBox 作者都看不懂的目录规则

Rob 当时在做 BusyBox 链接布局时,发现一件非常离谱的事:

为什么 kill/bin,而 killall 却在 /usr/bin

到底有没有一条明确规则能解释这些目录?

结论是:没有。

这背后不是逻辑,而是历史偶然


故事要从 1970 年代说起

Unix 诞生在 PDP-11 上。

那时候的硬盘有多大?

1.5MB。

不是 GB,是 MB

整个系统最初都装在根文件系统 / 里:

复制代码
/bin   基本命令
/sbin  系统管理命令
/lib   库

后来系统越写越大,一块盘装不下了

怎么办?

加第二块盘。

但 Unix 没有 C 盘 D 盘的概念,第二块盘被挂载到 /usr

于是世界开始分裂了:

复制代码
/bin      在第一块盘
/usr/bin  在第二块盘

关键规则(当年非常重要)

当时形成了一条非常清晰、非常有意义的规则:

系统早期启动必须用到的命令 → /bin、/sbin
挂载 /usr 之后才需要的命令 → /usr/bin、/usr/sbin

这解决了一个真实存在的"先有鸡还是先有蛋"的问题:

你需要 mount 才能挂载第二块磁盘,

但如果 mount 在第二块磁盘里,你就永远挂不上它 😂

所以:

复制代码
mount → /bin
其他不重要的命令 → /usr/bin

在 1970 年代,这是非常聪明、非常必要的设计。


为什么这套规则今天已经失去意义?

1️⃣ 现代系统有 initramfs

现在内核启动后,会先进入一个临时根文件系统(initramfs)

所有"早期启动需要的东西",都在这里解决了。

不再需要通过目录结构区分启动阶段。


2️⃣ 共享库的出现,打破了"独立性"假设

早期 Unix 程序是完全静态链接的:

复制代码
ls 里有一份 printf
cp 里有一份 printf
mv 里也有一份 printf

这意味着:

/bin 和 /usr/bin 的程序可以完全独立存在

来自不同磁盘、不同版本、不同系统

这正是目录分离的技术前提。

但有了共享库之后:

复制代码
/bin/ls 依赖 /usr/lib/libc.so.6

如果库版本不匹配,程序直接无法运行。

从这一刻开始:

/bin、/usr/bin、/lib、/usr/lib

已经不可能再被当成"可以独立升级、独立存在"的部分。

而目录结构,正是建立在"它们可以独立"的历史前提上。

这个前提已经被共享库彻底摧毁


3️⃣ 硬盘早就便宜到不需要精打细算

当年分目录是为了:

节省 1.5MB 磁盘空间

今天你手机缓存都比这大几万倍。

磁盘容量、分区、挂载策略,都不再是问题。


于是就出现了今天的奇观

我们仍然在用一套:

为 PDP-11 和 1.5MB 硬盘设计的目录结构

然后后人不断给它强行补充新的解释

复制代码
/      系统核心
/usr   发行版内容
/usr/local 本地安装
/opt   第三方软件

再加上各发行版对:

复制代码
/tmp、/var/tmp、/usr/tmp

规则还互相不一致。

你以为这是"Unix 的精妙哲学"。

实际上是:

在给 50 年前的一个硬盘容量问题打补丁。


Rob Landley 的真实感受

Rob 的困惑非常真实:

我只是想知道,为什么 kill 在 /bin,killall 在 /usr/bin?

答案是:

因为历史。

不是因为逻辑。


现代 Linux 其实已经在"悄悄修正"这件事

很多新发行版已经开始做一件事:

复制代码
/bin      → /usr/bin 的符号链接
/sbin     → /usr/sbin 的符号链接
/lib      → /usr/lib 的符号链接

也就是著名的:

/usr merge

本质上就是承认:

当年这套分离,已经没有技术意义了。


结论:你每天都在为 1970 年代买单

Linux 目录结构并不是一套完美设计的产物。

它是:

PDP-11 → 磁盘不够 → 挂第二块盘 → 静态链接 → 共享库 → 现代硬件

一层一层叠出来的历史化石。

所以当你再看到:

复制代码
/bin
/usr/bin

你看到的不是"精妙设计"。

你看到的是:

一块 1.5MB 的硬盘,仍然活在你的电脑里。

相关推荐
szxinmai主板定制专家12 分钟前
电力设备RK3568/RK3576+FPGA,多系统混合部署Linux+RTOS RT-THREAD,强实时性
linux·运维·服务器·人工智能·嵌入式硬件·fpga开发
枕星而眠22 分钟前
Linux 四大进程/线程同步锁详解:互斥锁、读写锁、条件变量、文件锁
linux·c语言·后端·ubuntu·学习方法
我是坑货1 小时前
Jenkins 构建失败排查记录:mvn -U 把新版依赖被远程旧版覆盖
运维·jenkins
L、2181 小时前
CANN调优工具链全景:从profiler到tensorboard的完整观测体系
linux·运维·服务器·深度学习
xiaoshuaishuai81 小时前
C# 签名异常与Gas预估失败调试方案
开发语言·网络·tcp/ip·c#
其实防守也摸鱼1 小时前
软件安全与漏洞--软件安全编码
java·前端·网络·安全·网络安全·web·工具
码点滴1 小时前
Workload 自动化进化论:从手动运维到 AI 驱动的 Kubernetes 智能管控
运维·人工智能·kubernetes·自动化·workload
darkdragonking1 小时前
Docker(五)OpenEuler22.03 安装docker ce、排坑
运维·docker·容器
j_xxx404_1 小时前
Linux进程信号捕捉与操作系统运行本质深度解析
linux·运维·服务器·开发语言·c++·人工智能·ai
eggrall1 小时前
Linux信号——保存信号
linux·运维·服务器