为什么类 Unix 系统中有多个 shell?

为什么类 Unix 系统中有多个 shell?

我刚刚开始学习 Unix 的基础知识,并且想知道为什么在类 Unix 系统中有如此多的 shell。从书中Unix环境下的高级编程:

shell 是一个命令行解释器,它读取用户输入并执行命令。shell 的用户输入通常来自终端(交互式 shell),有时来自文件(称为 shell 脚本)。

然后本书继续列出了一些 shell 程序,如 Bourne shell、Bourne-again shell、Cshell 等。我的问题基本上是为什么我们需要多个外壳?

答案1

因为人们有不同的需求,在特定情况下有适合您需求的替代方案是件好事。在我看来,shell 本身只是一个工具,应该可以被任何其他工具替代。这就是 Unix/Linux 的力量,与 Microsoft Windows 选择的力量相反。

同样...为什么有这么多文本编辑器?如果已经有浏览器了,为什么人们还要开发一种新的浏览器呢?为什么会有 GNOME、KDE、Xfce、LXDE、E17 等?

答案2

现代 UNIX 环境中使用的大多数 shell 都旨在符合 POSIX sh 规范。 POSIX sh 源自原始的 Korn shell (ksh88),而后者又源自早期的 Bourne shell,但 POSIX sh 仅指定了 ksh88 功能的一小部分。仅实现最低要求的 shell 缺少以安全合理的方式编写除最琐碎的脚本之外的所有脚本所需的许多功能。例如,局部变量和数组是非标准的额外内容。

因此,第一个原因是用额外的功能来扩展外壳。不同的 shell 选择关注不同的事情。例如,Zsh 专注于高级交互功能,而 ksh93(当前的“原始”korn shell)则专注于强大的编程功能和性能。即使像 Dash 这样非常小的 shell 也至少会添加一些非标准的额外功能,比如局部变量。

额外的功能即使有,也很少能广泛互操作。大多数 ksh88 功能集具有相当好的互操作性,例如扩展的 globbing 语法,但对于非标准功能,没有任何保证,并且您必须真正知道自己在做什么才能以可移植的方式使用它们。

第二个原因是遗产。仍然有许多专有的 Unix 对其 /bin/sh 使用古老的非标准实现。直到最近,Solaris 仍然使用 Bourne 作为默认外壳,并选择维护 Heirloom shell,而不是升级到现代外壳。这些系统通常带有不同的 shell,您可以切换到这些 shell,例如通过更改 PATH 变量或更改单个脚本中的 shebang。

所以总结一下。有多个 shell,通常是默认的:

  • 对于额外的功能,尤其是处理非便携式附加功能。
  • 处理通常不维护的遗留脚本。
  • 尺寸/性能。嵌入式系统通常需要小型 shell,例如 mksh 或 busybox sh。
  • 许可原因。 AT&T ksh 在 2000 年左右之前一直是专有软件。这在很大程度上催生了所有类似 ksh 的克隆,例如 Zsh 和 Bash。
  • 其他历史原因。虽然现在不太流行,但已经有人尝试重新设计该语言,例如 scsh 和 es。许多 shell 的进程替换功能最初来自 rc(语法略有不同),大括号扩展来自 csh。不同的 shell 具有不同的可用功能组合,通常具有一些细微或不那么细微的差异。

答案3

简答

由于奇怪的许可历史,没有任何一个实体开发过 Unix。这是一个志愿者和公司都参与的社区过程。这些实体并不总是共享所有工具,因此出现了单独的 shell。当我们意识到这会产生多大的反作用时,统一所有正在使用的 shell 已经太晚了。相反,我们已经完成了工作以确保所有这些外壳(理论上)彼此兼容

答案很复杂,并且与 Unix 本身的历史紧密相关。它不可能在本页上保留单一答案,但它已被广泛(错误)记录。通过浏览有关 Unix 历史的网络和书籍,您会找到更详细和准确的答案。

答案4

主要是历史...

Bourne 是作为(专有的)SysV Unix 的一部分开发的,而 BSD 使用csh...后来,bash 被开发为 Bourne shell(及其改进版本,如 ksh)的开源替代品。 POSIX 标准采用了类似 Bourne 的 shell。 ksh 是兼容的,bash 也可以是兼容的。

Shell 类似于原始的 Bourne shell(缺少命令完成等),csh并且比原始的 Bourne shell 更容易交互使用,但是tcsh对于脚本来说太可怕了...

在某些环境中,例如基于 Unix 的嵌入式系统,脚本功能、大小和速度比命令完成等交互功能更重要,并且倾向于使用 shell 的不同变体。

对于可移植脚本,您应该使用兼容 POSIX 的 Bourne 变体并避免扩展。

相关内容