sh和bash之间的区别

Wei*_*ang 1194 unix bash shell sh

在编写shell程序时,我们经常使用/bin/sh/bin/bash.我经常使用bash,但我不知道它们之间有什么区别.

bash和之间的主要区别是sh什么?

我们究竟需要意识到在编程时bashsh

Rom*_*aka 1043

什么是sh

sh(或Shell命令语言)是POSIX标准描述的编程语言.它有许多的实现(ksh88,dash,...).bash也可以被视为一种实现sh(见下文).

因为sh是规范而​​不是实现,所以/bin/sh是大多数POSIX系统上实际实现的符号链接(或硬链接).

什么是bash

bash最初是作为一个sh兼容的实现(虽然它早于POSIX标准几年),但随着时间的推移它已经获得了许多扩展.其中许多扩展可能会更改有效POSIX shell脚本的行为,因此它本身bash不是有效的POSIX shell.相反,它是POSIX shell语言的方言.

bash支持--posix交换机,使其更符合POSIX标准.它也试图模仿POSIX如果被调用为sh.

sh = bash?

很长一段时间,/bin/sh过去常常指向/bin/bash大多数GNU/Linux系统.结果,忽略两者之间的差异几乎是安全的.但最近这种情况开始发生变化.

系统一些流行的例子,其中/bin/sh不指向/bin/bash(和其中一些/bin/bash可能根本不存在)是:

  1. 现代Debian和Ubuntu系统,其符号链接shdash默认;
  2. Busybox,通常在Linux系统启动时运行,作为其中的一部分initramfs.它使用ashshell实现.
  3. BSD,通常是任何非Linux系统.OpenBSD使用pdkshKorn shell的后代.FreeBSD sh是原始UNIX Bourne shell的后代.Solaris有自己的sh,很长一段时间不符合POSIX标准; Heirloom项目提供免费实施.

你怎么能找出/bin/sh你的系统有什么意义?

复杂/bin/sh性可能是符号链接或硬链接.如果它是一个符号链接,解决它的便携方式是:

% file -h /bin/sh
/bin/sh: symbolic link to bash
Run Code Online (Sandbox Code Playgroud)

如果这是一个硬链接,请尝试

% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
Run Code Online (Sandbox Code Playgroud)

事实上,该-L标志包括符号链接和硬链接,但这种方法的缺点是它不可移植 - 虽然GNU findFreeBSD都支持它,但POSIX 不需要 find支持该-samefile选项.

Shebang线

最终,由你来决定使用哪一个,通过编写«shebang»系列.

例如

#!/bin/sh
Run Code Online (Sandbox Code Playgroud)

将使用sh(和任何碰巧指出的),

#!/bin/bash
Run Code Online (Sandbox Code Playgroud)

将使用/bin/bash它是否可用(如果不可用则失败并显示错误消息).当然,您也可以指定其他实现,例如

#!/bin/dash
Run Code Online (Sandbox Code Playgroud)

哪一个使用

对于我自己的脚本,我更喜欢sh以下原因:

  • 它是标准化的
  • 它更简单,更容易学习
  • 它可以在POSIX系统中移植 - 即使它们没有bash,也需要它们sh

使用也有好处bash.它的特点使编程更方便,类似于其他现代编程语言的编程.这些包括范围局部变量和数组.Plain sh是一种非常简约的编程语言.

  • 它可能意味着它们将`/ bin/tcsh`指定为`/ etc/passwd`中的默认交互式shell,而不是它们使用`tcsh`作为`sh`实现.`tcsh`具有C shell语法; 它甚至与sh POSIX标准都不兼容.有关FreeBSD的`sh`的描述,请参见http://www.freebsd.org/cgi/man.cgi?query=sh&sektion=1. (13认同)
  • 谢谢你的解释!作为参考,也可以在MacOS上使用sh!= bash. (3认同)
  • 在实践中,几乎每个`sh`的实现都支持使用关键字`local`声明的局部变量. (3认同)
  • @bizi Korays-MacBook-Pro:hello2 koraytugay $ sh --version GNU bash,版本3.2.57(1)-release(x86_64-apple-darwin14)版权所有(C)2007 Free Software Foundation,Inc.Korays-MacBook-Pro :hello2 koraytugay $ bash --version GNU bash,版本3.2.57(1)-release(x86_64-apple-darwin14)版权所有(C)2007 Free Software Foundation,Inc. (3认同)
  • @JosephHarriott,这是一个提示:由 shell 本身打印的字符,后面跟着您的命令。某些 shell 使用“$”而不是“%”,或者使用“#”作为根 shell。 (3认同)
  • @IanTait而不是`STR = ~REGEX`你可以使用`echo STR | grep -q REGEX`. (2认同)
  • 如果您使用“bash”运行脚本,则在出现语法错误时会显示更有用的错误消息。使用 bash 可以简单地节省时间。 (2认同)
  • @JosephHarriott - `%` 通常是 C Shell 类型的 _user_ shell(例如 csh、tcsh)的提示符。传统上,“#”被保留为超级用户(root)shell 的提示字符,无论选择哪一个。但这都属于常见/典型用法的范围,正如历史/传统上观察到的那样。您可以使用您喜欢的和/或用户可以容忍的。:) [谷歌如何](https://www.google.com/search?q=customize-unix-shell-prompt) (2认同)

Rei*_*chs 125

sh:http
bash://man.cx/sh:http://man.cx/bash

TL; DR:bash是一个sh具有更优雅的语法和更多功能的超集.在几乎所有情况下使用bash shebang系列是安全的,因为它在现代平台上非常普遍.

注意:在某些环境中,sh bash.检查sh --version.

  • 如果bash被调用为sh,它的行为有点不同.请参阅http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files("使用名称sh调用")和http://www.gnu.org/software/bash/manual /bashref.html#Bash-POSIX-Mode.例如,没有进程替换. (30认同)
  • 由于bash是sh的超集,并且某些操作系统(如FreeBSD)默认情况下没有安装bash,因此sh中的脚本将提供更大的可移植性. (11认同)
  • 在Ubuntu 16.04.3 LTS上,命令sh --version失败。 (2认同)

tri*_*eee 71

这个问题经常被提名为试图使用的人的规范,sh并且对于它的行为不一样感到惊讶bash.以下是常见误解和陷阱的快速概述.

首先,您应该了解会发生什么.

  • 如果你运行你的脚本sh scriptname,或运行它scriptname,并有#!/bin/sh家当行,你应该期望POSIX sh的行为.
  • 如果您使用shebang行运行脚本bash scriptname,或者在shebang行中scriptname使用#!/bin/bash(或本地等效项),则应该期望Bash行为.

拥有正确的shebang并通过仅键入脚本名称(可能具有相对路径或完整路径)来运行脚本通常是首选解决方案.除了正确的shebang之外,这还要求脚本文件具有执行权限(chmod a+x scriptname).

那么,它们实际上有何区别?

Bash参考手册有一个部分试图列举差异,但一些常见的混淆来源包括

  • [[不适用sh(只有[更笨重和有限).
  • sh 没有数组.
  • 一些Bash关键字,如local,sourcefunction,不可移植到shopt.
  • Bash有许多C风格的语法扩展,如let三参数declare循环,select增量赋值等.
  • Bash支持sh.
  • Bash拥有shlocal支持扩张.
  • for((i=0;i<=3;i++))仅指+=Bash(更一般地说$'string\nwith\tC\aescapes'是主目录sh).这是在POSIX中,但可能会从一些POSIX之前的<<<'here strings'实现中产生影响.
  • Bash使用*.{png,jpg}和替换进程{0..12}.
  • Bash支持具有~重定向的协同处理.
  • Bash显着扩展了shell算法(尽管仍然没有浮点支持)和变量子串操作的设施$HOME,包括~username,case转换等.
  • 许多Bash-only扩展,用于启用或禁用可选行为并公开shell的内部状态.
  • 用于交互式使用的许多便利功能然而不影响脚本行为.

请记住,这是一个简略的列表.有关完整的独家新闻,请参阅参考手册;有关很多良好的解决方法,请参阅http://mywiki.wooledge.org/Bashism ; 和/或尝试http://shellcheck.net/警告许多Bash功能.

一个常见的错误是有一个usernameshebang行,但然后使用/bin/sh实际运行脚本.这基本上禁用了任何仅限Bash的功能,因此您会遇到语法错误,例如尝试使用数组.

不幸的是,当你尝试使用这些结构时,Bash不会发出警告<(cmd).它也没有完全禁用所有 Bash功能,因此通过调用它来运行Bash >(cmd)不是检查脚本是否可以正确移植到&|/ 2>&1 |/ POSIX &>或像Heirloom这样的变种的好方法> ... 2>&1

  • [shellcheck.net](https://www.shellcheck.net)就是我所需要的.非常感谢. (3认同)
  • 从根本上讲,TL; DR版本是[And的答案](http://stackoverflow.com/a/30294230/874188)。 (2认同)

Sri*_*niV 49

UNIX.COM发布

外壳功能

下表列出了我认为可以让您选择一个shell而不是另一个shell的大多数功能.它不是一个明确的列表,也不包括每个可能的shell的每个可能的功能.如果在操作系统附带的版本中,或者如果可以直接从标准分发编译,则该功能仅被视为在shell中.特别是下面指定的C shell是SUNOS 4上提供的.*,相当多的供应商现在提供tcsh或他们自己的增强型C shell(他们并不总是明确表示他们正在运送tcsh.

码:

                                     sh   csh  ksh  bash tcsh zsh  rc   es
Job control                          N    Y    Y    Y    Y    Y    N    N
Aliases                              N    Y    Y    Y    Y    Y    N    N
Shell functions                      Y(1) N    Y    Y    N    Y    Y    Y
"Sensible" Input/Output redirection  Y    N    Y    Y    N    Y    Y    Y
Directory stack                      N    Y    Y    Y    Y    Y    F    F
Command history                      N    Y    Y    Y    Y    Y    L    L
Command line editing                 N    N    Y    Y    Y    Y    L    L
Vi Command line editing              N    N    Y    Y    Y(3) Y    L    L
Emacs Command line editing           N    N    Y    Y    Y    Y    L    L
Rebindable Command line editing      N    N    N    Y    Y    Y    L    L
User name look up                    N    Y    Y    Y    Y    Y    L    L
Login/Logout watching                N    N    N    N    Y    Y    F    F
Filename completion                  N    Y(1) Y    Y    Y    Y    L    L
Username completion                  N    Y(2) Y    Y    Y    Y    L    L
Hostname completion                  N    Y(2) Y    Y    Y    Y    L    L
History completion                   N    N    N    Y    Y    Y    L    L
Fully programmable Completion        N    N    N    N    Y    Y    N    N
Mh Mailbox completion                N    N    N    N(4) N(6) N(6) N    N
Co Processes                         N    N    Y    N    N    Y    N    N
Builtin artithmetic evaluation       N    Y    Y    Y    Y    Y    N    N
Can follow symbolic links invisibly  N    N    Y    Y    Y    Y    N    N
Periodic command execution           N    N    N    N    Y    Y    N    N
Custom Prompt (easily)               N    N    Y    Y    Y    Y    Y    Y
Sun Keyboard Hack                    N    N    N    N    N    Y    N    N
Spelling Correction                  N    N    N    N    Y    Y    N    N
Process Substitution                 N    N    N    Y(2) N    Y    Y    Y
Underlying Syntax                    sh   csh  sh   sh   csh  sh   rc   rc
Freely Available                     N    N    N(5) Y    Y    Y    Y    Y
Checks Mailbox                       N    Y    Y    Y    Y    Y    F    F
Tty Sanity Checking                  N    N    N    N    Y    Y    N    N
Can cope with large argument lists   Y    N    Y    Y    Y    Y    Y    Y
Has non-interactive startup file     N    Y    Y(7) Y(7) Y    Y    N    N
Has non-login startup file           N    Y    Y(7) Y    Y    Y    N    N
Can avoid user startup files         N    Y    N    Y    N    Y    Y    Y
Can specify startup file             N    N    Y    Y    N    N    N    N
Low level command redefinition       N    N    N    N    N    N    N    Y
Has anonymous functions              N    N    N    N    N    N    Y    Y
List Variables                       N    Y    Y    N    Y    Y    Y    Y
Full signal trap handling            Y    N    Y    Y    N    Y    Y    Y
File no clobber ability              N    Y    Y    Y    Y    Y    N    F
Local variables                      N    N    Y    Y    N    Y    Y    Y
Lexically scoped variables           N    N    N    N    N    N    N    Y
Exceptions                           N    N    N    N    N    N    N    Y
Run Code Online (Sandbox Code Playgroud)

上表的关键.

Y功能可以使用此shell完成.

外壳中不存在N Feature.

F功能只能通过使用shell功能机制来完成.

L必须将readline库链接到shell以启用此功能.

上表的注释

1. This feature was not in the original version, but has since become
   almost standard.
2. This feature is fairly new and so is often not found on many
   versions of the shell, it is gradually making its way into
   standard distribution.
3. The Vi emulation of this shell is thought by many to be
   incomplete.
4. This feature is not standard but unofficial patches exist to
   perform this.
5. A version called 'pdksh' is freely available, but does not have
   the full functionality of the AT&T version.
6. This can be done via the shells programmable completion mechanism.
7. Only by specifying a file via the ENV environment variable.
Run Code Online (Sandbox Code Playgroud)

  • 根据schily暴露的内容,似乎最好删除这个答案,因为它本质上是欺诈性的,OP并没有真正审查他粘贴的信息. (8认同)
  • 让我给出一些提示:作业控制于 1989 年添加到 Bourne Shell,Bourne Shell 于 2005 年开源。Korn shell 至少从 1988 年开始就有进程替换,并且自 1997 年以来就是开源的。顺便说一句:您关于 $ENV 的声明不正确,$ENV 仅针对交互式 shell 读取/执行。 (4认同)
  • 你的表对我来说没有用,因为它试图比较 Bourne Shell 的功能和 1988 年之前的 ksh 的功能。如果你真的为 1988 年制作一个表,你需要从该表中删除大多数其他 shell - 包括 bash 、sh 和 rc。您能解释一下您从哪里获得表的值吗? (3认同)
  • @schily这篇文章来自http://www.cs.virginia.edu/helpnet/Computer_OS/unix/shells/shelldiff.html (3认同)

Pre*_*raj 43

Shell是用户和操作系统之间的接口,用于访问操作系统的服务.它可以是GUI或CLI(命令行界面).

sh(Bourne sh ell)是一个shell命令行解释器,适用于Unix/Unix类操作系统.它提供了一些内置命令.在脚本语言中,我们将解释器表示为#!/bin/sh.它是其他shell最广泛支持的一种,如bash(自由/开放),kash(非自由).

Bash(B ourne a gain s hell)是Bourne shell的shell替代品.巴什是sh的超集.Bash支持sh.POSIX是一组标准,用于定义POSIX兼容系统应如何工作.Bash实际上不是POSIX兼容的shell.在脚本语言中,我们将解释器表示为#!/bin/bash.

比喻:

  • Shell就像一个接口或规范或API.
  • sh是一个实现Shell接口的类.
  • Bash是sh的子类.

在此输入图像描述

  • 我想这是试图说Bash继承自`sh`(因此它是OOP意义上的"子类")并扩展它(因此具有该功能的超集). (8认同)
  • 我不明白.你已经提到"Bash是sh的超集"和"Bash是sh的子类",它们不是相反的陈述吗?你能澄清一下吗? (3认同)
  • 屏幕截图很奇怪;它从何而来?如果 Bash 的“底层语法”是 `sh`,那么它也应该被列为 `ksh` 的底层语法。相反,您可能会说 Bash 的底层语法是“ksh”,因为多年来 Bash 大量借鉴了 Korn shell。 (2认同)

Tim*_*art 22

终奌站

  • 打开窗户的程序
  • xterm,rxvt,konsole,kvt,gnome-terminal,nxterm和eterm.

贝壳

  • 是在终端中运行的程序
  • Shell既是命令解释器又是编程语言
  • Shell只是一个执行命令的宏处理器.
  • 宏处理器意味着扩展文本和符号以创建更大表达式的功能.

SH比.BASH

SH

  • (贝壳)
  • 是一个特定的shell
  • 命令解释器和编程语言
  • BASH的前身

BASH

  • (Bourne-Again SHell)
  • 是一个特定的shell
  • 命令解释器和编程语言
  • 有sh功能和更多
  • SH的继任者
  • BASH是默认的SHELL

参考资料:

SHELL gnu.org:

在它的基础上,shell只是一个执行命令的宏处理器.术语宏处理器意味着扩展文本和符号以创建更大表达式的功能.

Unix shell既是命令解释器又是编程语言. 作为命令解释器,shell为丰富的GNU实用程序提供了用户界面.编程语言功能允许组合这些实用程序.可以创建包含命令的文件,并自己成为命令.这些新命令与/ bin等目录中的系统命令具有相同的状态,允许用户或组建立自定义环境以自动执行其常见任务.

壳可以以交互方式或非交互方式使用.在交互模式下,它们接受键盘输入的输入.当以非交互方式执行时,shell执行从文件读取的命令.

shell允许同步和异步执行GNU命令.shell在接受更多输入之前等待同步命令完成; 异步命令在读取和执行其他命令时继续与shell并行执行.重定向结构允许对这些命令的输入和输出进行细粒度控制.而且,shell允许控制命令环境的内容.

Shell还提供了一小组内置命令(内置命令),这些命令实现了通过单独的实用程序获取不可能或不方便的功能.例如,cd,break,continue和exec无法在shell外部实现,因为它们直接操作shell本身.历史,getopts,kill或pwd builtins等可以在单独的实用程序中实现,但它们作为内置命令使用起来更方便.所有shell内置函数都将在后续章节中介绍.

虽然执行命令是必不可少的,但shell的大部分功能(和复杂性)都是由于它们的嵌入式编程语言. 与任何高级语言一样,shell提供变量,流控制构造,引用和函数.

Shell提供专门用于交互式使用的功能,而不是增强编程语言.这些交互式功能包括作业控制,命令行编辑,命令历史记录和别名.本手册中描述了这些功能中的每一个.

BASH gnu.org:

Bash是GNU操作系统的shell或命令语言解释器.这个名字是'Bourne-Again SHell'的缩写,是Stephen Bourne的双关语,他是当前Unix shell sh的直接祖先的作者,出现在第七版贝尔实验室研究版的Unix中.

Bash在很大程度上与sh兼容,并结合了Korn shell ksh和C shell csh的有用功能.它旨在成为IEEE POSIX规范(IEEE标准1003.1)的IEEE POSIX Shell和Tools部分的一致实现.它为交互式和编程使用提供了超过sh的功能改进.

虽然GNU操作系统提供其他shell,包括csh版本,但Bash是默认shell.像其他GNU软件一样,Bash非常便携.它目前几乎运行在每个版本的Unix和一些其他操作系统上 - 为MS-DOS,OS/2和Windows平台提供独立支持的端口.


And*_*bis 14

其他答案一般指出了Bash和POSIX shell标准之间的区别.但是,在编写可移植的shell脚本并用于Bash语法时,一系列典型的bashisms和相应的纯POSIX解决方案非常方便.这个列表是在Ubuntu从Bash切换到Dash作为默认系统shell时编译的,可以在这里找到:https: //wiki.ubuntu.com/DashAsBinSh

此外,还有一个很棒的工具叫做checkbashisms,可以检查脚本中的bashisms,并且当你想要确保你的脚本是可移植的时候会很方便.


Gop*_* BG 12

bash 和 sh 是两个不同的 shell。基本上 bash 是 sh,具有更多功能和更好的语法。大多数命令的工作方式相同,但它们不同。Bash (bash) 是许多可用(但最常用)的 Unix shell 之一。Bash 代表“Bourne Again SHell”,是对原始 Bourne shell (sh) 的替代/改进。

Shell 脚本是在任何 shell 中编写脚本,而 Bash 脚本是专门为 Bash 编写的脚本。然而,在实践中,“shell 脚本”和“bash 脚本”经常互换使用,除非所讨论的 shell 不是 Bash。

话虽如此,您应该意识到大多数系统上的 /bin/sh 将是一个符号链接并且不会调用 sh。在 Ubuntu 中,/bin/sh 用于链接到 bash,这是 Linux 发行版上的典型行为,但现在已更改为链接到另一个名为 dash 的 shell。我会使用 bash,因为这几乎是标准(或者至少是最常见的,根据我的经验)。事实上,当 bash 脚本将使用 #!/bin/sh 时会出现问题,因为脚本制作者假定链接是到 bash 而不是必须的。


Rya*_*lor 9

它们几乎相同,但bash具有更多功能—— sh(或多或少)是bash.

sh通常意味着原件Bourne shell,它早于bash(Bourne *again* shell1977 年创建的 )。但实际上,最好将其视为符合 1992 年 POSIX 标准的高度交叉兼容的 shell。

#!/bin/shshshell开头或使用shell 的脚本通常这样做是为了向后兼容。任何 unix/linux 操作系统都会有一个shshell。在 Ubuntu 上sh经常调用dash,在 MacOS 上它是bash. 这些外壳可能是符合标准的行为、速度或向后兼容性的首选。

bash比原始版本更新sh,添加了更多功能,并寻求向后兼容sh. 理论上,sh程序应该在bash. bash几乎在所有 linux/unix 机器上都可用,并且通常默认使用——MacOS 的显着例外默认zsh为 Catalina (10.15)。默认情况下,FreeBSD 不附带bash安装。


Kei*_*son 6

/bin/sh可能会也可能不会调用与 相同的程序/bin/bash

sh至少支持POSIX 所需的功能(假设实现正确)。它也可能支持扩展。

bash,“Bourne Again Shell”,实现了 sh 加 bash 特定扩展所需的功能。完整的扩展集太长,无法在此描述,并且随着新版本的不同而有所不同。bash 手册中记录了这些差异。输入info bash并阅读“Bash Features”部分(当前版本中的第 6 部分),或在线阅读当前文档


小智 5

以最简单的方式解释差异:

有了基本的了解之后,其他的答案就会更容易理解了。

Shell - “Shell”是一个程序,它促进用户和操作系统(内核)之间的交互。有许多可用的 shell 实现,例如 sh、BashC shellZ shell等。

使用任何 shell 程序,我们将能够执行该 shell 程序支持的命令。

Bash -源自Bourne -一个shell 。使用这个程序,我们将能够执行 shell 指定的所有命令。此外,我们将能够执行一些专门添加到该程序中的命令。Bash 向后兼容 sh。

Sh - 它源自 Bourne shell。“sh”支持 shell 中指定的所有命令。这意味着,使用这个程序,我们将能够执行Shell指定的所有命令。

有关更多信息,请参阅: