bash和sh有什么区别?


28

我看到正在使用两种类型的代码:

#!/usr/bin/sh

和:

#!/user/bin/bash

我在网上搜索了此内容,意见分歧很大。我在大多数网站上看到的解释sh都比早bash,并且没有真正的区别。

有人知道两者之间的区别吗?您能给我一个实际的例子,何时在另一个上使用?


有关不同shell(不只是shand bash)的一般概述,请访问:http
akira 2010年

1
另一个伟大的历史在这里:faqs.org/faqs/unix-faq/shell/shell-differences
John Wright

Answers:


34

bash是的超集sh。一切你可以做sh你能做的bash

Bash具有更多功能(分支,内置插件,数组),使脚本更易于编写。稍后的* nix /bin/sh链接为/bin/bash

有关此教程的完整说明


5
@Saif Bechan:Bourne shell(sh)不仅被扩展的原因之一是Bash是由其他人编写的。我也敢打赌,那里有许可证问题。阅读有关Bourne Shell的文章en.wikipedia.org/wiki/Bourne_shell
Felix 2010年

7
删除sh会破坏很多脚本,这些脚本期望它存在并且依赖于它解析事物的方式。Linux用户可能不在乎,但是在Solaris,AIX或HP-UX上花费数千美元的人们可能会非常恼火。
njd 2010年

3
...为了获得更多乐趣,Ubuntu符号链接/ bin / sh到破折号。Dash并不完全兼容sh或bash,但应该可以更快地启动。当系统启动时,所有init.d脚本都会运行,我认为总体上节省的时间是值得的。
kbyrd

8
我很确定Dash完全符合sh。问题是有些人编写的脚本说/ bin / sh,但是脚本本身需要/ bin / bash才能工作。没有人注意到一个问题,因为在大多数情况下,/ bin / sh只是指向/ bin / bash。
davr 2010年

8
@Saif:sh不能简单扩展的另一个原因是:其源代码纯属地狱。看一看。应该为C ...
grawity

6

传统上,/ bin / sh是原始的Bourne shell,没有历史记录或命令行编辑,也没有作业控制。

在大约15年左右的时间里,大多数Unix都安装了POSIX shell,或者至少安装了ksh或bash(它们几乎类似于POSIX),但是在/ bin / sh中仍然具有更有限的shell。

这样做的原因是希望旧sh命令的旧外壳脚本仍然可以使用。
由于字符{}!对bash具有特殊含义,因此使用这些字符(不转义)的较旧的shell脚本可能会失败。
(Bourne shell将按!!{1,2}字面意义使用,而bash会将其解释为前一个命令(!!)的重复,然后是大括号扩展)。

但是,在Linux上,该sh命令几乎始终只是bash具有所有相同功能的的链接。


2
如果以/ bin / sh调用,Bash应该(但并非总是)以sh兼容模式运行。当Ubuntu将/ bin / sh从链接到/ bin / bash切换到链接到/ bin / dash时,发生了很多事情。当他们本应使用标准sh时,损坏的东西假定为bashisms。
Broam 2010年

4

sh可以表示Bourne shell或/ bin / sh,这是大多数现代平台上的其他一些(符合POSIX的)shell。“ POSIX shell”是POSIX定义的抽象shell,它由bash在POSIX模式下实现,或者默认情况下由ksh或dash实现。/ bin / sh有时也称为POSIX shell,因为它是在大多数平台上都符合POSIX的shell。原始的Bourne外壳不是POSIX外壳。

bashref列出了bash和Bourne shell之间差异在POSIX模式下调用bash时,man bash有一个更改列表。

/ bin / sh在OS X上不是符号链接或硬链接,但其大小几乎与/ bin / bash相同:

$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x  1 root  wheel  1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x  1 root  wheel  1334000 Jul 26 01:52 /bin/sh

男人的bash

如果使用名称sh调用bash,则它会尝试尽可能接近于sh的历史版本的启动行为,同时也要符合POSIX标准。

否则,对Bourne贝壳的模仿非常有限。bash +B(Bourne)实际上会禁用括号扩展之类的功能。

$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}

但是,即使禁用POSIX模式,echo -e默认情况下,echo的行为也类似于:

$ sh
$ shopt -uo posix
$ echo '1\b2'
2

/ bin / sh在Ubuntu上是破折号,因此在OS X上某些bashisms可与/ bin / sh一起使用,但在Ubuntu上不行。

如果您确实想为原始的Bourne shell(类似)编写脚本,则可以#!/usr/bin/env bash +B改用。

我认为为bash编写脚本比避免不属于POSIX规范或Bourne shell或不使用其他shell测试所有内容的功能要容易。


2

实际上,即使/ bin / sh可能是/ bin / bash的链接,但如果以sh身份启动,其行为也会有所不同。从bash手册页:

如果使用名称sh调用bash,则它会尝试尽可能接近于sh的历史版本的启动行为,同时也要符合POSIX标准。

因此sh,它试图模仿历史的sh行为。与一样bash,它试图像交互式登录shell一样有用。


2

在许多系统上,尤其是在Solaris上,bash是动态链接的,而sh是静态链接的。这可能会构成安全威胁,因此,root用户仅应将/ bin / sh用作shell(如果您需要以root身份登录)。


2
如果您做的不好,ldconfig或者/lib由于某种原因您的目录被清除,在紧急情况下也很有用。
LawrenceC
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.