# 伯克利 Unix 第一幕

加州大学伯克利分校的 Robert Fabry 教授参加了 1973 年 10 月的 SOSP 会议。他是对 Thompson 的演讲印象深刻的人之一。回到 Cory Hall（伯克利的一教学楼）后，Fabry 的第一项工作是尝试促成计算机科学、统计学和数学三个系共同购买一台 PDP-11/45。他随后从 Thompson 那里订购了一盘磁带，并且在 1974 年 1 月，由研究生 Keith Standiford 安装了 Unix。正如 Kirk McKusick 所述，Ken Thompson 在此之前一直亲自参与所有实际安装，但这次没有直接参与，虽然“很快就需要用他的专业知识来确定几起奇怪系统崩溃的原因”。Thompson 会在机房给 Keith Standiford 打电话，将电话接入 300 波特的声学调制解调器，并“远程调试来自新泽西的崩溃转储”。

下个问题出现是因为数学系和统计系想运行 DEC 的 RSTS 操作系统。于是每天的时间被分配成切片：Unix 运行 8 小时，接着运行 16 小时的 RSTS。当时接触 Unix 的一名本科生是 Eric Allman。

> 我当时正在修入门操作系统课程，他们一直在 6400 机器上使用一个叫做 Toy Operating System 的系统。但他们想换成 11/40 上的 Unix，可那时我们每天只能用 8 小时，而且每天的 8 小时还不一样。我记得当时遇到不少困难：我在看手册，完全不明白为什么有人会想用 echo 命令，真是奇怪。当然，现在懂了。的确，第四版很不稳定。那个系统只有研究人员才会喜欢。它运行缓慢，工具稀少。后来我被 Ingres 项目聘用了。

Michael Stonebraker 和 Eugene Wong 教授的 Ingres 数据库是最早迁移到 Unix 的项目之一。由于对分配的时间不满意，他们在 1974 年春买了一台自己的 PDP-11/40。但即使如此，11/45 机上的学生时间仍不够用。1974 年 6 月，Stonebraker 教授和 Fabry 教授开始为计算机科学系争取两台教学用的 11/45。资金在 1975 年初筹齐，正好那时 DEC 宣布了更适合的 11/70，于是大家把钱合并起来购买了 11/70。这台机器在秋天到货，正好 Ken Thompson 来做一年的访问教授休假。Thompson、Bob Kridle 和 Jeff Schriebman 在新装的 11/70 上启动了第六版 Unix。

这其中一个有趣的副作用是“50 套 bug”磁带。Thompson 告诉我：

> 首先需要明白的是，外界运行的是 Unix 的各个版本（V4、V5、V6、V7），但我们并不是这样看的。我们认为它是一个连续体。V5 只是我们在某个时间点拥有的版本，并且很可能因为维护准备输出而很快就过时了。
>
> 在 V6 之后，我准备去伯克利教书一年，正打算带上一套系统。因为这几乎是一个发布版本，我便制作了一个与 V6 的 diff。去伯克利的路上，我在厄巴纳 - 香槟停留，照看正在完成博士学位的 Greg Chesson（顺便招募）。我把 diff 磁带留给了他，并告诉他如果它流传出去我也无所谓。（我想我也给了别人，比如 Katz）。\[O’Brien 提到的 diff 磁带很可能就是从 Chesson 那里传给他的。]
>
> 我觉得这很重要，因为我发现了一整套非常严重的多程序（异步）bug，确实需要修复。当时分发的版本是“原样”发布，没有更新措施。而且用户之间交换这类信息在保密协议中被严格禁止。整个状况根本行不通，我觉得我必须做点什么。
>
> Lou Katz 的说法略有不同：
>
> 收集了大量的 bug 修复补丁，与其一个一个发布，不如由 Ken 组装成一盘补丁合集磁带（“50 个修复”）。其中一些修复非常重要，虽然我不记得具体是哪几个。我怀疑相当一部分修复实际上是由贝尔实验室外的人完成的。Ken 试图发送这盘补丁，但律师们不断拖延阻挠。
>
> 最终，彻底失望后，有人“在 Mountain Avenue 发现了一盘补丁磁带”。\[贝尔实验室地址是新泽西州 Murray Hill 的 600 Mountain Avenue。]
>
> 当律师发现这事后，给所有许可证持有人打电话威胁，如果不销毁该磁带会有严重后果，还试图查明他们是如何获得这盘磁带的。我猜没人真正告诉他们（我没说）。这是律师们存在意义的第一次尝试，也是杀死 Unix 的开端。到这时，参与 Unix 的律师人数远超过技术人员。许可证条款开始变化，费用迅速上涨。

那年秋天，同样有两位新的研究生来到伯克利校园：Chuck Haley 和 Bill Joy。他们对这个新系统非常着迷，开始在 Ken Thompson 拼凑出来的 Pascal 系统上工作。Haley 和 Joy 改进了 Pascal 系统，直到它成为学生们首选的编程系统。但当 Model 33 Teletype 终端被 ADM-3 屏幕终端取代时，Haley 和 Joy 对 ed 行编辑器感到沮丧。他们采用了由伦敦玛丽女王学院的 Coulouris 开发的一个叫 em 的编辑器，并开发出了逐行编辑器 ex。Coulouris 是英国第一位收到 Unix（版本 4）的人，时间是在 1973 年末。他告诉我：

> 我在 1975 年秋天于玛丽女王学院开发了 em，目的是让我们更有效地利用最近购入的一些 VDU 终端。我们有在图形显示器上开发应用的经验，支持光标键和手写板驱动的光标定位（这些经验来自 William Newman，他曾在犹他和 Xerox PARC 之间与我们共事了一年半）。我得出结论，Unix 当时几乎未被利用的“raw”终端输入模式，可以用来实现我们在单用户图形系统中习惯的那种文本编辑的便利性和即时反馈，这促使我开发了 em。
>
> 顺便说一下，em 代表“凡人编辑器”（editor for mortals）——这是我在开发时 Ken Thompson 访问我们实验室时给它起的名字。他说：“是啊，我见过类似的编辑器，但我不觉得需要它们，我不想在编辑时看到文件的状态。”
>
> Unix 屏幕编辑器的发展可能从未在贝尔实验室被认真考虑，部分原因是 Ken 的态度，另一部分原因是多年里他们没有合适的终端。他们长期使用 TTY 和其他打印终端，后来给 Unix 团队每人配了 Tektronix 4014 屏幕，这是一种大型存储管显示器。存储管显示器无法运行屏幕编辑器，因为图像不能更新！因此，Unix 屏幕编辑的开创工作不得不由别人来完成，而最初是我们在做，并且持续了很多年。
>
> 然后，我在 1976 年夏天作为访问学者来到伯克利计算机科学系。我在一个充满电传打字机终端的房间使用系里的 Unix。我带来了 em 的源代码和安装包，用于自己使用（虽然 em 是为 VDU 设计的，但它的单字符交互也能在 TTY 上使用——虽然非常慢——每次交互后都会重新打印当前行！）。
>
> 一天，坐在隔壁终端的是一位相当疯狂的黑客和博士生（Bill Joy），他说他正在写一款 Pascal 编译器。我向他展示了 em，他说：“不错，系统支持人员可能会对它感兴趣。”他带我去见了他们。他们有几台 PDP-11（具体型号我不太确定），支持好几个房间的 VDU 终端，终端以 9600 波特连接，这正是 em 能大显身手的环境。
>
> 我解释说 em 是对 ed 的扩展，提供了按键级别的单行编辑交互，在屏幕上显示最新的行（类似单行屏幕编辑器）。这是通过将终端模式设置为“raw”实现的，这样可以在按键时立即读取单个字符——在 1976 年，这对于程序来说是个怪异的做法。
>
> 系统支持人员（Jeff Schriebman）说：“这很好，但如果让所有用户都使用 raw 模式，由于每次按键都要进程切换，CPU 开销会很大。”
>
> 我对此反应感到有些沮丧，想着“我开发的这个编辑器运行开销太大了，在我们的小系统中还可以，在伯克利这个大的 Unix 环境中就没用了。”
>
> 尽管如此，Bill 和系统支持人员还是拿走了我的源代码，看看是否能用。那时我去了东海岸待了一个星期左右。回来时发现 Bill 已经以我的代码为起点，进展很大，开发出了后来成为 ex 和 vi 的东西，编辑器也装在了服务机上——当然仍需要“raw”模式，但显然它的优点超过了缺点。
>
> 看到 em 很可能让 Bill Joy 和 BSD 团队意识到 Unix 上屏幕编辑器的可能性。如果我没开发 em 并带着它访问伯克利，早期的 BSD Unix 很可能不会包含屏幕编辑器。这可以看作是 Unix 发展史上一个小的跨大西洋的思想逆流例子。
>
> 不幸的是，vi 没有继承 em 中包含的一些人机界面原则。在玛丽女王学院，我们早已得出结论，模态交互是个糟糕的主意，我也花了不少功夫确保 em 中的交互不会让任何按键有多个含义。而 vi 在插入模式和编辑模式上的设计严重违反了这一原则。
>
> 因此，我们在玛丽女王学院从未使用过 vi。取而代之的是，我的一位同事 Richard Bornat 与我的一名博士生 Harold Thimbleby 合作，设计了一个基于合理人机界面原则的全屏编辑器。玛丽女王学院的编辑器叫 ded（display editor）。它几乎完全没有模式，但需要支持较多功能键的终端。它在七十年代末和八十年代初在欧洲得到广泛分发和采用，但后来逐渐被 vi 和 emacs 取代。

与此同时（在宇宙的另一个角落），当时作为康奈尔的“JCL 黑客”的 Kirk McKusick 被一位在特拉华大学学习的朋友介绍了 Unix。“他向我展示了如何在上面玩游戏，”McKusick 告诉我，

> 所以直到 1976 年我来到伯克利之前，我其实并没有接触过 Unix。我那年春天去伯克利，是因为我在考虑研究生项目，当时正值春假，校园里人不多。但我在计算机房碰到了 Bill Joy，他正忙着写代码，他说：“嗨，我是 Bill Joy，这就是我们正在做的东西——一个运行在 Unix 上的 Pascal 系统。”我问：“Unix 能干什么？”他说：“你可以编辑文件，编译文件，还能下棋。让我帮你登录。”于是我下午就一直在下棋。那时我决定我喜欢伯克利，这里就是我要去的地方。

当 Thompson 于 1976 年夏末回到贝尔电话实验室后，Haley 和 Joy 将兴趣转向了内核。在 Schriebman 的监督下，他们将修复补丁安装到了“50 个 Bug”磁带上。掌握了源代码操作后，他们开始提出改进建议。

与此同时，Pascal 编译器的消息传开了，并且在 1978 年初，Joy 开始制作伯克利软件发行版（BSD）。这份发行版于 1978 年 3 月 9 日通过一封信提供给了 Tom Ferrin。“许可证”只是纸张的一面，Tom 于 3 月签署了它。磁带内容包括：

> a) Unix Pascal 系统
>
> b) Ex 文本编辑器
>
> ……由以下人员创建：
>
> a) W. N. Joy、S. L. Graham、C. B. Haley、K. Thompson
>
> b) W. N. Joy

附带许可证的说明单指出：

> 该发行版为标准的“tp”格式，采用 800 bpi 磁带。最小且推荐使用的卷长为 1200 英尺。
>
> 售价为 50 美元。

我之所以详细讲述这些，是因为我觉得这很好地体现了 Unix 在其第一个十年中最优秀的特质，也正是这些特质使其成为如此受欢迎的操作系统。

贝尔电话实验室创造了一些东西，并以源代码形式发布。英国的一位用户基于它创造了新的东西。加州的另一位用户对原版和英国版本进行了改进。它以成本价分发给社区。改进后的版本被纳入了下一版贝尔电话实验室发布中。

专利和授权机构无法控制这一切。系统不断变得更好，使用范围也不断扩大。

1978 年，作为发行秘书的 Bill Joy 免费发送了大约 30 份 BSD 发行版。但几台带有可寻址光标的 ADM-3a 终端的出现，使他能够创建 vi（可视化编辑器）。

这又引出了另一个问题：如何为多种类型的终端优化代码。Joy 决定通过使用一个解释器来重新绘制屏幕，从而整合屏幕管理。该解释器根据终端特性驱动——这就是 termcap 的诞生。

到了 1978 年中期，已经完成了足够多的工作（Pascal 系统更健壮，可以在 PDP-11/34 上运行，还有 vi 和 termcap），于是第二版伯克利软件发行版（2BSD）被放到了磁带上。Bill Joy 接听电话，组织发行版，吸纳用户反馈融入系统。他还发出了近 75 盘 2BSD 磁带（针对 PDP-11 的 Unix 最新版本是 2.10.1，于 1989 年由 USENIX 协会提供，约 80MB，售价 200 美元，依然非常划算）。

Paula Hawthorn 曾向我回忆起那些日子：

> Kashtan 刚刚发表了他对 Unix 与 VMS 的比较，而我也已经完成了许多论文工作，所以这应该是在 77/78 年的冬天。一群电子工程与计算机科学系的学生去越野滑雪度周末。Bill Joy、Mike Ubell、我和其他几个人都在那里。我们坐在租来的公寓厨房的地板上（因为我们在讨论工作，所以被禁止去客厅）。当 Bill 读着 Kashtan 更好的性能数据时，Bill 和 Mike 阅读着 Unix 源代码，而我则解释其他操作系统中磁盘和缓冲的工作原理——我的硕士性能测量是在运行 Kronos 的 CDC 6600 上完成的。我的博士研究是关于 Ingres 性能的，结果发现 Ingres 的性能显然非常依赖于能够物理顺序读取逻辑顺序数据。Unix 需要类似于 extent（连续区间）的机制。天哪，没有人想听这些，但我有性能测量数据，Kashtan 也有性能测量数据。于是我们一起研究 Unix 代码，决定在哪里优化加速。这标志着让 Unix 成为高性能系统的开始……

Mike Ubell（后来写了这段历史）说：

> 我记得 Bill 在做其他事情的时候花了很多时间看代码。他在做底层的 CPU 优化，努力减少指令数量。

Ubell 还告诉了我有关 shell 历史机制的事情：

> Bill 在 csh 中实现了历史记录机制。我很喜欢它，因为我是出了名地经常把最常见的单词拼写错，而 ADM3a 终端又没有剪切粘贴功能。我记得他当时是把历史记录写入文件，但他不喜欢那样的工作方式，于是把它去掉了。失去了这个提升效率的工具后，我用 shell 已经使用的内存解析结构重新实现了它。Bill 很喜欢我实现的方式，然后就沿着这条路继续开发。我的 shell 版本在伯克利流传了好几个月，直到 Bill 发布了下一个版本。
>
> C shell 的手册页（在“历史替换”部分）仍然体现了 Ubell 的拼写问题：
>
> “历史替换能让你在正在输入的命令行中使用以前命令行中的单词。这简化了拼写修正和复杂命令或参数的重复输入。”
>
> Ubell 的经历也与 Eric Allman 的说法完全契合：
>
> “软件设计的一条通用原则是，你应该写出自己想用的程序。”
>
> **早期版本和 PDP 机型**

| UNIX 版本 | PDP 机型                 |
| ------- | ---------------------- |
| 第 1 版   | PDP-7                  |
| 第 3 版   | PDP-11; 11/20          |
| ·       |                        |
| ·       | PDP-11/45              |
| ·       |                        |
| 第 6 版   | PDP-11/70              |
| 第 7 版   | PDP-11, Interdata 8/32 |
