为什么Bash是大多数操作系统的默认Shell?

为什么大多数操作系统(如Ubuntu、Fedora、OSX等)默认使用bash作为shell?为什么很多高级用户主要使用zsh?如果zsh这么好,为什么不是默认选择呢?
我两个都用,对于我所有的任务来说,没有区别 :)

5一切都是一个高斯曲线:如果大多数高级用户使用ksh,那么大多数人使用不同的shell也是事实,这本身就可以解释为什么ksh不是默认的shell。然而,我不认为这是原因,让我们等待一些杀手级答案,我相信这个问题会得到回答。 - kos
1实际上,我相信Ubuntu默认使用dash作为shell... - Bakuriu
1这个问题有一个很好的答案,我投票赞成保持它开放。 - Seth
5个回答

我对此进行了一些阅读,结论似乎是它是GNU(大多数基于Linux的操作系统使用的)的默认shell,因此作为GNU的一部分而打包提供。它已经有了20年的发展历程,稳定而全面,可以说是最好的全能型Shell,满足所有除了最高级用户之外的需求。
要了解更多,请参阅为什么bash在Linux上是标准的?(Unix & Linux上相同的问题)。
不妨再补充一点内容,如果您感兴趣,还有许多其他的Shell可供尝试,这里有一些来源于这个回答
  • Zsh具有更先进的交互功能,但在脚本编写方面存在一些怪癖(现在比过去少)。在1990年代初至中期,Linux刚开始发展时,zsh几乎是未知的。

  • Ksh自20世纪80年代中期以来一直是商业UNIX系统的事实标准,但直到2000年之前它都是专有软件,因此在Linux上无法使用。此外,与bash相比,ksh的命令行编辑能力较差。

  • Pdksh是ksh的一个免费克隆版本,可能是一个选择,但它并不广为人知,并且拥有较低的命令行编辑能力。(尽管ATT ksh现在是免费的,Pdksh项目已经不再活跃,但它仍然在一些BSD系统中使用)

  • 一些发行版将ash变体安装为/bin/sh。Ash(我指的是称为ash的一系列松散的shell)被设计为小而快速,没有交互功能(仅用于编辑脚本)。对ash的再度关注是相对较新的现象;在1990年代,现有的变体缺乏很多功能。

  • Tcsh是zsh出现之前最先进的交互式shell,但它与sh不兼容,并且在脚本编写方面不太好用。


1当你从其他地方复制粘贴内容时,你应该明确指出这是这种情况。 - muru
1@muru我确实提供了原帖的链接,但我明白你的意思,可能需要更清楚一些。 - Mark Kirby
你评论中提到的zsh在脚本编写方面有一些小问题,这个说法的来源是什么?算了,我看到这个评论来自其他地方。 - Scooter
1你也有 fish(它与 sh 语法不兼容)。 - Léo Lam
1你能解释一下Korn shell编辑有什么不足之处吗?在我看来,它似乎一直都很好用,即使是在90年代。 - Jonathan Leffler
@JonathanLeffler 我没有写那是从这里来的 http://unix.stackexchange.com/questions/28749/why-is-bash-standard-on-linux 答案二,请在那里询问。 - Mark Kirby
兼容性是我相信的主要原因。就像Mozilla用户代理字符串在各种浏览器中无处不在的情况一样。 - Ivan Chau
虽然来得很晚,但GNU/Linux社区曾经是UNIX社区(尤其是BSD专家)的笑柄,因为我们甚至连shebang都搞不对……到处都是bashisms,而#!/bin/sh作为shebang。这在Debian和Ubuntu中得到了改变,却导致当时80%到90%的为GNU/Linux编写的自定义shell脚本出现问题。至少它教会了我们如何正确指定shebang....;-) - thecarpy

Bourne Shell(早期的sh)是Unix的AT&T分支上进行改进并被Korn Shell(ksh)所取代。ksh也来自于AT&T贝尔实验室,不使用GPL许可证(当前版本为Eclipse Public License)。C-shell(csh)来自于伯克利版Unix,也不使用GPL许可证(BSD许可证),并且使用与sh不同的语法。Z-shell(zsh)是对sh的改进,但不使用GPL许可证(类似MIT的许可证)。Bash是对sh的改进,使用了GPL许可证,并来自GNU。仅从许可证的角度来看,Bash可能会成为GPL操作系统的选择。特别是作为发行版核心的一部分的shell。
但是Bash也是GNU项目,这使得我认为它具有更活跃的开发,并且比起伯克利Unix或AT&T Unix的传统产品更容易进行贡献。可以很好地论证zsh是一个比Bash更好的shell,但不足以克服其不同的许可证和非GNU项目的身份。
回到Linux发行版首次出现并选择默认shell的时候(90年代初至中期),还没有github(2008年)甚至SourceForge(1999年)。在那个时候,我认为GNU项目相对于非GNU项目在引起注意、吸引和包括新开发人员方面具有真正的优势。因此,发行版可以认为Z-shell更好,但也可以期望Bash将得到良好的支持和维护,并且还会添加更多功能,使其能够赶上zsh。
现在Bash已经成为事实上的标准,并有关于它的书籍。有一本书同时涵盖了Bash和Z-shell,但没有一本专门涵盖zsh的书籍,而有多本书专门涵盖Bash。
而且,如果发行版在升级现有系统时更改默认设置,那么一些初始化文件的名称可能会不同(例如.bashrc与.zshrc),文件的内容可能具有不兼容的语法。因此,他们非常不愿意这样做,使得新下载的系统默认为zsh,而升级的系统默认为bash。对于同一个发行版来说,使用两个不同的默认设置可能是他们不想要支持的,用户/公司也不愿意处理这种情况。

Unix shell语言都很丑陋。有些特别丑(如csh),有些可能稍微好一点(ksh?实际上我不太清楚),但是当涉及到可读性和对大型项目的严谨性等方面时,它们都无法与Python、C#或Haskell等设计良好的通用编程语言相媲美。所以,当你需要稳定的东西时,你绝对不会选择任何一种shell语言。
但是,当你想要快速完成简单任务时,你会选择它们。为此,你需要:
- 简洁的语法,足够一致,以便你能够记住它(查找简写操作符很困难)。如果你的shell在所有地方都安装了,这就非常重要,因为你真的不愿意记住多个这样的混乱怪物。 - 良好的交互功能,这样你就可以直接进入终端并让事情正常工作,而不必在多个脚本文件之间切换。 - 能够从任何地方获取任何脚本片段,并使其正常工作。在这里,与sh兼容性是一个重要的优势,而且再次强调,流行程度越高越好。
所以你会发现,在这些 shell 语言中,流行程度比通用语言更重要。因此,即使 ksh 自身是一种“更好”的语言,如果 bash 在相关领域中更受欢迎(在 GNU 中它是首选),那么使用它也不会有太大的优势。

那些进行切换的人都是经验丰富的,并且有足够的能力轻松地切换到他们最喜欢的 shell。然而,一个新手被迫使用不那么流行的 shell 会很快感到困惑,如果他们搜索互联网上的某些内容,结果却无法实现。因此,任何一个面向 Unix 老手以外的发行版,如果不将 bash 设为标准,就会带来相当大的风险,只有少数人会从中受益(而且收益微乎其微)。


2任何关心空白量的语言都不是“设计良好”的,但我同意流行度是关键。 - Nagora
1@Nagora:意见各异。顺便说一句,你总是可以用大括号和分号来书写Haskell,我想Python也有类似的替代方案。只是,没有人这样做,因为基于缩进的分组对于可读性来说真的很棒。 - leftaroundabout

  1. 在需要的时候它就在那里
  2. 它有足够多的吸引人的元素,初学者可以花上一周来定制他们的提示符。
  3. 对于常见的使用情况来说,它已经足够好了(最常见的是启动单个命令)
  4. 当它不够好时,Perl、Python和Lua可以弥补不足。
  5. Perl作为交互式shell效果很差
  6. 虽然Fish、Ksh或Zsh理论上可能是更好的shell,但对我来说改进不够大,因此当Perl工作得很好或可移植性成问题时,我仍然选择Dash。

“Critical Mass” 是主要答案,我个人认为。Bash 不仅适用于命令行工作,还适用于脚本编写,并且有大量的 Bash 脚本存在。无论现在有多好的替代品用于交互,能够轻松地“即插即用”这些脚本的需求超过了这些优势。因此,现在唯一有可能取代 Bash 的 shell 是完全向后兼容的下一个版本...也就是下一个 Bash 版本。

1无论你的默认shell是什么,你都可以直接使用任何bash脚本。这就是脚本顶部的she-bang (#! /bin/bash) 的意义所在。 - Panther
1只要系统中存在bash shell,我至少知道Solaris的某个版本不包含bash。 - Tulains Córdova
@bodhi.zazen 在使用两个不同的shell之间切换时,会有一定的心理负担——一个用于交互,一个用于脚本编写。总的来说,这样做往往不值得麻烦。 - Nagora
1@Nagora 运行脚本的心理成本是多少? - kos
@kos 如果你只是简单地运行脚本,那就没有问题。但如果你需要维护和调整脚本,那么你需要注意不同底层shell之间的一些细微差别,这样在你必须使用"其他"语法进行工作时,就会产生持续的金属成本和上下文切换成本。 - Nagora