什么是 GNU

作者:Arnold Robbins

上个月我们描述了 Plan 9 的起源、sam 编辑器和 9term 终端模拟器。那么,在窗口内运行的 shell 呢?同样,Plan 9 的作者也借此机会重新思考了 shell 应该如何工作的问题。Plan 9 的 shell 被称为 rc,因为它“运行命令”。

rc Shell

尽管在许多方面,Bourne shell 是一种简单、优雅、高级的编程语言,但它有一个严重的缺陷,因为它被设计得非常像一种宏处理语言。输入文本被扫描、重新扫描和再次扫描,因为每个处理阶段都在执行。(在 Korn shell 中,这被推向几乎荒谬的程度,其中有大约十一个不同的处理阶段。)这导致了相当复杂和巴洛克的引用规则,需要嵌套转义序列。

rc 中,输入文本只被扫描和解析一次。该语言有一个真正的基于 yacc 的语法,清楚地说明了一切的含义。引用规则非常简单。引用的文本必须用单引号括起来。要在引用的字符串中获得单引号,请将其加倍(如 FORTRAN 中那样)。使用显式运算符来提供字符串连接,并且变量可以是字符串列表,而不仅仅是单个字符串。

语法更接近 C 或 awk 的语法,而不是 Bourne 的 Algol 68。这减少了混乱,避免了不必要的关键字和分号。它比传说中的 csh 更像 C。

rc 提供 shell 函数,信号处理程序被编写为具有特殊名称(sighupsigterm 等)的函数,而不是使用字符串。I/O 重定向也更强大,它有一个符号,用于将文件描述符 0 和 1 连接到管道的输入和输出端。

rc 的一个可自由分发的克隆版本是可用的。它由 Byron Rakitzis 编写,并实现了 rc 论文中描述的语言,并进行了一些扩展。rc 的优点在于它小巧快速,并且 shell 程序可以非常优雅。它也可以在几乎任何类型的 Unix 系统上运行。

当将 rc9term 一起使用时,通常将主提示符设置为仅为一个分号,而将辅助提示符设置为空。这允许您抓取整个命令,包括提示符,并重新发送它们。分号被视为一个简单的空语句。使用双击选择整行,以及菜单的默认保存操作,使得一遍又一遍地发送和重新发送同一行变得非常简单;大部分工作都可以用鼠标完成。

资源侧边栏列出了 rc shell 的 ftp 位置。还有一个使用 rc 的人员的邮件列表。

es Shell

es 是“可扩展 shell”。Paul Haahr 和 Byron Rakitzis 认为,尝试将函数式语言的一些功能与 Unix shell 的功能结合起来会很有趣。shell 的许多内部功能(例如 I/O 重定向和设置管道)在语言中作为内置函数可用,并且程序片段可以作为参数传递给函数。

es 提供了一流的函数、词法作用域、异常系统和丰富的返回值(即,函数可以返回除数字以外的值)。解释这些大部分内容超出了本文的范围。es 在 1993 年冬季 Usenix 会议论文集中进行了描述。阅读这篇论文,并浏览邮件列表的存档,以了解该语言是如何演变的,这将有所帮助。有关 es 的完整详细信息,您需要阅读论文、手册页和 es 发行版中的 initial.es 文件。查看示例 .esrc 文件也是一个好主意。

基本上,es 背后的想法是获取 shell 执行的原始操作,例如 fork 进程、创建管道和设置 I/O 重定向,并将它们作为用户程序可以直接调用的函数提供。反过来,传统的 shell 语法建立在这些原始操作之上。

词法作用域允许您保存操作的定义,然后用您自己的操作替换它,并在以前的操作之上进行操作。以下是 es 论文中的一个示例。此代码实现了管道分析器。它保存了 %pipe 的定义,该定义创建管道,并提供了一个新的定义,用于对管道的每个组件进行计时,并使用旧的 %pipe 来实际创建管道。(es 是论文中用于示例的 es 的提示符。默认提示符是分号。)

es > let (pipe = $fn-%pipe) {
        {
                fn %pipe first out in rest {
                {
                        if (~ $#out 0) {
                                time first
                        } {
                                $pipe { time $first } $out
$in { %pipe $rest }
                        }
                }
es> cat paper9  tr -cs a-zA-Z0-9 '\012' | sort |
 uniq -c | sort | -nr  sed 6q
213 the
150 a
120 to
115 of
109 is
 96 and
 2r    0.3u   0.2s      cat paper9
 2r    0.3u   0.2s      tr -cs a-zA-Z0-9 \012
 2r    0.5u   0.2s      sort
 2r    0.4u   0.2s      uniq -c
 3r    0.2u   0.1s      sed 6q
 3r    0.6u   0.2s      sort -nr

这是一个简单的示例,但它说明了 es 中可用的一些功能。es 真的值得一个专栏来介绍。有关更多信息,请参阅上述来源和邮件列表存档。

侧边栏列出了 esftp 位置,并且还提供了一个邮件列表。

9wm 窗口管理器

到目前为止,我们看到的工具,特别是 sam9term,都是构建在 X Windows 之上的,并且可以与任何窗口管理器一起使用。有一段时间,我使用 mwm 运行它们。

在 1993 年秋季,我获得了 gwm(通用窗口管理器)的版本,其中包含 WOOL(Windows 对象定向 Lisp)代码,该代码实现了与原始 Bell Labs Blit 终端非常相似的界面。这提供了一个简单、干净的界面,类似于 Plan 9 上使用的界面(8½ 可以被认为是 Blit 的进一步演变)。此代码由悉尼大学的 John Mackin 编写。如果您有兴趣,资源侧边栏显示了您可以获取此代码的位置。此代码可以工作,但它很大且速度很慢。

但是,最近出现了一个新的窗口管理器 9wm9wm 在 X windows 下实现了 8½ 的窗口管理策略。它由悉尼大学的 David Hogan 编写,使用原始 Xlib(不是一个漂亮的景象),并且完全符合 ICCCM 标准。9wm 也小巧且速度非常快。引用 README 文件中的话

9wm 是一个 X 窗口管理器,它试图在 X 施加的约束范围内尽可能地模拟 Plan 9 窗口管理器 8½。它提供了一个简单而舒适的用户界面,没有华丽的装饰或标题栏。也没有图标。并且它是点击式输入。这不会吸引所有人,但如果您还没有被吓退,请继续阅读。(并且在您尝试之前不要否定它)。

9wm 是“点击式输入”。这意味着您必须将鼠标移动到特定窗口中,然后单击按钮 1。该窗口将成为当前窗口,并由粗黑边框指示。其他窗口具有细黑边框。此行为与 sam 的行为相同。

9wm 菜单(通过根窗口上的按钮 3 访问)包含五个项目

  • 新建 - 打开一个新窗口(如果没用 9term 则用 9termxterm

  • 重塑 - 更改屏幕上窗口的形状,

  • 移动 - 移动窗口,

  • 删除 - 吹走一个窗口,

  • 隐藏 - “图标化”一个窗口。

9wm(和 8½)最引人注目的地方也许是没有图标。相反,要从屏幕上删除窗口,请从主菜单中选择隐藏。光标变为目标。您将目标移动到要隐藏的窗口,然后单击按钮 3。单击任何其他按钮都会取消操作。

当窗口被隐藏时,它会从屏幕上完全消失,甚至不留下图标。相反,一个新的项目出现在按钮 3 9wm 菜单的底部,其中包含窗口的名称。要再次打开窗口,您只需从菜单中选择窗口的名称。

与其他程序一样,9wm 菜单会记住您上次的操作,以便下次您弹出菜单时,之前的选择已突出显示

9menu 命令行菜单程序

现在,这是我个人对这幅图景的小小贡献。我使用了一段时间的 GWM Blit 模拟,它理解它是构建在 X 之上的,当您选择新建时,它会为您提供一个主机菜单(您在配置文件中定义了这些主机),您可以在这些主机上启动远程 xterm。这很好,我发现在 9wm 下缺少它。

(在 Plan 9 中,这不是问题;网络中的多个主机是紧密集成的,但在带有 Unix 的 X 中,这是一个问题。)

我想要的是一个简单的程序,您可以向它提供菜单项和关联的命令,并且该程序将弹出一个窗口,该窗口只是一个菜单。选择一个项目将运行一个命令。该程序将长期存在,使菜单永久显示。一个接近于此的程序存在,xmenu。不幸的是,xmenu 在执行命令后会消失,并且在与 9wm 交互时行为不佳。

9wm 的启发,从其菜单代码开始,并在 David Hogan 的帮助下,我编写了 9menu9menu 弹出一个窗口,其中包含项目列表,并在按下按钮时执行相应的命令。

9menu 允许您编写自己的菜单并自定义行为以适合您,而无需 .twmrc.mwmrc 文件的麻烦。很容易让一个项目生成另一个 9menu,从而产生类似于右拉菜单的效果。

以下是我使用它的两种方式:一种用于远程系统,另一种用于我可能想要运行的程序。因为我很懒,所以在两者中都有 xterm。我使用一个名为 rxterm 的 shell 脚本,该脚本了解我想要在其上打开窗口的远程主机,以及它们是否可以启动 9termxterm。(这是从 GWM Blit 代码遗留下来的,主要是为了方便。)这些示例来自我的 .xinitrc-geometry 字符串是为了让 9wm 放置窗口,即使它们最初是图标化的。

9menu -geometry 67x136-4+477 -iconic -popdown -label Remotes \
        'solaria:rxterm solaria.cc.gatech.edu' \
        'burdell:rxterm burdell.cc.gatech.edu' \
        'chrome:rxterm chrome.cc.gatech.edu' \
        'xterm:rxterm xterm' \
        exit &
9menu -geometry 103x102-3+624 -iconic -popdown -label 'X programs' \
        'xterm:rxterm xterm' \
        xtetris xlock '9wm restart' '9wm exit' exit &

我使用 -iconic 启动程序,以便它们会自动隐藏并成为 9wm 菜单的一部分。-popdown 选项使菜单在选择项目后自动图标化自身,因为我发现这是我最方便的工作方式:弹出菜单,选择一个项目,然后继续我想做的事情,而无需菜单挂在那里。虽然不如 sam9term9wm 那样大规模的程序,但我发现 9menu 为我完成了整个软件包。

经验

我已经使用这个环境将近两年了,发现它干净、优雅且易于使用。最初,我从使用 rc 开始,然后在 1993 年初 sam 可用时开始使用它。在那之后不久,我开始 beta 测试 9term,特别是使其在 SunOS 下正确运行。在 1993 年秋季,GWM Blit 代码变得可用,我切换到该代码,并使用了将近一年。在 1994 年春季,我开始 beta 测试 9wm,它最终于 1994 年底发布。在阅读了关于 es 的文章并在冬季 Usenix 上听到演示后,我在 1993 年 1 月切换到了 es

贝尔实验室的研究小组以将“小而美”原则应用于软件设计而闻名。最初 Unix 就是如此,并且已将其重新应用于分布式系统、shell 和 Plan 9 的用户界面。

界面简单、一致、易于使用且非常干净。本专栏中描述的所有程序在按钮的功能、哪个窗口是当前窗口以及菜单如何记住之前的操作方面,都以相同的方式运行。

我至今尚未强调的一个重要点是,所有程序都使用弹出菜单。我发现这非常方便,尤其是与 Windows 或 Macintosh 等系统相比,在这些系统中,您必须将鼠标移动到菜单栏才能下拉特定菜单。弹出菜单节省了大量原本无用的鼠标移动,从而使系统更易于使用。

我对窗口系统的第一次接触是在很久以前,在一个 Blit 终端上。界面简单、干净且优雅。从那时起,我一直在寻找一个与 Blit 的优雅相匹配的 X windows 环境。现在,通过 sam9term9wmrces 的组合,我觉得我终于找到了那个环境,我非常高兴。更令人高兴的是,所有这些程序都很快,并且我也可以使用广泛的 X 应用程序(xoj,有人用吗?)。后一点不幸的是对于唯一的另一个选择 mgr 来说并非如此(我在 9term 可用之前一直使用它。

在 Linux 下使用这些程序

这里描述的所有程序都可以在 Linux 下编译。我没有自己的 Linux 系统(信不信由你!),但有一段时间我借用了一个,并且能够启动所有这些程序。不幸的是,该系统是一台笔记本电脑,屏幕太小,无法使 X 值得使用。sam 可以正常启动,使用 Make.solaris makefile 作为起点。9wm 也编译得很好。9term 花了一些功夫,但它确实编译并运行了。在邮件列表中询问后,我了解到 9term 在 Linux 下(尚未)不能完全正确地工作。不过,当您阅读本专栏时,这可能已被修复。有关将 9term 移植到 Linux 的信息,请联系 Pete Fenelon (pete@minster.york.ac.uk) 和 Markus Friedl (msfriedl@faui01.informatik.uni-erlangen.de)。rces 都可以编译并在 Linux 下运行,但需要做一些工作。对于 rc,您必须手动生成 sigmsgs.c 文件,基于 /usr/src/linux/include/sys/signal.h。Jeremy Fitzhardinge 报告了另一个错误,即 rcint 用于附加组的数组,而 Linux 使用 gid_t,即 shortes 对于信号处理需要类似的更改,但这些实际上已在 Makefile 中记录。

摘要

9term9wm 的组合提供了对优雅的 Plan 9 用户界面的非常接近的模拟。sam 是一款功能强大、易于使用的编辑器。rc 是一个简单、干净的 shell,而 es 是一个很棒的 shell,具有很大的潜力。值得阅读描述这些组件的论文。完整的组合再次证明“小而美”。

致谢

感谢 Chris Siebenmann 和 Daniel Ehrlich,他们是各种邮件列表的维护者,感谢他们的帮助,以及感谢列表中回复我关于 Linux 问题成员。感谢 Bob Flandrena、Paul Haahr 和 Miriam Robbins 的评论。

参考文献
  • Rob Pike、Dave Presotto、Ken Thompson 和 Howard Trickey,“来自贝尔实验室的 Plan 9”,1990 年夏季英国 UKUUG 会议论文集,伦敦,1990 年 7 月,第 1-9 页。

  • Rob Pike、Dave Presotto、Ken Thompson 和 Howard Trickey,“Plan 9,分布式系统”,1991 年春季 EurOpen 会议论文集,特罗姆瑟,1991 年 5 月,第 43-50 页。

  • Rob Pike,“文本编辑器 sam”,软件—实践与经验,1987 年 11 月,第 17 卷,第 11 期,第 133-153 页。

  • Rob Pike,“8½,Plan 9 窗口系统”,1991 年夏季 Usenix 会议论文集,纳什维尔,1991 年 6 月,第 257-265 页。

  • Tom Duff,“Rc—Plan 9 和 UNIX 系统的 Shell”,1990 年夏季英国 UKUUG 会议论文集,伦敦,1990 年 7 月,第 21-33 页。

这些论文都以 Postscript 格式提供,作为 Plan 9 文档的一部分。

  • Paul Haahr 和 Byron Rakitzis,“Es:具有高阶函数的 shell”,1993 年冬季 Usenix 会议论文集,1993 年 1 月,第 53-62 页。

本文可通过 ftpes 源代码一起获得。

Arnold Robbins (arnold@gnu.ai.mit.edu) 是一位专业程序员和半专业作家。自 1987 年以来,他一直为 GNU 项目做志愿者工作,自 1981 年以来一直从事 Unix 和类 Unix 系统的工作。关于本专栏的问题和/或评论可以通过邮寄方式发送给作者,地址为 c/o Linux Journal,或通过电子邮件发送。

加载 Disqus 评论