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

Rah*_*ara 359 bash scripts sh shebang

如果我写,

#!/bin/bash
echo "foo"
Run Code Online (Sandbox Code Playgroud)

或者

#!/bin/sh
echo "foo"
Run Code Online (Sandbox Code Playgroud)

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

rev*_*dj1 314

bash并且sh是两个不同的壳。基本上bashsh,具有更多功能和更好的语法。大多数命令的工作方式相同,但它们是不同的。

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

有关更多信息,请访问http://man.cx/shhttp://man.cx/bash

  • 你的第一段非常具有误导性。“sh”根本不是 shell,而是当前配置的 *system shell* 的符号链接,在 Linux 系统上通常是 bash 或 dash(最近版本的 Ubuntu 使用后者)。 (35认同)
  • `/bin/sh` 曾经是 1977 年称为 *bourne shell* 的 shell。bash 是一个 /bin/sh 兼容的 shell,*可以*用作符合 posix 的 bourne shell 替换。https://en.wikipedia.org/wiki/Bourne_shell (25认同)
  • *bash* 是事实上的标准(使用非常广泛),但它不是“标准”;Ubuntu 上的 *sh* 使用 *dash*,这是一个符合 Posix 的 shell,所以它真的是标准的。我的建议是尽可能多地使用 *dash* 来编写脚本,尤其是服务器端脚本。尽管 *bash* 更具表现力,但 *dash* 运行速度更快且更安全。 (7认同)

tho*_*ter 104

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

shell 不仅负责绘制您的小提示,还负责解释您的命令,尤其是当您放入管道、条件等复杂逻辑时。

bash是最常用的 shell,用作 Linux 系统用户的默认 shell。它是 Unix 历史上使用的其他 shell 的精神后代。它的名字bash是 Bourne-Again Shell 的缩写,这是对它旨在取代的 Bourne shell 的致敬,尽管它也结合了 C Shell 和 Korn Shell 的功能。

现在,它从/bin/bash- 任何带有 bash 的系统都可以在此处访问。

不过,使用 shell 的不仅仅是用户。脚本(shell 脚本)需要 shell 来解释它们。当您运行 shell 脚本时,您的系统需要启动一个 shell 进程来执行您的脚本。

问题是,不同的 shell 之间存在微小的不一致,当涉及到运行脚本时,这可能是一个真正的问题。 bash有很多脚本功能,这些功能仅适用于 bash,而不适用于其他 shell。这很好,如果您总是要使用 bash 来运行这些脚本。其他 shell 可能会尝试模拟 bash,或者遵循 POSIX 标准,bash 非常支持该标准(尽管添加了自己的扩展)。

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

/bin/sh是一个代表系统 shell的可执行文件。实际上,它通常被实现为指向可执行文件的符号链接,无论是哪个 shell 都是系统 shell。系统 shell 是一种系统脚本应该使用的默认 shell。在 Linux 发行版中,长期以来,这通常是到bash的符号链接,以至于总是将 /bin/sh 链接到 bash 或与 bash 兼容的 shell 已成为某种约定。然而,在过去的几年里,Debian(和 Ubuntu)决定将系统 shell 从 bash 切换到dash- 一个类似的 shell - 打破了 Linux(好吧,GNU)中将 bash 用于 /bin/sh 的悠久传统。Dash 被视为更轻、更快的 shell,它可以提高启动速度(以及其他需要大量 shell 脚本的东西,比如包安装脚本)。

Dash 与 bash 相当兼容,基于相同的 POSIX 标准。但是,它没有实现特定于 bash 的扩展。存在使用#!/bin/sh(系统外壳)作为其shebang 的脚本,但需要特定于bash 的扩展。这目前被认为是应该由 Debian 和 Ubuntu修复错误,它们需要 /bin/sh 在指向破折号时能够工作。

即使 Ubuntu 的系统 shell指向 dash,此时您作为用户的登录 shell仍然是 bash。也就是说,当您在 Linux 中的任何地方登录终端模拟器时,您的登录 shell 将是 bash。当 shell 以交互方式使用并且用户熟悉 bash(并且可能在他们的主目录中具有 bash 特定的自定义项)时,操作速度不是问题。

编写脚本时应该使用什么

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

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


小智 26

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

bash(1) 手册页

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

例如 bash 特定的语法:

 exec  > >(tee logfile.txt)
Run Code Online (Sandbox Code Playgroud)

#!/bin/sh即使 sh->bash 符号链接到位,也会在以 开头的 shell 中给出错误。


小智 12

GNU Bash: #!/bin/bash; POSIX 外壳:#!/bin/sh.

  • 嗯,简短但准确的答案。还行 (2认同)