这是一篇转载的文章,介绍《UNIX痛恨者手册》这本书的,原文链接,我是想放这本书的下载链接,第一个是中文版,第二个是英文版
UNIX 痛恨者手册可以算是一本奇书了。一般的技术书,写作缘由大多是作者特别喜欢某样技术,兴高采烈地拿出来和读者分享。而此书的几个作者,都是因为恨 UNIX 恨到“人生长恨水长东”的境界了,于是乎搞了个邮件组,广泛收集各种愤怒,最后基于邮件组里面张贴的各种抱怨,编撰成了痛恨者手册这样一本书,来专门宣泄对 UNIX 的愤怒,也算得上是空前绝后了。
尽管这本书视角独特,以现在的眼光看,作者的抱怨中,真正属于 UNIX 固有问题的只占 50%,其他如对 sendmail 排山倒海的批评,对 C++ 的尽情嘲弄,实际上都不属于 UNIX 系统特有的。其他的 50%,则颇有历史意义,可以看到当年的 UNIX 系统是何其的“原始”。特别是对照现在的 Linux 来看,可以看出 Linux 作为当年 UNIX 的继承人,在文件系统,安全性,稳定性等等方面的巨大的进步。
除去一些对 UNIX 中具体 BUG 的批评,这本书的背后实际上是三种设计哲学间的交锋,我把这三种哲学叫做 MIT 哲学,UNIX 哲学和 GUI 系统哲学。“MIT 哲学”这个词,是借用那篇著名的 Worse is better 文章中的叫法。MIT 哲学的代表是 LISP 机器,即提供一个 LISP 环境的机器。这个机器提供给用户的,是优雅的编程环境,如统一的内存管理,统一的函数式接口,良好的文档等等,一切程序员所需要的,都给准备好了。但这个系统不管是作为个人计算机还是作为工作站都没有获得成功。
GUI 系统哲学从施乐的 Alto 开始,到90年代中期 Windows 95 出现之前,已经颇有气象,特别是在个人计算机领域,几乎所有的个人计算机厂商都在提供自己的图形界面操作系统。GUI 系统的哲学,是友好的用户界面和一致的使用体验。至于具体的功能,则委托给具体的应用程序实现。
而 UNIX 哲学,则像是一种开放式系统的哲学:除去提供统一的系统调用和标准工具外(POSIX),不强调系统的一致性。UNIX 像是一堆松散的积木堆起来的一个系统,在遵守 POSIX 标准的前提下(其实是个非常松散的标准)各个厂商都可以自己选择积木搭建系统。
UNIX 这种开放的,允许自由搭积木的做法,是和信奉MIT哲学的人水火不容的。这些用户在 UNIX 的因为开放造成的不一致性上尽情吐槽。比如说,UNIX 一个饱受诟病的缺憾是其命令行参数不统一。在命令行下,有的命令加 -h 是显示帮助,有的却是显示隐藏文件,还有的命令压根不接受 -h 参数。这样的问题,反映了 UNIX 在演化过程中缺少一个统一的规划。这在演化路径单一的其他操作系统上是不可想象的。再比如,UNIX 的计算模型很简单,即用 C 语言和 shell 对系统调用做一个胶水包装,不提供内存管理也不提供异常处理,文件系统也很低级,不支持文件恢复也不支持文件的元信息存储。而 MIT 的LISP 机器的计算模型和存储系统看上去都更加高级,统一的函数式接口,自动内存管理等等。用过 LISP 机器的人自然不习惯 UNIX 这种看上去“低级”的操作系统。结果是,用过 LISP Machine 的用户除了抱怨 UNIX 外,只能寻求在 UNIX 上构建一个新的层,来弥补 UNIX 的不足。这事情的一个结果就是造就了Emacs 这个怪兽,到最后几乎所有能在 UNIX 里做的事情,都能在 Emacs 里完成。这样,除了操作系统内核外,Emacs 完全取代了 UNIX 环境。Emacs 功能强大到大家都同意 Emacs 是个万能软件,而 vi 用户则开玩笑说 Emacs 是个缺少一个好编辑器的操作系统。大家都知道,Emacs 的作者正是从 MIT 出来的 Richard Stallman。
痛恨者手册的作者也是在 MIT 的 AI 实验室工作多年的技术人员。为了解释 UNIX 的成功,他借用了 Worse is better 中的说法(Garbriel 断言 C 语言和 UNIX 是终极计算机病毒),把 UNIX 归类为世界上第一个计算机病毒。书中提到,UNIX 和病毒的共同特征为:体积小,可传染多种宿主(可移植),变异快速等等。书中说, UNIX 的普及并不是因为它在技术比其他操作系统更加优越,只是因为可移植,可传染和变异快,才占据了很大一块用户份额。
这个解释我认为是相当精当的。相对于其他操作系统,UNIX 基于C书写,可移植和早期的免费分发方式,即使技术上不够好,仍然像流行性感冒一样蔓延。一传十,十传百,快速攻城略地。当时 UNIX 的风行程度可以从几个侧面来证明。八十年代初雨后春笋一般地冒出了很多新的UNIX公司,SUN 和 SGI 就是是借着 UNIX 成长起来的典型例子。他们短短几年间就靠 UNIX 工作站业务跑上了纳斯达克。微软和苹果是靠个人电脑业务起家的,各自都有自己的操作系统,却也跑到UNIX世界下注,都曾经推出过自家的UNIX发行版(分别叫做 Xenix 和 A/UX)。UNIX这个”病毒”在工作站和服务器上的寄生能力极强,直到后来演化能力和传播能力更强的“病毒” Linux 的出现,加上 .COM 泡沫破裂的一场大洗牌,才把 UNIX 的市场份额压了下去。Linux 则彻底继承了所有的“病毒”特性,除去原有的体积小,可移植外,通过开放内核源代码,造就了现在从超级计算机服务器到嵌入式系统无处不在的现状。从设备总量来说,世界上从未有一个操作系统如 Linux 如此成功。
可惜的是 MIT 哲学派本身没有成功的操作系统产品用来作为比较(除了Emacs这个运行在UNIX上的程序外),因此在批评 UNIX 上火力就欠缺了一分。为了写出一本厚厚的痛恨者手册砸向UNIX,就需要来自另外一派,即信奉GUI哲学的用户的愤怒。
这些用户的愤怒,主要集中在易用性上。图形界面操作系统的出现,本质上就是为了解决计算机的可用性问题。在图形界面系统出现之前,掌握计算机的使用需要的是阅读厚厚的手册。图形界面出现后,只需要几分钟的演示,普通用户即可操作计算机完成一些简单的任务。这种效率的本质提升,正是施乐的 Alto 和苹果的 Macintosh 的革命性所在。而 UNIX 所拥有的,是一堆两个字母的命令,不一致的命令行参数,和一个实际上不是为 GUI 系统设计的 X 图形系统。命令难记,X 又臃肿,即使有了这些仍然没有构成一个统一的桌面系统(所以后来才有KDE 和 Gnome),也难怪用户吐槽不已了。
在这类来自 GUI 用户的抱怨中,出乎我意料的一条是对UNIX管道的抱怨。主要的批评点在于管道作为一种 IPC 机制本身不够强大,包括管道不支持双向数据流(双向管道的用例也极少),只能把数据作为字节流而不能传递结构化数据,和指针等等。从传统 UNIX 用户的眼光来看,这些指责是很不公平的。管道的作用是串接程序的输入输出,将小工具串成强大的工具链。但管道并不是 UNIX 上唯一的 IPC 机制,UNIX 有其他的 IPC 机制来支持管道之外的功能。换一个角度看,要求管道支持双向通信,结构化通信等等,正是从 GUI 哲学出发的对管道的批判。在 GUI 世界,进程间的通信有了两种新的方式:1、把小程序全部集成到一个大的多线程窗口程序中来进行线程间通信; 2、通过在不同程序间复制粘贴对象。从这两个角度考虑,自然会要求 UNIX 管道能像线程间通信一样双向,以及支持有结构的对象而不是单纯的字节流。
GUI 程序的这一套新的进程间通信机制,改变了所在平台的软件架构。UNIX 的软件架构,是围绕软件工具(Software Tools) 的概念展开的,归结起来就是每个工具做一件事情,且做到最好的哲学。因为 GUI 程序本身的复杂性,把林林总总的功能,放入一个大程序中让各模块直接在一个进程空间里互相通信成了一个通行的做法。比如电子表格软件中的公式计算,无需代理到 bc 这样的外部计算器中,直接由内置的模块完成。在这种哲学的指导下,为了给提供全面的解决方案,各种商业程序都追求大而全,内置各种可能用到的功能,因此体积也越来越大。几百兆大小的商业软件不足为奇了。UNIX 痛恨者手册推崇这种只能算局部最优的程序构建方法,而反过来抱怨管道这个另一个局部最优不够好,在我看来是有历史局限性的。
总的来说,这本书代表了 UNIX哲学以外的其他两种哲学对 UNIX 尖锐的批评,是值得当成UNIX 发展史的一部分而一读的。
栋哥解读得真不错!书我也下载了,不过看完了这篇文章,您说我是读呢还是不读呢?
总的来说,这本书代表了 UNIX哲学以外的其他两种哲学对 UNIX 尖锐的批评,是值得当成UNIX 发展史的一部分而一读的。
栋哥,刚刚我也品尝到了,国内平台的管理精髓。我在微博上发现了,有给萨达姆叫冤平反,批老布什总统在死亡公路上肆意的屠杀伊拉克军人。将老布什总统描绘成刽子手。我实在看不下去了,我给他留言说,这是有联合国安理会的660号决议的,萨达姆是拒绝接受这个决议,联合国秘书长亲自奔赴巴格达,也被萨达姆拒绝从科威特撤军,然后萨达姆在边境和科威特摆出的和多国部队决战的架势,伊拉克军队溃败以后通过公路逃往伊拉克,他也没有挂白旗,也没有向联军投降,攻击他有什么有什么不对了?结果我不仅被博主拉黑了,微博管理员那给我禁言三天,还劝我要与这个博主来友好互动,这是什么逻辑呀?经过这次遭遇,我就在想栋哥说的没错,中文互联网这些语料要是去喂国产人工智能,做出来的那个一定会是个胡说八道的
视角很新颖,原来讨厌UNIX的不光有GUI哲学的,还有MIT哲学的,而且貌似后者才是主体。
栋哥,我两年前看这本书的时候,写了一个工具,解决的就是第一章的问题,你瞅瞅~
https://github.com/cryptic-resolver/cr.rb