sh与破折号链接有什么意义?


35

我想知道与sh符号链接的意义dash是什么?我知道那dash应该比更快bash,但是我不确定为什么原来的shshell不存在sh

或为什么没有sh链接到任何东西bash

Answers:


70

关于“为什么原始sh外壳不存在sh” 的简短答案是没有原始sh。

好的,有:这是汤普森弹壳。版本1具有我们今天所知道的一些功能,特别是重定向和管道(请阅读Dennis Ritchie的有关Unix早期历史的论文)。后来的版本增加了一些功能,例如带有后台执行&,globlob(由外部程序实现)和某些形式的引用,但它没有变量或嵌套的控制结构。通过外部程序if(以一个条件和一个命令作为参数)和goto(通过更改其父文件在脚本文件中的位置来工作)提供了条件和循环。

1979年,在Unix V7中,汤普森(Thompson)外壳/bin/shBourne外壳代替。第一个版本已经具有今天破折号中提供的许多功能,后续版本引入了更多功能。几年后,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


我认为有充分的理由将ksh93用作/ bin / sh -这是可用的性能最高的POSIX shell之一。同意破折号的普遍存在只是时间问题。
Charles Duffy

2
@CharlesDuffy Ksh93处理复杂事物的速度更快,但在启动时间和短脚本(例如system应用程序对(3)的所有调用)中的破折号击败了它,这是主要因素。
吉尔(Gilles)'所以

21

速度和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脚本都已经满足了这一要求。因此,我们认为此更改对兼容性的影响将最小。

参见https://wiki.ubuntu.com/DashAsBinSh


dash支持不需要的功能POSIX吗?
NerdOfLinux

@NerdOfLinux除了POSIX之外,/ bin / sh支持什么也没有关系(只要这些添加不会破坏POSIX脚本);重要的是它支持所有POSIX(并尽可能快)。只要破折号满足这些要求,/ bin / sh就可以链接到它。
Guntram Blohm支持Monica 17'Nov

9

在GNU / Linux发行版中,“原始/bin/sh”实际上是Bash。

GNU希望使用一个在GPL之下的类Bourne外壳,因此这就是为什么他们选择Bash作为其/bin/sh替代Bourne 的原因,而Bourne并非GPL许可的。现代Linux发行版继承了这一决定,以至于它成为/bin/shBash 的事实上的标准。最初的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更加紧密对齐的外壳。


“破折号非常快,但也非常兼容POSIX-与Bourne shell紧密结合的标准。”是的,尽管POSIX与之紧密相关ksh。我不记得具有算术扩展`$(())`的Bourne shell,它是POSIX。
Sergiy Kolodyazhnyy

1
另外,在伯恩(Bourne)中,^是竖线字符-因此echo foo ^ catfoo ^ cat在POSIX sh中发出,但foo在伯恩(Bourne)中发出;这个特定的测试是Autoconf区分两者的方式。
Charles Duffy

有趣,所以通过POSIX,您是说Korn吗?
thomasrutter

0

/bin/sh/bin/dash我认为是出于兼容性原因而链接到。许多脚本只是以

#!/bin/sh

因此,通过移动到dash而不进行符号链接,如果/bin/sh根本不存在,许多脚本将无法正常运行(或根本无法运行)。

进行了从更改bashdash因为根据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

dashbash不提供某些功能,例如:

甚至有外界的机会,现在有一些脚本依赖于bash无法提供的破折号的某些功能!


我已经知道兼容性可能是一个因素,但我一直在寻找一个不太明显且更深入的答案...
NerdOfCode

2
因此,如果我将原始bourne外壳安装sh/bin/sh,这会破坏那些启动脚本吗?
甜点

最好是先在虚拟机中尝试一下,然后再部署到现实世界中……
NerdOfCode

2
您应该保留/bin/sh发行版提供的shell,因为这正是他们通过启动脚本等获得的目标。但是,如果您确实用Bourne取代了它,那么它几乎可以兼容。我可以想象会有破损,只是由于微小的差异与纯粹的代码量所致。当然,您可以通过自定义的hashbang随意使用自己的脚本中的任何shell。
thomasrutter

1
@mckenzm /bin/sh链接到哪个外壳独立于任何特定用户设置为其初始登录外壳的外壳。的目标/bin/sh并不取决于所查看的用户,因此您确实需要使用- sudo或其他充当root用户的方式-对其进行更改。另外,通常,对于任何软件包,都dpkg-reconfigure必须以root用户身份运行。相反,通常允许用户更改其自己的初始登录Shell,并且可以使用chsh命令进行更改。一个人的初始登录Shell的名称也将输入$SHELL,也用于一些交互式非登录Shell。
伊利亚·卡根
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.