提问人:Weiwei Yang 提问时间:4/20/2011 最后编辑:Peter MortensenWeiwei Yang 更新时间:9/17/2023 访问量:786431
sh 和 Bash 之间的区别
Difference between sh and Bash
问:
在编写 shell 程序时,我们经常使用 和 。我通常使用 ,但我不知道它们之间有什么区别。/bin/sh
/bin/bash
bash
Bash 和 ?sh
在 Bash 和 中编程时,我们需要注意什么?sh
答:
sh
: http://man.cx/sh
Bash: http://man.cx/bash
TL的;DR:Bash 是 的超集,具有更优雅的语法和更多的功能。在几乎所有情况下使用 Bash shebang 系列都是安全的,因为它在现代平台上无处不在。sh
注意:在某些环境中,是 Bash。检查。sh
sh --version
评论
sh
#!/usr/bin/env sh
sh
bash
)
什么是sh?
sh
(或 Shell 命令语言)是 POSIX 标准描述的一种编程语言。它有许多实现(、Dash 等)。Bash 也可以被视为 (见下文) 的实现。ksh88
sh
因为是规范,而不是实现,是大多数 POSIX 系统上实际实现的符号链接(或硬链接)。sh
/bin/sh
什么是 Bash?
Bash 最初是一个兼容的实现(尽管它比 POSIX 标准早了几年),但随着时间的推移,它已经获得了许多扩展。其中许多扩展可能会更改有效 POSIX shell 脚本的行为,因此 Bash 本身不是有效的 POSIX shell。相反,它是 POSIX shell 语言的一种方言。sh
Bash 支持开关,这使得它更符合 POSIX。如果作为 .--posix
sh
sh = 重击?
在很长一段时间里,用于大多数 GNU/Linux 系统。因此,忽略两者之间的差异几乎是安全的。但这种情况最近开始改变。/bin/sh
/bin/bash
一些不指向(其中一些甚至可能不存在)的系统的流行示例是:/bin/sh
/bin/bash
/bin/bash
- 现代 Debian 和 Ubuntu 系统,默认符号链接到;
sh
dash
- Busybox,通常在 Linux 系统启动期间作为 的一部分运行。它使用 ash shell 实现。
initramfs
- BSD 系统,以及一般任何非 Linux 系统。OpenBSD 使用 ,这是 KornShell 的后代。FreeBSD 是原始 Unix Bourne shell 的后代。Solaris 有自己的,在很长一段时间内都不符合 POSIX;Heirloom 项目提供免费实施。
pdksh
sh
sh
你怎么能找出你的系统上有什么点?/bin/sh
复杂的是,这可能是一个符号链接,也可能是一个硬链接。如果它是符号链接,则解决它的可移植方法是:/bin/sh
% file -h /bin/sh
/bin/sh: symbolic link to bash
如果是硬链接,请尝试
% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
事实上,该标志涵盖了符号链接和硬链接,
但这种方法的缺点是它不便携——
POSIX 不需要支持该选项,尽管 GNU find 和 FreeBSD find 都支持它。-L
find
-samefile
社邦线
最终,由您决定使用哪一个,将“shebang”台词写为脚本的第一行。
例如
#!/bin/sh
将使用(以及碰巧指向的任何内容),sh
#!/bin/bash
如果可用,则使用(如果不可用,则失败并显示错误消息)。当然,您也可以指定其他实现,例如/bin/bash
#!/bin/dash
使用哪一个
对于我自己的脚本,我更喜欢以下原因:sh
- 它是标准化的
- 它更简单,更容易学习
- 它是跨 POSIX 系统的可移植的——即使它们碰巧没有 ,它们也必须具有
bash
sh
使用也有好处。它的功能使编程更加方便,类似于其他现代编程语言的编程。其中包括作用域局部变量和数组等内容。Plain 是一种非常简约的编程语言。bash
sh
评论
bash
%
$
%
#
%
#
%
Shell 是用户和操作系统之间的接口,用于访问操作系统的服务。它可以是 GUI 或 CLI(命令行界面)。
sh (Bourne shell) 是一个 shell 命令行解释器,用于类 Unix/Unix 操作系统。它提供了一些内置命令。在脚本语言中,我们将解释器表示为 。它是其他 shell(自由/开放)、kash(非自由)等最广泛支持的一种。#!/bin/sh
Bash (Bourne again shell) 是 Bourne shell 的替代品。Bash 是 sh 的超集。POSIX是一套标准,定义了符合POSIX标准的系统应该如何工作。Bash 实际上并不是一个符合 POSIX 的 shell。在脚本语言中,我们将解释器表示为 。#!/bin/bash
类比:
- Shell 就像一个接口、规范或 API。
- sh 是一个实现 Shell 接口的类。
- Bash 是 sh 的子类。
评论
sh
sh
ksh
ksh
/bin/sh
可以也可能不会调用与 相同的程序。/bin/bash
sh
至少支持 POSIX 所需的功能(假设实现正确)。它也可能支持扩展。
bash
,“Bourne Again Shell”,实现了 sh 和 bash 特定扩展所需的功能。完整的扩展集太长,无法在这里描述,并且会因新版本而异。这些差异记录在 bash 手册中。键入并阅读“Bash 功能”部分(当前版本中的第 6 节),或在线阅读当前文档。info bash
评论
sh
只给你一个 POSIX shell,如果你在当前的 shell 中设置了正确的设置。没有定义的 PATH 名称为您提供 POSIX shell。PATH
sh
其他答案通常指出了 Bash 和 POSIX shell 标准之间的区别。但是,在编写可移植的 shell 脚本并习惯于 Bash 语法时,典型的 bashisms 列表和相应的纯 POSIX 解决方案非常方便。当 Ubuntu 从 Bash 切换到 Dash 作为默认系统 shell 时,这样的列表已经编译,可以在这里找到: https://wiki.ubuntu.com/DashAsBinSh
此外,还有一个很棒的工具叫做 checkbashisms,它可以检查脚本中的 bashisms,当您想确保脚本是可移植的时,它会派上用场。
来自 UNIX.COM 的帖子
外壳功能
下表列出了我认为会让您选择一个 shell 而不是另一个 shell 的大多数功能。它不打算成为一个明确的列表,也不包括每个可能的 shell 的每个可能功能。只有当某个功能在操作系统附带的版本中,或者如果它直接从标准发行版编译时可用,则该功能才被视为位于 shell 中。特别是下面指定的 C shell 是 SUNOS 4.* 上可用的 C,相当多的供应商现在要么发布 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 中才能启用 此功能。
上表注释
- 此功能不在原始版本中,但后来变成了 几乎是标准的。
- 此功能相当新,因此通常在许多功能上都找不到 版本的 shell,它正在逐渐进入 标准分布。
- 许多人认为这个 shell 的 Vi 模拟是 不完全的。
- 此功能不是标准的,但存在非官方补丁 执行此操作。
- 一个名为“pdksh”的版本是免费提供的,但没有 AT&T版本的全部功能。
- 这可以通过 shells 可编程完成机制来完成。
- 仅通过 ENV 环境变量指定文件。
评论
终端
- 设置窗口的程序
- xterm、rxvt、konsole、kvt、gnome-terminal、nxterm 和 eterm。
壳
- 是在终端中运行的程序
- Shell 既是一种命令解释器,也是一种编程语言
- Shell 只是一个执行命令的宏处理器。
- 宏处理器意味着扩展文本和符号以创建更大表达式的功能。
SH 与 BASH
上海
- (谢尔)
- 是特定的 shell
- 命令解释器和编程语言
- BASH 的前身
巴什
- (伯恩-再次谢尔)
- 是特定的 shell
- 命令解释器和编程语言
- 具有 sh 功能等
- SH的继任者
- BASH 是默认的 SHELL
参考资料:
壳牌 gnu.org:
从根本上说,shell 只是一个执行 命令。术语宏处理器是指文本和 符号被扩展以创建更大的表达式。
Unix shell 既是命令解释器,又是编程语言。作为命令解释器,shell 为 丰富的 GNU 实用程序集。编程语言功能允许 这些实用程序要组合。包含命令的文件可以是 创建,并成为命令本身。这些新命令具有 与 /bin 等目录中的系统命令状态相同,允许 用户或组建立自定义环境以自动执行其 常见任务。
Shell 可以以交互方式或非交互方式使用。在互动中 模式,它们接受从键盘键入的输入。执行时 以非交互方式,shell 执行从文件中读取的命令。
shell 允许同步执行 GNU 命令和 异步。shell 等待同步命令完成 在接受更多意见之前;异步命令继续执行 与 shell 并行,同时读取并执行其他 命令。重定向结构允许对 这些命令的输入和输出。此外,外壳允许 控制命令环境的内容。
Shell 还提供一小组内置命令(内置) 实现无法或不方便通过以下方式获得的功能 单独的实用程序。例如,cd、break、continue 和 exec cannot 在 shell 外部实现,因为它们直接操作 外壳本身。history、getopts、kill 或 pwd 内置,其中 其他的,可以在单独的实用程序中实现,但它们更多 方便用作内置命令。所有 shell 内置函数都是 在后续各节中介绍。
虽然执行命令是必不可少的,但大部分权力(和 shell的复杂性是由于它们的嵌入式编程语言。像任何高级语言一样,shell 提供变量、流程 控件构造、引用和函数。
Shell 提供专门用于交互式使用的功能,而不是 而不是增强编程语言。这些互动功能 包括作业控制、命令行编辑、命令历史记录和 别名。本手册中介绍了这些功能中的每一个。
BASH gnu.org:
Bash 是 GNU 的 shell 或命令语言解释器 操作系统。这个名字是“Bourne-Again SHell”的首字母缩写, 斯蒂芬·伯恩(Stephen Bourne)的双关语,斯蒂芬·伯恩(Stephen Bourne)是 当前的 Unix shell sh,出现在第七版贝尔实验室 Unix的研究版。
Bash 在很大程度上与 sh 兼容,并包含有用的功能 来自 Korn shell ksh 和 C shell csh。它旨在成为一个 IEEE POSIX Shell 和 Tools 部分的一致性实现 IEEE POSIX规范(IEEE标准1003.1)。它提供 与 SH 相比,在交互和编程方面都进行了功能改进 用。
虽然 GNU 操作系统提供了其他 shell,包括 csh 的版本,Bash 是默认的 shell。像其他 GNU 软件一样, Bash 非常便携。它目前几乎运行在每个版本的 Unix 和其他一些操作系统 - 独立支持的端口 适用于 MS-DOS、OS/2 和 Windows 平台。
这个问题经常被提名为那些试图使用并惊讶于它的行为与 .以下是常见误解和陷阱的简要概述。sh
bash
首先,您应该了解会发生什么。
- 如果使用 ,或者在 shebang 行中使用 和 have 运行脚本,则应该会出现 POSIX 行为。
sh scriptname
scriptname
#!/bin/sh
sh
- 如果使用 ,或在 shebang 行中使用 和 have(或本地等效项)运行脚本,则应该会出现 Bash 行为。
bash scriptname
scriptname
#!/bin/bash
通常,通过键入脚本名称(可能具有相对路径或完整路径)来获得正确的 shebang 并运行脚本是首选解决方案。除了正确的 shebang 之外,这还要求脚本文件具有执行权限 ()。chmod a+x scriptname
那么,它们到底有什么不同呢?
Bash 旨在向后兼容 Bourne shell 和 POSIX,但具有许多附加功能。Bash 参考手册中有一个部分试图列举差异,但一些常见的混淆来源包括
[[
在(只有更笨拙和有限)中不可用。参见 Bash 中单方括号和双方括号的区别sh
[
sh
没有数组。- 一些 Bash 关键字(如 、 、 、 、 和 )不能移植到 。(一些实现支持例如。
local
source
function
shopt
let
declare
select
sh
sh
local
- Bash 有许多 C 风格的语法扩展,如三参数循环、增量赋值等。该功能暂时被 POSIX 接受(这意味着它现在可以在 Bash 中工作,但尚未被仅遵守当前 POSIX 规范的系统支持,并且可能在未来一段时间内不会支持)。
for((i=0;i<=3;i++))
+=
$'string\nwith\tC\aescapes'
sh
- Bash 支持 。
<<<'here strings'
- Bash 具有和大括号扩展。
*.{png,jpg}
{0..12}
- Bash 扩展了 () 等通配工具,用于递归子目录,以及使用不同的、更通用的通配符语法。
**
globstar
extglob
这在 POSIX 中,但在某些 POSIX 之前的实现中可能缺失。~
仅在 Bash 中指$HOME
(更一般地说,~username
是指username
的主目录)。/bin/sh
- Bash 具有 和 的进程替换。
<(cmd)
>(cmd)
- Bash 具有 Csh 样式的便捷重定向别名,例如 for 和 for
&|
2>&1 |
&>
> ... 2>&1
- Bash 支持具有重定向功能的协同进程。
<>
- Bash 具有丰富的扩展非标准参数扩展集,例如 、 、 大小写转换等。
${substring:1:2}
${variable/pattern/replacement}
- Bash 大大扩展了 shell 算术的功能(尽管仍然没有浮点支持)。有一个过时的遗留语法,但是应该用 POSIX 算术语法替换。(不过,一些传统的 POSIX 之前的实现可能不支持这一点。
$[expression]
$((expression))
sh
- 一些内置命令具有不可移植的选项,例如 、 和 perennial 。
type -a
printf -v
echo -e
- 魔术变量(如 、 、 和 )是 Bash 扩展。请参阅参考手册。
$RANDOM
$_
$SECONDS
$PIPESTATUS[@]
$FUNCNAME
- Bash 将一些系统设施公开为文件句柄,如 、 、 等
/dev/stdin
/dev/fd/<number>
/dev/tcp/<network address>
- 语法差异,如 export
which 是不可移植的(variable=value
和可移植字符串比较使用单个等号)。export
变量应与变量赋值分开,并且[ "x" == "y" ]
[ ... ]
- 许多仅限 Bash 的扩展,用于启用或禁用可选行为并公开 shell 的内部状态。
- 许多用于交互使用的便利功能,但不会影响脚本行为。
请记住,这是一个删节列表。有关完整的独家新闻,请参阅参考手册,并 http://mywiki.wooledge.org/Bashism 了解许多好的解决方法;和/或尝试 http://shellcheck.net/ 它会警告许多仅限 Bash 的功能。
一个常见的错误是有 shebang 行,但仍然用于实际运行脚本。这基本上禁用了任何仅限 Bash 的功能,因此您会遇到语法错误,例如尝试使用数组。(shebang 行在语法上是一个注释,因此在此场景中被简单地忽略。#!/bin/bash
sh scriptname
不幸的是,当您尝试使用这些构造时,Bash 不会发出警告,当它被调用为 .它也不会完全禁用所有仅限 Bash 的功能,因此通过调用它来运行 Bash 并不是检查您的脚本是否正确移植到 ash
/dash
/POSIX sh 或 Heirloom sh
等变体的好方法。
如果您想检查严格的 POSIX 合规性,请尝试在其指定的 POSIX 模式下进行 posh
(然而,这似乎没有得到适当的记录)。sh
sh
顺便说一句,POSIX 标准化工作旨在指定各种类似 U*x 的平台行为的行为,包括 shell ()。
但是,这是一个不断发展的文档,因此,某些实现遵循早期版本的 POSIX 规范;此外,还有一些遗留的实现甚至没有尝试遵守 POSIX。
最初的 Bourne shell 有一些怪癖,后来被 POSIX 规范理顺了,该规范在很大程度上是基于 .(许多 Bash 扩展也是 的创新。sh
ksh88
ksh
评论
export variable=value
busybox sh
Linux 操作系统提供不同类型的 shell。尽管 shell 有许多共同的命令,但每种类型都有独特的功能。 让我们研究一下不同种类的常用贝壳。
Sh外壳:
Sh shell 也称为 Bourne shell。Sh shell 是 Stephen Bourne 于 1977 年在 AT&T 贝尔实验室为 Unix 计算机开发的第一个 shell。它包括许多脚本工具。
Bash shell:
Bash shell 代表 Bourne Again Shell。Bash shell 是大多数 Linux 发行版中的默认 shell,可以替代 Sh shell(Sh shell 也将在 Bash shell 中运行)。Bash shell 无需修改即可执行绝大多数 Sh shell 脚本,并提供命令行编辑功能。
评论
它们几乎相同,但 bash
具有更多功能——(或多或少)是 .sh
bash
sh
通常表示早于 () 的原文,创建于 1977 年。但是,在实践中,最好将其视为符合 1992 年 POSIX 标准的高度交叉兼容的 shell。Bourne shell
bash
Bourne *again* shell
以 shell 开头或使用 shell 的脚本通常这样做是为了向后兼容。任何 unix/linux 操作系统都会有一个 shell。在 Ubuntu 上经常调用,在 MacOS 上,它是 .这些 shell 可能是符合标准的行为、速度或向后兼容性的首选。#!/bin/sh
sh
sh
sh
dash
bash
bash
比原版更新,添加更多功能,并力求向后兼容。 程序通常可以在 中运行良好。 在几乎所有的 linux/unix 机器上都可用,并且通常默认使用 - 除了 MacOS 默认为 Catalina (10.15) 之外。默认情况下,FreeBSD 没有附带安装。sh
sh
sh
bash
bash
zsh
bash
评论
sh
远远早于POSIX。如今,您会希望您找到的任何产品至少与 POSIX 兼容;但在遗留系统上,这绝不是给定的。POSIX的稳定性远远超过外壳;事实上,您可能会争辩说操作系统调用和库函数的标准化更为重要。sh
sh
程序在实践中应该在 Bash 中运行良好,而不仅仅是“理论上”。显然存在一些极端情况,例如当脚本使用一个变量时,该变量的名称由 Bash 保留,但不由其他 shell 保留。
以最简单的方式解释差异:
有了基本的了解后,其他答案会更容易理解。
Shell - “Shell”是一个程序,它促进了用户和操作系统(内核)之间的交互。有许多可用的 shell 实现,如 sh、Bash、C shell、Z shell 等。
使用任何 shell 程序,我们将能够执行该 shell 程序支持的命令。
Bash - 它源自 Bourne-a gain Shell。使用此程序,我们将能够执行 shell 指定的所有命令。此外,我们将能够执行一些专门添加到此程序的命令。Bash 向后兼容 sh。
Sh - 它源自 Bourne Shell。“sh” 支持 shell 中指定的所有命令。这意味着,使用此程序,我们将能够执行 Shell 指定的所有命令。
有关详细信息,请参阅:
评论