#!/bin/sh 和 #!/bin/bash 有什么区别?

#!/bin/sh 和 #!/bin/bash 有什么区别?

如果我写,

#!/bin/bash
echo "foo"

或者

#!/bin/sh
echo "foo"

两者的结果相同。我见过一些以#!/bin/sh或开头的脚本#!/bin/bash。它们之间有什么区别吗?

答案1

bashsh是两种不同的 shell。基本上bashsh,具有更多功能和更好的语法。大多数命令的工作原理相同,但它们有所不同。

话虽如此,你应该意识到/bin/sh在大多数系统上将是一个符号链接,并且不会调用sh。在 Ubuntu 中,/bin/sh以前链接到bash,这是 Linux 发行版的典型行为,但现在已更改为链接到另一个名为 dash 的 shell。我会使用bash,因为这几乎是标准(或者至少根据我的经验,这是最常见的)。事实上,当 bash 脚本使用 时会出现问题,#!/bin/sh因为脚本制作者假设链接是 ,bash但其实不必如此。

更多信息:

答案2

在 Linux 和其他类 Unix 系统上,您可以选择多个 shell。

Shell 不仅负责提供显示提示的交互式环境,而且还负责解释您的命令(无论是键入的还是从脚本加载的)。

狂欢是 Linux 系统用户最常用的默认 shell。它是 Unix 历史上使用的其他 shell 的精神继承者。它的名字是狂欢是 Bourne-Again Shell 的缩写,是对其旨在取代的 Bourne shell 的致敬,尽管它还融合了 C Shell 和 Korn Shell 的功能。

现在,它从/bin/bash任何带有 bash 的系统运行,都可以从这里访问它。

不过,Shell 并非仅供用户交互使用。脚本 (shell 脚本) 也需要 shell 来解释它们。当你运行一个 shell 脚本时,你的系统需要启动一个 shell 进程来执行该脚本。

问题是,不同的 shell 之间存在细微的不一致性,当运行脚本时,这些可能是一个真正的问题。 狂欢具有许多脚本功能,这些功能是 bash 独有的,其他 shell 则没有。如果您总是使用 bash 来运行这些脚本,那么这没问题。其他 shell 可能会尝试模拟 bash,或者遵循 POSIX 标准,而 bash 对此标准支持得很好(尽管添加了自己的扩展)。

可以使用 shebang 在 shell 脚本的顶部指定应使用哪个 shell 运行。脚本可以在#!/bin/bash第一行指定,这意味着脚本应始终使用 bash 运行,而不是使用其他 shell。

/bin/sh是一个可执行文件,代表系统外壳。实际上,它通常被实现为指向系统 shell 的可执行文件的符号链接。系统 shell 是系统脚本应该使用的默认 shell。在 Linux 发行版中,很长一段时间内,这通常是指向狂欢,以至于 Linux 总是将 /bin/sh 链接到 bash 成为一种惯例。Bash 可以检测到何时启动了“sh”符号链接,并启用兼容模式,使其更像旧版 shell(主要是它旨在取代的 Bourne shell,但它也使其更兼容 POSIX)。然而,即使在这种兼容模式下,bash 也提供了许多在原始 Bourne shell 或 POSIX 标准中不可用的可选功能。

在过去的几年里,Debian(和 Ubuntu)决定将系统 shell 从 bash 切换到短跑- 打破了 Linux(当然,GNU)长期以来使用 bash 代替 /bin/sh 的传统。Dash 被视为更轻量、速度更快的 shell,有利于提高启动速度(以及其他需要大量 shell 脚本的操作,如软件包安装脚本)。

Dash 与 bash 的兼容性相当好,因为它们基于相同的 POSIX 标准。但是,它没有实现 bash 提供的许多非标准扩展。现有的脚本使用#!/bin/sh(系统 shell)作为其 shebang,但需要特定于 bash 的扩展。目前这被认为是应该修复的错误由 Debian 和 Ubuntu 提供,当指向 dash 时需要 /bin/sh 才能工作。

尽管 Ubuntu 的系统外壳指向 dash,你的登录外壳作为用户,现在仍然是 bash。也就是说,当您登录到 Linux 中任何地方的终端仿真器时,您的登录 shell 将是 bash。当 shell 以交互方式使用且用户熟悉 bash(并且可能在其主目录中有特定于 bash 的自定义设置)时,操作速度不是问题。

编写脚本时应使用的内容

如果您的脚本需要仅 bash 支持的功能,请使用#!/bin/bash

但是如果可能的话,最好确保您的脚本与 POSIX 兼容,并使用#!/bin/sh,它应该始终非常可靠地指向任何安装中的首选的与 POSIX 兼容的系统 shell。

答案3

除了前面的答案之外,即使/bin/sh是的符号链接/bin/bash#!/bin/sh也不完全等同于#!/bin/bash

来自bash(1) 手册页

“如果使用名称 sh 调用 bash,它会尝试尽可能地模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准。”

例如 bash 特定的语法:

 exec  > >(tee logfile.txt)

在以 开头的 shell 中会出现错误#!/bin/sh,即使有 sh->bash 符号链接也是如此。

答案4

GNU Bash:#!/bin/bash;POSIX shell:#!/bin/sh

相关内容