sh 和 Bash 之间的区别
在编写shell程序时,我们经常使用/bin/sh
和/bin/bash
。我通常使用bash
,但我不知道它们之间有什么区别。
Bash 和 sh
之间的主要区别是什么?
在Bash和sh中编程时需要注意什么?
When writing shell programs, we often use /bin/sh
and /bin/bash
. I usually use bash
, but I don't know what's the difference between them.
What's main difference between Bash and sh
?
What do we need to be aware of when programming in Bash and sh
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
sh是什么?
sh
(或 Shell 命令语言)是由 POSIX 标准。它有许多实现(ksh88
、Dash ,...)。 Bash 也可以被认为是sh
的实现(见下文)。因为
sh
是一个规范,而不是一个实现,所以/bin/sh
是大多数 POSIX 系统上实际实现的符号链接(或硬链接)。什么是巴什?
Bash 最初是一个与
sh
兼容的实现(尽管它早于 POSIX 标准几年),但随着时间的推移,它已经获得了许多扩展。其中许多扩展可能会更改有效 POSIX shell 脚本的行为,因此 Bash 本身并不是有效的 POSIX shell。相反,它是 POSIX shell 语言的一种方言。Bash 支持
--posix
开关,这使其更符合 POSIX 标准。如果作为sh
调用,它还会尝试模仿 POSIX。sh = bash?
很长一段时间以来,在大多数 GNU/Linux 系统上,
/bin/sh
用来指向/bin/bash
。结果,几乎可以安全地忽略两者之间的差异。但这种情况最近开始发生变化。一些流行的系统示例,其中
/bin/sh
不指向/bin/bash
(并且在某些系统上/bin/bash
可能会指向/bin/bash
)甚至不存在)是:sh
符号链接到dash
;initramfs.它使用 ash shell 实现。
pdksh
,它是 KornShell。 FreeBSD 的sh
是原始 Unix Bourne shell 的后代。 Solaris 有自己的sh
,长期以来不符合 POSIX 标准; Heirloom 项目 提供免费实现。如何找出
/bin/sh
在您的系统上指向什么?复杂的是
/bin/sh
可能是符号链接或硬链接。如果它是符号链接,则解决该问题的可移植方法是:这是一个硬链接,请尝试
事实上,
-L
标志涵盖了符号链接和硬链接,但这种方法的缺点是不可移植——
POSIX 不需要
find
支持-samefile
选项,尽管都是 GNU 查找 和 FreeBSD find 支持它。Shebang 行
最终,您可以通过将“shebang”行写为脚本的第一行来决定使用哪一个。
例如,
将使用
sh
(以及任何它所指向的内容),如果可用,将使用
/bin/bash
(如果不可用,则会失败并显示错误消息)。当然,您还可以指定另一种实现,例如使用哪个实现
对于我自己的脚本,我更喜欢
sh
,原因如下:bash
,它们也需要有sh
使用
bash
也有优点。它的特性使编程更加方便并且类似于其他现代编程语言的编程。其中包括作用域局部变量和数组等。 Plainsh
是一种非常简约的编程语言。What is sh?
sh
(or the Shell Command Language) is a programming language described by the POSIX standard. It has many implementations (ksh88
, Dash, ...). Bash can also be considered an implementation ofsh
(see below).Because
sh
is a specification, not an implementation,/bin/sh
is a symlink (or a hard link) to an actual implementation on most POSIX systems.What is Bash?
Bash started as an
sh
-compatible implementation (although it predates the POSIX standard by a few years), but as time passed it has acquired many extensions. Many of these extensions may change the behavior of valid POSIX shell scripts, so by itself Bash is not a valid POSIX shell. Rather, it is a dialect of the POSIX shell language.Bash supports a
--posix
switch, which makes it more POSIX-compliant. It also tries to mimic POSIX if invoked assh
.sh = bash?
For a long time,
/bin/sh
used to point to/bin/bash
on most GNU/Linux systems. As a result, it had almost become safe to ignore the difference between the two. But that started to change recently.Some popular examples of systems where
/bin/sh
does not point to/bin/bash
(and on some of which/bin/bash
may not even exist) are:sh
todash
by default;initramfs
. It uses the ash shell implementation.pdksh
, a descendant of the KornShell. FreeBSD'ssh
is a descendant of the original Unix Bourne shell. Solaris has its ownsh
which for a long time was not POSIX-compliant; a free implementation is available from the Heirloom project.How can you find out what
/bin/sh
points to on your system?The complication is that
/bin/sh
could be a symbolic link or a hard link. If it's a symbolic link, a portable way to resolve it is:If it's a hard link, try
In fact, the
-L
flag covers both symlinks and hardlinks,but the disadvantage of this method is that it is not portable —
POSIX does not require
find
to support the-samefile
option, although both GNU find and FreeBSD find support it.Shebang line
Ultimately, it's up to you to decide which one to use, by writing the «shebang» line as the very first line of the script.
E.g.
will use
sh
(and whatever that happens to point to),will use
/bin/bash
if it's available (and fail with an error message if it's not). Of course, you can also specify another implementation, e.g.Which one to use
For my own scripts, I prefer
sh
for the following reasons:bash
, they are required to havesh
There are advantages to using
bash
as well. Its features make programming more convenient and similar to programming in other modern programming languages. These include things like scoped local variables and arrays. Plainsh
is a very minimalistic programming language.sh
:http://man.cx/shBash: http://man.cx/bash
TL;DR:Bash 是一个
sh
的超集,具有更优雅的语法和更多功能。几乎在所有情况下使用 Bash shebang 行都是安全的,因为它在现代平台。注意:在某些环境中,
sh
是 Bash。检查sh --version
。sh
: http://man.cx/shBash: http://man.cx/bash
TL;DR: Bash is a superset of
sh
with a more elegant syntax and more functionality. It is safe to use a Bash shebang line in almost all cases as it's quite ubiquitous on modern platforms.NB: in some environments,
sh
is Bash. Checksh --version
.对于尝试使用
sh
并惊讶于它的行为与bash
不同的人来说,这个问题经常被提名为规范问题。以下是常见误解和陷阱的简要概述。首先,您应该了解会发生什么。
sh scriptname
运行脚本,或者使用scriptname
运行脚本并在 shebang 行,您应该期望 POSIXsh
行为。bash scriptname
运行脚本,或者使用scriptname
运行脚本并在其中包含#!/bin/bash
(或本地等效项)在 shebang 行中,您应该预料到 Bash 行为。拥有正确的 shebang 并通过仅键入脚本名称(可能带有相对路径或完整路径)来运行脚本通常是首选解决方案。除了正确的 shebang 之外,这还需要脚本文件具有执行权限(
chmod a+x scriptname
)。那么,它们实际上有何不同?
Bash 的目标是向后兼容 Bourne shell 和 POSIX,但还有许多附加功能。 Bash 参考手册有一个 部分它试图列举差异,但一些常见的混淆来源包括
[[
在sh
中不可用(只有[
这是更笨重和有限)。另请参阅 Bash 中的单方括号和双方括号有什么区别?sh
没有数组。local
、source
、function
、shopt
、let
、< code>declare、pushd
、popd
和select
无法移植到sh
。 (一些sh
实现支持例如local
。)for((i=0;i<=3 ;i++))
循环、+=
增量赋值等。$'string\nwith\tC\aescapes'
功能暂定为 接受 POSIX (意味着它现在可以在 Bash 中使用,但尚不被sh 支持code> 仅遵守当前 POSIX 规范的系统,并且可能在未来一段时间内不会)。
<<<'here strings'
。*.{png,jpg}
和{0..12}
大括号扩展。**
(globstar
) 和用于使用不同的 更通用的通配符语法。这是在 POSIX 中,但是某些 POSIX 之前的~
指的是$HOME
仅在 Bash 中(更一般的是~username
到username
的主目录)。/bin/sh
实现中可能会丢失。<(cmd)
和>(cmd)
进行进程替换。<>
重定向的协进程。&|
代表2>&1 |
和&>
代表> ; ... 2>&1
${substring:1:2}
、${variable/pattern/replacement}
、case Bash 扩展了 shell算术$[expression]
语法,但应使用 POSIX 算术$((expression))
语法替换。 (不过,一些旧的 POSIX 之前的sh
实现可能不支持这一点。)type -a
、printf -v 、 cd -P 和常年使用的 echo -e 。
$RANDOM
、$_
、$SECONDS
、$PIPESTATUS[@]
和$ FUNCNAME
是 Bash 扩展。请参阅参考手册。/dev/stdin
、/dev/fd/
、/dev/tcp/
等语法差异,export variable=value
(export variable
应与变量赋值分开)和[ "x" == "y" ]
不可移植([ ... ]
中的可移植字符串比较使用单个等号)。请记住,这是一个简短的列表。请参阅参考手册了解完整内容,并http://mywiki.wooledge.org/Bashism 了解更多信息许多好的解决方法;和/或尝试 http://shellcheck.net/ 它会针对许多仅限 Bash 的功能发出警告。
一个常见的错误是使用
#!/bin/bash
shebang 行,但仍然使用sh scriptname
来实际运行脚本。这基本上会禁用任何仅 Bash 的功能,因此您会遇到语法错误,例如尝试使用数组时。 (shebang 行在语法上是一个注释,因此在这种情况下它会被忽略。)不幸的是,当您尝试使用这些构造时,当 Bash 作为
sh
调用时,它不会发出警告。它也不会完全禁用所有仅限 Bash 的功能,因此通过将 Bash 调用为sh
来运行 Bash 并不是检查脚本是否可以正确移植到的好方法。ash
/dash
/POSIXsh
或类似 传家宝sh
。如果您想检查严格的 POSIX 合规性,请尝试
posh
在其指定的 POSIX 模式下
(然而,这似乎没有正确记录)。
顺便说一句, POSIX 标准化工作旨在指定各种 U*x- 的行为类似平台行为,包括 shell (
sh)。
然而,这是一个不断发展的文档,因此,某些实现遵循 POSIX 规范的早期版本;此外,还有一些遗留实现甚至没有尝试遵守 POSIX。
最初的 Bourne shell 有一些怪癖,后来由 POSIX 规范纠正,该规范很大程度上基于
ksh88
。 (许多 Bash 扩展也是ksh
的创新。)This question has frequently been nominated as a canonical for people who try to use
sh
and are surprised that it's not behaving the same asbash
. Here's a quick rundown of common misunderstandings and pitfalls.First off, you should understand what to expect.
sh scriptname
, or run it withscriptname
and have#!/bin/sh
in the shebang line, you should expect POSIXsh
behavior.bash scriptname
, or run it withscriptname
and have#!/bin/bash
(or the local equivalent) in the shebang line, you should expect Bash behavior.Having a correct shebang and running the script by typing just the script name (possibly with a relative or full path) is generally the preferred solution. In addition to a correct shebang, this requires the script file to have execute permission (
chmod a+x scriptname
).So, how do they actually differ?
Bash aims to be backwards-compatible with the Bourne shell and POSIX, but has many additional features. The Bash Reference manual has a section which attempts to enumerate the differences but some common sources of confusion include
[[
is not available insh
(only[
which is more clunky and limited). See also What is the difference between single and double square brackets in Bash?sh
does not have arrays.local
,source
,function
,shopt
,let
,declare
,pushd
,popd
, andselect
are not portable tosh
. (Somesh
implementations support e.g.local
.)for((i=0;i<=3;i++))
loop,+=
increment assignment, etc. The$'string\nwith\tC\aescapes'
feature is tentatively accepted for POSIX (meaning it works in Bash now, but will not yet be supported bysh
on systems which only adhere to the current POSIX specification, and likely will not for some time to come).<<<'here strings'
.*.{png,jpg}
and{0..12}
brace expansion.**
(globstar
) for recursing subdirectories, andextglob
for using a different, more versatile wildcard syntax.This is in POSIX, but may be missing from some pre-POSIX~
refers to$HOME
only in Bash (and more generally~username
to the home directory ofusername
)./bin/sh
implementations.<(cmd)
and>(cmd)
.<>
redirection.&|
for2>&1 |
and&>
for> ... 2>&1
${substring:1:2}
,${variable/pattern/replacement}
, case conversion, etc.$[expression]
syntax which however should be replaced with POSIX arithmetic$((expression))
syntax. (Some legacy pre-POSIXsh
implementations may not support that, though.)type -a
,printf -v
,cd -P
, and the perennialecho -e
.$RANDOM
,$_
,$SECONDS
,$PIPESTATUS[@]
and$FUNCNAME
are Bash extensions. See the Reference Manual./dev/stdin
,/dev/fd/<number>
,/dev/tcp/<network address>
, etcexport variable=value
(export variable
should be separate from variable assignment) and[ "x" == "y" ]
which are not portable (portable string comparison in[ ... ]
uses a single equals sign).Remember, this is an abridged listing. Refer to the reference manual for the full scoop, and http://mywiki.wooledge.org/Bashism for many good workarounds; and/or try http://shellcheck.net/ which warns for many Bash-only features.
A common error is to have a
#!/bin/bash
shebang line, but then nevertheless usingsh scriptname
to actually run the script. This basically disables any Bash-only functionality, so you get syntax errors e.g. for trying to use arrays. (The shebang line is syntactically a comment, so it is simply ignored in this scenario.)Unfortunately, Bash will not warn when you try to use these constructs when it is invoked as
sh
. It doesn't completely disable all Bash-only functionality, either, so running Bash by invoking it assh
is not a good way to check if your script is properly portable toash
/dash
/POSIXsh
or variants like Heirloomsh
.If you want to check for strict POSIX compliance, try
posh
in its designated POSIX mode
(which however does not seem to be properly documented).
As an aside, the POSIX standardization effort is intended to specify the behavior of various U*x-like platform behaviors, including the shell (
sh
).However, this is an evolving document, and so, some implementations adhere to an earlier version of the POSIX specification; furthermore, there are some legacy implementations which didn't even try to adhere to POSIX.
The original Bourne shell had some quirks which were later straightened out by the POSIX spec, which in large parts is based on
ksh88
. (Many of the Bash extensions are also innovations fromksh
.)Shell 是用户和操作系统之间用于访问操作系统服务的接口。它可以是 GUI 或 CLI(命令行界面)。
sh (Bourne shell) 是一个 shell 命令行解释器,适用于 Unix/类 Unix 操作系统。它提供了一些内置命令。在脚本语言中,我们将解释器表示为
#!/bin/sh
。它是受到 bash(免费/开放)、kash(非免费)等其他 shell 最广泛支持的一种。Bash (Bourne again shell) 是 Bourne shell 的替代品。 Bash 是 sh 的超集。 Bash 支持 sh。 POSIX 是一组定义 POSIX 兼容系统应如何工作的标准。 Bash 实际上并不是一个 POSIX 兼容的 shell。在脚本语言中,我们将解释器表示为
#!/bin/bash
。类比:
Shell is an interface between a user and OS to access to an operating system's services. It can be either GUI or CLI (Command Line interface).
sh (Bourne shell) is a shell command-line interpreter, for Unix/Unix-like operating systems. It provides some built-in commands. In scripting language we denote interpreter as
#!/bin/sh
. It was one most widely supported by other shells like bash (free/open), kash (not free).Bash (Bourne again shell) is a shell replacement for the Bourne shell. Bash is superset of sh. Bash supports sh. POSIX is a set of standards defining how POSIX-compliant systems should work. Bash is not actually a POSIX compliant shell. In a scripting language we denote the interpreter as
#!/bin/bash
.Analogy:
帖子来自 UNIX.COM
Shell 功能
下表列出了我认为可以实现的大部分功能您选择一个外壳而不是另一个外壳。它并不是一个明确的列表,也不包括每个可能的 shell 的每个可能的功能。仅当某个功能位于操作系统附带的版本中,或者可以直接从标准发行版编译时,该功能才被视为位于 shell 中。特别是下面指定的 C shell 在 SUNOS 4.* 上可用,相当多的供应商现在提供 tcsh 或他们自己的增强型 C shell(他们并不总是表明他们正在提供 tcsh。
代码:
上表的关键。
Y 功能可以使用此 shell 来完成
N 功能不存在于 shell 中
F 功能只能通过使用 shell 函数来完成 。
机制。
L readline 库必须链接到 shell 中才能启用
此功能。
上表注释
几乎标准。
shell 版本,它正在逐渐进入
标准分布。
不完整。
执行此操作。
AT&T 版本的全部功能。
Post from UNIX.COM
Shell features
This table below lists most features that I think would make you choose one shell over another. It is not intended to be a definitive list and does not include every single possible feature for every single possible shell. A feature is only considered to be in a shell if in the version that comes with the operating system, or if it is available as compiled directly from the standard distribution. In particular the C shell specified below is that available on SUNOS 4.*, a considerable number of vendors now ship either tcsh or their own enhanced C shell instead (they don't always make it obvious that they are shipping tcsh.
Code:
Key to the table above.
Y Feature can be done using this shell.
N Feature is not present in the shell.
F Feature can only be done by using the shells function
mechanism.
L The readline library must be linked into the shell to enable
this Feature.
Notes to the table above
almost standard.
versions of the shell, it is gradually making its way into
standard distribution.
incomplete.
perform this.
the full functionality of the AT&T version.
TERMINAL
SHELL
SH 与。 BASH
SH
BASH
参考材料:
SHELL
gnu.org:
BASH gnu.org:
TERMINAL
SHELL
SH Vs. BASH
SH
BASH
REFERENCE MATERIAL:
SHELL
gnu.org:
BASH gnu.org:
其他答案通常指出了 Bash 和 POSIX shell 标准之间的区别。然而,当编写可移植的 shell 脚本并使用 Bash 语法时,典型的 bashism 和相应的纯 POSIX 解决方案的列表非常方便。当 Ubuntu 从 Bash 切换到 Dash 作为默认系统 shell 时,已经编译了这样的列表,可以在这里找到:
https://wiki.ubuntu.com/DashAsBinSh
此外,还有一个很棒的工具,名为 checkbashisms 用于检查脚本中的 bashism,当您想确保脚本可移植时会很方便。
Other answers generally pointed out the difference between Bash and a POSIX shell standard. However, when writing portable shell scripts and being used to Bash syntax, a list of typical bashisms and corresponding pure POSIX solutions is very handy. Such list has been compiled when Ubuntu switched from Bash to Dash as default system shell and can be found here:
https://wiki.ubuntu.com/DashAsBinSh
Moreover, there is a great tool called checkbashisms that checks for bashisms in your script and comes handy when you want to make sure that your script is portable.
它们几乎相同,但
bash
具有更多功能 -sh
(或多或少)是bash
的较旧子集>。sh
通常表示原始的Bourne shell
,它早于bash
(Bourne *again* shell
),并且被创建1977 年。但是,实际上,最好将其视为符合 1992 年 POSIX 标准的高度交叉兼容的 shell。以
#!/bin/sh
或使用sh
shell 通常这样做是为了向后兼容。任何 unix/linux 操作系统都会有一个sh
shell。在 Ubuntu 上,sh
经常调用dash
,在 MacOS 上,它是bash
的特殊 POSIX 版本。由于符合标准的行为、速度或向后兼容性,这些 shell 可能是首选。bash
比原来的sh
更新,添加了更多功能,并力求向后兼容sh
。sh
程序通常在bash
中运行得很好。bash
几乎在所有 Linux/unix 机器上都可用,并且通常默认使用 - 值得注意的例外是,从 Catalina (10.15) 开始,MacOS 默认使用zsh
。默认情况下,FreeBSD 没有安装bash
。They're nearly identical but
bash
has more features –sh
is (more or less) an older subset ofbash
.sh
often means the originalBourne shell
, which predatesbash
(Bourne *again* shell
), and was created in 1977. But, in practice, it may be better to think of it as a highly-cross-compatible shell compliant with the POSIX standard from 1992.Scripts that start with
#!/bin/sh
or use thesh
shell usually do so for backwards compatibility. Any unix/linux OS will have ansh
shell. On Ubuntush
often invokesdash
and on MacOS it's a special POSIX version ofbash
. These shells may be preferred for standard-compliant behavior, speed or backwards compatibility.bash
is newer than the originalsh
, adds more features, and seeks to be backwards compatible withsh
.sh
programs will usually run just fine inbash
.bash
is available on nearly all linux/unix machines and usually used by default – with the notable exception of MacOS defaulting tozsh
as of Catalina (10.15). FreeBSD, by default, does not come withbash
installed./bin/sh
可能会也可能不会调用与/bin/bash
相同的程序。sh
支持至少功能POSIX 要求(假设正确实现)。它也可能支持扩展。bash
,即“Bourne Again Shell”,实现了 sh 以及特定于 bash 的扩展所需的功能。完整的扩展集太长,无法在此描述,并且随着新版本的不同而有所不同。 bash 手册中记录了这些差异。输入info bash
并阅读“Bash 功能”部分(当前版本中的第 6 部分),或阅读 当前在线文档。/bin/sh
may or may not invoke the same program as/bin/bash
.sh
supports at least the features required by POSIX (assuming a correct implementation). It may support extensions as well.bash
, the "Bourne Again Shell", implements the features required for sh plus bash-specific extensions. The full set of extensions is too long to describe here, and it varies with new releases. The differences are documented in the bash manual. Typeinfo bash
and read the "Bash Features" section (section 6 in the current version), or read the current documentation online.以最简单的方式解释差异:
有了基本的了解后,其他答案就会更容易理解。
Shell - “Shell”是一个程序,它促进用户和操作系统(内核)之间的交互。有许多可用的 shell 实现,例如 sh、Bash、C shell, Z shell等。
使用任何一个shell程序,我们将能够执行该shell程序支持的命令。
Bash - 它源自Bourne-again Shell。使用这个程序,我们将能够执行 shell 指定的所有命令。此外,我们将能够执行一些专门添加到该程序中的命令。 Bash 向后兼容 sh。
Sh - 它源自 Bourne Shell。 “sh”支持 shell 中指定的所有命令。这意味着,使用这个程序,我们将能够执行Shell指定的所有命令。
有关详细信息,请参阅:
The differences explained in the easiest way possible:
After having a basic understanding, the other answers will be easier to understand.
Shell - "Shell" is a program, which facilitates the interaction between the user and the operating system (kernel). There are many shell implementations available, like sh, Bash, C shell, Z shell, etc.
Using any of the shell programs, we will be able to execute commands that are supported by that shell program.
Bash - It derived from Bourne-again Shell. Using this program, we will be able to execute all the commands specified by the shell. Also, we will be able to execute some commands that are specifically added to this program. Bash has backward compatibility with sh.
Sh - It derived from Bourne Shell. "sh" supports all the commands specified in the shell. It means, using this program, we will be able to execute all the commands specified by Shell.
For more information, see:
Linux 操作系统提供不同类型的 shell。尽管 shell 有许多共同的命令,但每种类型都有独特的功能。
让我们研究一下最常用的不同类型的 shell。
Sh shell:
Sh shell 也称为 Bourne shell。 Sh shell 是 AT&T 贝尔实验室的 Stephen Bourne 于 1977 年为 Unix 计算机开发的第一个 shell。它包括许多脚本工具。
Bash shell:
Bash shell 代表 Bourne Again Shell。 Bash shell 是大多数 Linux 发行版中的默认 shell,并替代 Sh shell(Sh shell 也将在 Bash shell 中运行)。 Bash shell 无需修改即可执行绝大多数 Sh shell 脚本,并且还提供命令行编辑功能。
The Linux operating system offers different types of shell. Though shells have many commands in common, each type has unique features.
Let’s study different kind of mostly used shells.
Sh shell:
Sh shell is also known as Bourne shell. Sh shell is the first shell developed for Unix computers by Stephen Bourne at AT&T's Bell Labs in 1977. It includes many scripting tools.
Bash shell:
Bash shell stands for Bourne Again Shell. Bash shell is the default shell in most Linux distributions and substitute for the Sh shell (the Sh shell will also run in the Bash shell). The Bash shell can execute the vast majority of Sh shell scripts without modification and provide commands line editing feature also.