sh和bash之间的区别

时间:2011-04-20 03:33:17

标签: bash shell unix sh

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

bashsh之间的主要区别是什么?

bashsh编程时,我们需要注意什么?

12 个答案:

答案 0 :(得分:977)

什么是sh

sh(或Shell命令语言)是POSIX standard描述的编程语言。 它有许多实现(ksh88dash,...)。 bash也可以 被视为sh的实施(见下文)。

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

什么是bash

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

bash支持--posix切换,这使其更符合POSIX标准。如果调用sh,它还会尝试模仿POSIX。

sh = bash?

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

/bin/sh未指向/bin/bash(以及某些/bin/bash可能不存在的系统)的一些常见示例包括:

  1. 现代Debian和Ubuntu系统,默认情况下符号链接shdash;
  2. Busybox,通常在Linux系统引导期间作为initramfs的一部分运行。它使用ash shell实现。
  3. BSD,通常是任何非Linux系统。 OpenBSD使用pdksh,它是Korn shell的后代。 FreeBSD的sh是原始UNIX Bourne shell的后代。 Solaris有自己的sh,很长一段时间不符合POSIX标准; Heirloom project
  4. 提供免费实施

    如何找出系统中/bin/sh分的内容?

    复杂性是/bin/sh可能是符号链接或硬链接。 如果它是符号链接,则portable解决方法是:

    % file -h /bin/sh
    /bin/sh: symbolic link to bash
    

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

    % find -L /bin -samefile /bin/sh
    /bin/sh
    /bin/bash
    

    实际上,-L标志包含符号链接和硬链接, 但这种方法的缺点是它不便携 - POSIX does not require find支持-samefile选项, 虽然GNU findFreeBSD find都支持它。

    Shebang line

    最终,您可以通过编写«shebang»行来决定使用哪一个。

    E.g。

    #!/bin/sh
    

    将使用sh(以及任何指向的内容),

    #!/bin/bash
    
    如果可用,

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

    #!/bin/dash
    

    使用哪一个

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

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

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

答案 1 :(得分:110)

shhttp://man.cx/sh
bashhttp://man.cx/bash

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

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

答案 2 :(得分:53)

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

首先,你应该明白会发生什么。

  • 如果您使用sh scriptname运行脚本,或者使用scriptname运行脚本并在shebang行中使用#!/bin/sh,那么您应该期望POSIX sh行为
  • 如果您使用bash scriptname运行脚本,或者使用scriptname运行脚本并且在shebang行中使用#!/bin/bash(或本地等效项),则应该预期Bash行为。

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

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

Bash参考手册有一个section which attempts to enumerate the differences但是一些常见的混淆来源包括

  • [[sh中不可用(只有[更加笨重且有限)。
  • sh没有数组。
  • 某些Bash关键字(例如localsourcefunctionselect无法移植到sh。 (某些sh实施支持例如local。)
  • Bash有许多C风格的语法扩展,如$'string\nwith\tC\aescapes'和三参数for((i=0;i<=3;i++))循环,+=增量分配等。
  • Bash支持<<<'here strings'
  • Bash有*.{png,jpg}{0..12}支撑扩展。
  • ~仅在Bash中引用$HOME(更常见的是~usernameusername的主目录。)这是在POSIX中,但可能正在从一些POSIX前/bin/sh实施中获益。
  • Bash使用<(cmd)>(cmd)进行流程替换。
  • Bash具有Csh样式的便捷重定向别名,例如&|的{​​{1}}和2>&1 |的{​​{1}}
  • Bash支持使用&>重定向的协同处理。
  • Bash提供了一组丰富的扩展非标准参数扩展,例如> ... 2>&1<>,大小写转换等。
  • Bash显着扩展了shell算法的功能(尽管仍然没有浮点支持)。
  • 许多Bash-only扩展,用于启用或禁用可选行为并公开shell的内部状态。
  • 用于交互式使用的许多便利功能,但不会影响脚本行为。

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

常见的错误是拥有${substring:1:2} shebang行,但仍然使用${variable/pattern/replacement}来实际运行脚本。这基本上禁用了任何仅限Bash的功能,因此您会收到语法错误,例如试图使用数组。

不幸的是,当您在#!/bin/bash调用这些结构时尝试使用这些结构时,Bash不会发出警告。它也不会完全禁用所有所有 Bash功能,因此通过将其调用为sh scriptname来运行Bash不是检查脚本是否可以正确移植到{{}}的好方法。 {3}} / ash / POSIX dashsh

等变体

答案 3 :(得分:47)

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

上表的关键。

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

外壳中没有N功能。

F功能只能通过使用shells功能来完成           机构。

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.

答案 4 :(得分:34)

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

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

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

类比:

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

enter image description here

答案 5 :(得分:22)

TERMINAL

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

<强> SHELL

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

SH Vs. BASH

<强> SH

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

<强> BASH

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

参考资料:

<强> SHELL gnu.org:

  

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

     

Unix shell既是命令解释器又是编程语言。   作为命令解释器,shell提供了用户界面   丰富的GNU实用程序集。编程语言功能允许   这些实用程序要合并。包含命令的文件可以是   创造,并成为命令本身。这些新命令有   与/ bin等目录中的系统命令相同,允许   用户或组建立自定义环境以自动化他们的   共同的任务。

     

可以交互式或非交互式使用shell。在互动中   模式,他们接受从键盘输入的输入。执行时   非交互式,shell执行从文件读取的命令。

     

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

     

Shell还提供了一小组内置命令(内置命令)   实现不可能或不方便获得通过的功能   单独的实用程序例如,cd,break,continue和exec不能   在shell之外实现,因为它们直接操作   壳本身。其中包括历史,傀儡,杀戮或者内置的   其他的,可以在单独的实用程序中实现,但它们更多   方便用作内置命令。所有的shell内置都是   在随后的章节中描述。​​

     

执行命令至关重要,大部分功能(和   shell的复杂性是由于它们的嵌入式编程语言。   像任何高级语言一样,shell提供变量,流   控制构造,引用和功能。

     

Shells提供专门用于交互式使用的功能   而不是增加编程语言。这些互动功能   包括作业控制,命令行编辑,命令历史和   别名。本手册中介绍了这些功能中的每一项。

BASH gnu.org:

  

Bash是GNU的shell或命令语言解释器   操作系统。这个名字是'Bourne-Again SHell'的首字母缩写,   史蒂芬伯恩的一个双关语,他的直系祖先的作者   目前的Unix shell sh,出现在第七版贝尔实验室   研究版Unix。

     

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

     

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

答案 6 :(得分:14)

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

此外,还有一个名为checkbashisms的强大工具可以检查脚本中的基础知识,并且当您想要确保脚本是可移植的时,它会派上用场。

答案 7 :(得分:3)

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

sh支持至少功能required by POSIX(假设正确实施)。它也可能支持扩展。

bash,&#34; Bourne Again Shell&#34;,实现了sh plus bash特定扩展所需的功能。完整的扩展集在这里描述的时间太长,并且随着新版本的不同而不同。 bash手册中记录了这些差异。输入info bash并阅读&#34; Bash功能&#34;部分(当前版本的第6部分),或阅读current documentation online

答案 8 :(得分:2)

它们几乎相同,但是bash具有更多功能sh(或多或少)是bash的较旧子集。

sh通常是指原始Bourne shell,其早于bashBourne *again* shell),创建于1977年。但是,实际上,最好考虑一下它是高度兼容的外壳,符合1992年的POSIX标准。

#!/bin/sh开头或使用sh shell的脚本通常这样做是为了向后兼容。任何unix / linux操作系统都将具有sh shell。在Ubuntu sh上经常调用dash,在MacOS上,它是bash的特殊POSIX版本。对于标准兼容的行为,速度或向后兼容性,这些外壳可能是首选。

bash比原始的sh更新,添加了更多功能,并力求与sh向后兼容。从理论上讲,sh程序应在bash中运行。 bash在几乎所有linux / unix机器上都可用,通常默认情况下使用–值得注意的是MacOS在Catalina(10.15)之前默认为zsh。 FreeBSD默认情况下未安装bash

答案 9 :(得分:2)

尽可能轻松地实现差异: 有了基本了解之后,上面发布的其他评论将更容易理解。

Shell -“ Shell”是一个程序,可促进用户与操作系统(内核)之间的交互。有许多shell实现可用,例如sh,bash,csh,zsh ...等。

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

重击-它源自 B ourne- a 获得 Sh ell。使用此程序,我们将能够执行Shell指定的所有命令。此外,我们将能够执行一些专门添加到该程序中的命令。 Bash与sh具有向后兼容性。

Sh-它源自Bourne Sh ell。 “ sh”支持外壳程序中指定的所有命令。就是说,使用该程序,我们将能够执行Shell指定的所有命令。

有关更多信息,请执行以下操作: -https://man.cx/sh -https://man.cx/bash

答案 10 :(得分:0)

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

Shell脚本是在任何Shell中编写脚本,而Bash脚本是专门为Bash编写脚本。但是,实际上,除非有问题的shell不是Bash,否则“ shell脚本”和“ bash脚本”通常可以互换使用。

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

答案 11 :(得分:-1)

Linux操作系统提供了不同类型的Shell。尽管shell有许多共同的命令,但每种类型都有其独特的功能。 让我们研究另一种最常用的外壳。

Sh shell:

Sh shell也称为Bourne Shell。 Sh shell是1977年由AT&T的Bell Labs的Stephen Bourne为Unix计算机开发的第一个shell。它包含许多脚本工具。

重击外壳:

Bash shell代表Bourne Again Shell。 Bash shell是大多数linux发行版中的默认shell,并替代Sh Shell(Sh shell也将在Bash shell中运行)。 Bash Shell可以执行绝大多数Sh Shell脚本,而无需进行修改,并且还提供命令行编辑功能。