编写shell程序时,我们经常使用/bin/sh
和/bin/bash
。我通常使用bash
,但我不知道它们之间有什么区别。
bash
和sh
之间的主要区别是什么?
在bash
和sh
编程时,我们需要注意什么?
答案 0 :(得分:977)
sh
(或Shell命令语言)是POSIX
standard描述的编程语言。
它有许多实现(ksh88
,dash
,...)。 bash
也可以
被视为sh
的实施(见下文)。
因为sh
是规范而不是实现,/bin/sh
是符号链接
(或硬链接)到大多数POSIX系统的实际实现。
bash
最初是sh
兼容的实现(虽然它早于POSIX标准几年),但随着时间的推移它已经获得了许多扩展。其中许多扩展可能会更改有效POSIX shell脚本的行为,因此bash
本身不是有效的POSIX shell。相反,它是POSIX shell语言的方言。
bash
支持--posix
切换,这使其更符合POSIX标准。如果调用sh
,它还会尝试模仿POSIX。
很长一段时间以来,/bin/sh
曾经指向大多数GNU / Linux系统上的/bin/bash
。结果,忽略两者之间的差异几乎是安全的。但最近这种情况开始发生变化。
/bin/sh
未指向/bin/bash
(以及某些/bin/bash
可能不存在的系统)的一些常见示例包括:
sh
到dash
; initramfs
的一部分运行。它使用ash
shell实现。pdksh
,它是Korn shell的后代。 FreeBSD的sh
是原始UNIX Bourne shell的后代。 Solaris有自己的sh
,很长一段时间不符合POSIX标准; Heirloom project。如何找出系统中/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 find和FreeBSD find都支持它。
最终,您可以通过编写«shebang»行来决定使用哪一个。
E.g。
#!/bin/sh
将使用sh
(以及任何指向的内容),
#!/bin/bash
如果可用,将使用/bin/bash
(如果不可用,则会失败并显示错误消息)。当然,您也可以指定其他实现,例如
#!/bin/dash
对于我自己的脚本,我更喜欢sh
,原因如下:
bash
,也需要sh
使用bash
也有好处。它的特点使编程更方便,类似于其他现代编程语言的编程。这些包括范围局部变量和数组。简单sh
是一种非常简约的编程语言。
答案 1 :(得分:110)
sh
:http://man.cx/sh
bash
:http://man.cx/bash
TL; DR :bash
是sh
的超集,具有更优雅的语法和更多功能。在几乎所有情况下使用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
没有数组。local
,source
,function
和select
无法移植到sh
。 (某些sh
实施支持例如local
。)$'string\nwith\tC\aescapes'
和三参数for((i=0;i<=3;i++))
循环,+=
增量分配等。<<<'here strings'
。*.{png,jpg}
和{0..12}
支撑扩展。~
仅在Bash中引用$HOME
(更常见的是~username
到username
的主目录。)/bin/sh
实施中获益。<(cmd)
和>(cmd)
进行流程替换。&|
的{{1}}和2>&1 |
的{{1}} &>
重定向的协同处理。> ... 2>&1
,<>
,大小写转换等。请记住,这是一个简略的列表。有关完整的独家新闻,请参阅参考手册;有关许多良好的解决方法,请参阅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 dash
或sh
答案 3 :(得分:47)
外壳功能
下表列出了我认为可以让您选择一个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
。
类比:
答案 5 :(得分:22)
TERMINAL
<强> SHELL 强>
SH Vs. BASH 强>
<强> SH 强>
<强> BASH 强>
参考资料:
<强> 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
,其早于bash
(Bourne *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)
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脚本,而无需进行修改,并且还提供命令行编辑功能。