Answers:
关于“为什么原始sh外壳不存在sh
” 的简短答案是没有原始sh。
好的,有:这是汤普森弹壳。版本1具有我们今天所知道的一些功能,特别是重定向和管道(请阅读Dennis Ritchie的有关Unix早期历史的论文)。后来的版本增加了一些功能,例如带有后台执行&
,globlob(由外部程序实现)和某些形式的引用,但它没有变量或嵌套的控制结构。通过外部程序if
(以一个条件和一个命令作为参数)和goto
(通过更改其父文件在脚本文件中的位置来工作)提供了条件和循环。
1979年,在Unix V7中,汤普森(Thompson)外壳/bin/sh
由Bourne外壳代替。第一个版本已经具有今天破折号中提供的许多功能,后续版本引入了更多功能。几年后,Korn外壳面世,功能不断增强。许多Unix变体以ksh
。
在1992年,POSIX编纂了最少的sh
功能集,这些功能基本上是Bourne加一些东西。任何自称为“ Unix”的系统都必须至少实现这些功能。商业Unix系统通常使用ksh作为POSIX sh,但是有少数几个(例如OSF / 1)有自己的。
直到最近,Bourne shell和Korn shell都不是开源的,因此当Linux世界在1990年代中期开始形成时,它们就不可用了。/bin/sh
必须是别的东西。大多数Linux发行版去了庆典,从外壳GNU项目是往往是Bourne和Korn之间的脚本功能方面,比任何交互使用好得多)。唯一可行的替代方法是pdksh(“公共领域的Korn shell”),它是免费的(现已停产,但仍以mksh生存,该状态正在积极开发中),但我不记得使用pdksh的Linux发行版是/bin/sh
,我不知道为什么,我想是因为Linux发行版始终是GNU / Linux发行版,基本上可以提供存在GNU版本的任何工具的GNU版本。
还有一些sh
称为“ ash”的开源实现,最著名的是Almquist shell,但是它们非常不完整,缺少人们想要使用的某些POSIX功能。作为Debian维护者的程序员Herbert Xu扩展了ash使其与POSIX兼容。最终,他的版本被重命名为破折号,并且有人/bin/sh
在Debian而不是bash中进行了推广。Ubuntu在Debian开始系统地将bashisms(在#!/bin/sh
脚本中使用bash特定功能的使用)视为bug之前就开始了。两者都切换了以后(Ubuntu 6.10,Debian仅在2009年(这是lenny的目标。 但切换仅在lenny发布后才进行,即处于挤压状态))。
一个主要的原因使用破折号,而不是bash的作为/bin/sh
是,它是显著更快。这对于Ubuntu尤为重要,Ubuntu从一开始就努力保持启动时间短。Dash也倾向于使用比bash更少的内存,这对于包装脚本来说有些重要,该包装脚本仅在底层程序退出时留一些清理。dash的另一个好处是,它仅依赖于libc(核心系统库),而bash也依赖于终端支持库(没有它们就无法启动,甚至无法运行脚本)。这意味着破折号有更好的机会继续在损坏的系统上工作。
在21世纪的某个时候,Korn Shell变得开源,并且出现了Bourne Shell的开源版本(旧版本,因为几年前开发已经停止)。但是dash和bash在Linux世界中根深蒂固,以至于无法获得他们的认可,尤其是Bourne shell,因为它的价值仅是历史性的。Dash取代Bash是有好处的,因为它具有明显的优势,但其他竞争者中没有一个具有决定性的优势/bin/sh
。
system
应用程序对(3)的所有调用)中的破折号击败了它,这是主要因素。
速度和POSIX兼容性(换句话说,可移植性)是主要因素。请记住,这/bin/sh
是针对系统脚本的,这些脚本可能来自也可能不来自旧版本的Ubuntu和/或其他系统。
当然,闪亮的功能bash
对于我们的用户来说很酷,但是在必须管理多个不同服务器/系统的环境中运行内容时-具有符合POSIX的外壳会带来很大的不同。特别是,如果您是新的系统管理员和具有许多脚本的继承环境。
至于为什么没有原始的Bourne外壳,则很简单-它是AT&T贝尔实验室最初拥有的专有产品。
另外,实际上在Ubuntu Wiki上对此有一个明确的解释:
为什么要进行此更改?切换默认Shell的主要原因是效率。bash是适合交互使用的出色的全功能外壳;实际上,它仍然是默认的登录外壳。但是,与破折号相比,它的启动和操作相当大且缓慢。作为Ubuntu引导过程的一部分,启动了大量的Shell实例。Ubuntu核心开发团队认为,最好不要进行单独更改以使其在/ bin / dash下显式运行,而这种更改将需要大量的日常维护,并且如果没有引起足够的注意,则很可能会倒退。默认外壳。在Ubuntu 6.10中启动速度的提高通常被错误地归因于Upstart,它是在Ubuntu 6中用于以后开发init系统的理想平台。10主要运行在System V兼容模式下,只有很小的行为更改。这些改进实际上主要是由于更改了/ bin / sh。
这是关于可移植性的说明:
Debian政策手册长期以来一直要求“将'/ bin / sh'指定为解释器的shell脚本只能使用POSIX功能”;实际上,这项要求自Ubuntu项目启动之初就已经存在。此外,任何可以移植到其他Unix系统(例如BSD或Solaris)的shell脚本都已经满足了这一要求。因此,我们认为此更改对兼容性的影响将最小。
dash
支持不需要的功能POSIX
吗?
在GNU / Linux发行版中,“原始/bin/sh
”实际上是Bash。
GNU希望使用一个在GPL之下的类Bourne外壳,因此这就是为什么他们选择Bash作为其/bin/sh
替代Bourne 的原因,而Bourne并非GPL许可的。现代Linux发行版继承了这一决定,以至于它成为/bin/sh
Bash 的事实上的标准。最初的Bourne shell(“ sh”)已在其他非Linux Unix中使用,甚至在Solaris 10之前也已使用,但是它从未成为Linux发行版的中流tay柱。
/bin/sh
从bash 切换到dash是Debian的一项决定(由Ubuntu继承),主要是出于速度的驱动-这是在他们花大力气提高启动速度的同时,启动CPU的大部分时间都与运行一致初始化脚本。
Bash继续用作用户的默认交互/登录外壳程序,但是Dash是/bin/sh
针对系统脚本(例如init脚本)执行的命令之一。
Dash速度很快,但也非常兼容POSIX-与Bourne Shell紧密结合的标准。因此,从某种程度上讲,通过从Bash切换到Dash,我们回到了与Bourne更加紧密对齐的外壳。
ksh
。我不记得具有算术扩展`$(())`的Bourne shell,它是POSIX。
^
是竖线字符-因此echo foo ^ cat
将foo ^ cat
在POSIX sh中发出,但foo
在伯恩(Bourne)中发出;这个特定的测试是Autoconf区分两者的方式。
/bin/sh
/bin/dash
我认为是出于兼容性原因而链接到。许多脚本只是以
#!/bin/sh
因此,通过移动到dash
而不进行符号链接,如果/bin/sh
根本不存在,许多脚本将无法正常运行(或根本无法运行)。
进行了从更改bash
,dash
因为根据https://wiki.ubuntu.com/DashAsBinSh:
切换默认Shell的主要原因是效率。bash是适合交互使用的出色的全功能外壳;实际上,它仍然是默认的登录外壳。但是,与破折号相比,它的启动和操作相当庞大且缓慢。作为Ubuntu引导过程的一部分,启动了大量的Shell实例。Ubuntu核心开发团队认为,最好不要进行单独更改以使其在/ bin / dash下显式运行,而这种更改将需要大量的日常维护,并且如果没有引起足够的注意,则很可能会倒退。默认外壳。
sh
未链接到bash
,因为
Debian政策手册长期以来一直要求“将'/ bin / sh'指定为解释器的shell脚本只能使用POSIX功能”
如果要bash
用作/bin/sh
:
如果问题更加普遍,并且您想要改回默认的系统外壳,则可以指示软件包管理系统停止将破折号安装为/ bin / sh:
sudo dpkg-reconfigure dash
dash
bash不提供某些功能,例如:
甚至有外界的机会,现在有一些脚本依赖于bash无法提供的破折号的某些功能!
sh
到/bin/sh
,这会破坏那些启动脚本吗?
/bin/sh
发行版提供的shell,因为这正是他们通过启动脚本等获得的目标。但是,如果您确实用Bourne取代了它,那么它几乎可以兼容。我可以想象会有破损,只是由于微小的差异与纯粹的代码量所致。当然,您可以通过自定义的hashbang随意使用自己的脚本中的任何shell。
/bin/sh
链接到哪个外壳独立于任何特定用户设置为其初始登录外壳的外壳。的目标/bin/sh
并不取决于所查看的用户,因此您确实需要使用- sudo
或其他充当root用户的方式-对其进行更改。另外,通常,对于任何软件包,都dpkg-reconfigure
必须以root用户身份运行。相反,通常允许用户更改其自己的初始登录Shell,并且可以使用chsh
命令进行更改。一个人的初始登录Shell的名称也将输入$SHELL
,也用于一些交互式非登录Shell。