冷知识:bin、sbin 与 usr/bin、usr/sbin 目录的由来

在 Linux/macOS 系统的根目录 / 下,有这样几个目录:binsbinusr/binusr/sbin

青小蛙一直搞不懂为什么要这样,直到看了 BusyBox 的核心开发者 Rob Landley 在邮件列表中吐槽这件事,才终于明白为什么,堪称 Linux 冷知识呀。@Appinn

冷知识:bin、sbin 与 usr/bin、usr/sbin 目录的由来 1

说起来,这个冷知识的来源,也十分的冷门。在 2010 年(是的,16年前),BusyBox 的核心开发者 Rob Landley 在邮件列表中直接提到:

我发现 busybox 将其链接分散到这 4 个目录中,是否存在一条简单的规则来决定每个链接位于哪个目录?

例如,我看到 kill 命令在 /bin 目录下,而 killall 命令在 /usr/bin 目录下……我不明白。
弄清楚这背后的逻辑是什么。


为什么要分这么多目录?它们到底是干什么的?

答案有些简单,也有点出乎意料,这不是特意设计出来的,而是又一个历史遗留

这要从 1970 年代说起

Unix 诞生于 1970 年代,运行在 PDP-11 这样的古老机器上。
当时的硬盘有多大?1.5MB。

冷知识:bin、sbin 与 usr/bin、usr/sbin 目录的由来 2
底部是PDP-11/40 CPU,顶安装了一个TU56双磁带DECtape驱动器。

最开始,整个系统都装在根文件系统 / 里,其中包括:

  • /bin:基本命令
  • /sbin:系统管理命令
  • /lib:库文件

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

第二块硬盘

于是需要第二块硬盘,并挂载到 /usr 目录下。

(与 Windows 不太一样,没有 C 盘、D 盘。在 Linux 下,你可以把第二块磁盘挂载到 /usr 等任何目录下)

此时,就出现了四个路径:

  • /bin/sbin必须在系统早期启动时就能用的命令
  • /usr/bin/usr/sbin系统启动完成、挂载 /usr 后才能用的命令

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

先挂载磁盘才能用 mount 命令,但 mount 又在磁盘里 😂

为什么这种划分在今天已经不合理了?

Rob Landley 觉得,这套规则在现代设备,以及现代 Linux 中,已经没有意义了。

临时根文件系统

现代系统有临时根文件系统(initramfs / initrd)了,这是在内核启动后、真正的根文件系统挂载前,用来“过渡启动”的一个小型 Linux 系统。

冷知识:bin、sbin 与 usr/bin、usr/sbin 目录的由来 3

启动早期依赖的问题早就由临时根文件系统解决了,所以不再需要靠目录结构来“区分启动阶段”,

共享库

共享库是一份可以被多个程序同时使用的公共代码。它可以是:

/lib/libc.so.6
/usr/lib/libc.so.6
/usr/lib/libstdc++.so.6

没有共享库之前:

早期 Unix(1970s),程序是这样的:

  • 全部静态链接
  • 每个可执行文件里:
    • 都自带一整套函数代码
    • 比如字符串处理、IO、数学函数

举个极端但真实的例子:

ls 里有一份 printf
cp 里有一份 printf
mv 里也有一份 printf

这种方式的特点是:

  • 程序彼此完全独立
  • /bin/usr/bin 里的程序,可以来自不同磁盘、不同版本
  • “只升级 /bin,不动 /usr”在技术上是可行的

有了共享库之后:

好处巨大,节省磁盘空间、多进程共享内存、修一个漏洞,全系统生效。

但代价是程序和库“绑死”了,如果 ls 程序需要 libc.so.6 这个库,但 /usr/lib/ 目录下只有 libc.so.5,那么 ls 就无法运行。

这意味着,在共享库成为主流之后:

  • /bin 里的程序
  • /usr/bin 里的程序
  • /lib/usr/lib 里的库

已经不可能再被当成“可以独立升级、独立维护的部分”。

而 /bin、/usr/bin 这样的目录分离设计,正是建立在这一历史前提之上:
它们可以相互独立,甚至部署在不同的磁盘之上。

廉价的硬盘

对比 1970 年代,现在的硬盘已经廉价太多太多了,容量也不知道翻了多少倍。当然如今的价格比起前两年又涨了一点,但拉宽时间段,还是非常廉价。技术上进行分区调整也不是问题了。

当磁盘容量、分区调整都不再是问题时,当年为了“省磁盘”而产生的目录分离,也就失去了现实基础。

历史惯性下的新规则

你每天在用的 Linux 目录结构,其实是在为 1970 年代的一块 1.5MB 硬盘继续买单。

在历史惯性下,人们不断给这些目录强行赋予新定义,比如:

  • /:系统原生内容
  • /usr:发行版附加内容
  • /usr/local:本地安装的软件
  • /opt:第三方商业软件
  • 各发行版对 /tmp/var/tmp/usr/tmp 的规则还互相不一致

这最终导致缺乏统一逻辑增加了复杂度,本质上是在为一个早已消失的历史问题“打补丁”。

在现代 Linux 系统中,这样的目录结构已经几乎没有技术必要,却因为惯性和“标准”被延续至今。


原文:https://www.appinn.com/linux-bin-usr-directory-history/

写留言

Enable Notifications OK No thanks