sh 和 Bash 的区别 [英] Difference between sh and Bash
问题描述
在编写shell程序时,我们经常使用/bin/sh
和/bin/bash
.我通常使用bash
,但我不知道它们之间有什么区别.
Bash 和 sh
的主要区别是什么?
使用 Bash 和 sh
编程时需要注意什么?
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 标准.如果作为 sh
调用,它还会尝试模仿 POSIX.
sh = bash?
很长一段时间以来,/bin/sh
在大多数 GNU/Linux 系统上都用于指向 /bin/bash
.结果,忽略两者之间的差异几乎变得安全.但最近这种情况开始发生变化.
/bin/sh
不指向 /bin/bash
的系统的一些流行示例(以及其中一些 /bin/bash
代码>甚至可能不存在)是:
- 现代 Debian 和 Ubuntu 系统,默认将
sh
符号链接到dash
; - Busybox,它通常在 Linux 系统启动时作为
的一部分运行initramfs
.它使用 ash shell 实现. - BSD 系统,以及通常的任何非 Linux 系统.OpenBSD 使用
pdksh
,KornShell.FreeBSD 的sh
是原始 Unix Bourne shell 的后代.Solaris 有自己的sh
不符合 POSIX;可以从 Heirloom 项目 获得免费实现.
您如何找出/bin/sh
在您的系统上指向的内容?
复杂的是 /bin/sh
可以是符号链接或硬链接.如果是符号链接,便携的解决方法是:
% file -h/bin/sh/bin/sh: bash 的符号链接
如果是硬链接,试试
% find -L/bin -samefile/bin/sh/bin/sh/bin/bash
事实上,-L
标志涵盖了符号链接和硬链接,但是这种方法的缺点是不便携——POSIX 不需要 find
来支持-samefile
选项,虽然都是 GNU find 和 FreeBSD find 支持它.>
社帮线
最终,由您决定使用哪个,将 «shebang» 行写为脚本的第一行.
例如
#!/bin/sh
将使用 sh
(以及任何指向的内容),
#!/bin/bash
将使用 /bin/bash
如果它可用(如果它不可用则失败并显示错误消息).当然,你也可以指定另一种实现,例如
#!/bin/dash
使用哪个
对于我自己的脚本,我更喜欢 sh
,原因如下:
- 标准化
- 它更简单,更容易学习
- 它可以跨 POSIX 系统移植——即使他们碰巧没有
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
?
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 of sh
(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 as sh
.
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:
- Modern Debian and Ubuntu systems, which symlink
sh
todash
by default; - Busybox, which is usually run during the Linux system boot time as part of
initramfs
. It uses the ash shell implementation. - BSD systems, and in general any non-Linux systems. OpenBSD uses
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:
% file -h /bin/sh
/bin/sh: symbolic link to bash
If it's a hard link, try
% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
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.
#!/bin/sh
will use sh
(and whatever that happens to point to),
#!/bin/bash
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.
#!/bin/dash
Which one to use
For my own scripts, I prefer sh
for the following reasons:
- it is standardized
- it is much simpler and easier to learn
- it is portable across POSIX systems — even if they happen not to have
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. Plain sh
is a very minimalistic programming language.
这篇关于sh 和 Bash 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!