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

如果我写,

#!/bin/bash echo "foo" 

要么

 #!/bin/sh echo "foo" 

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

bashsh是两个不同的shell。 基本上bashsh ,具有更多function和更好的语法。 大多数命令的工作方式相同,但它们不同。

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

有关详细信息,请访问http://man.cx/sh,http://man.cx/bash 。

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

shell不仅负责绘制你的小提示,还负责解释你的命令,特别是如果你输入管道,条件等复杂的逻辑。

bash是最常用的shell,用作Linux系统用户的默认shell。 它是整个Unix历史中使用的其他shell的精神后代。 它的名字, bash是Bourne-Again Shell的缩写,它是为了取代它而设计的Bourne shell的致敬,尽管它还包含了C Shell和Korn Shell的function。

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

但是,不只是使用shell的用户。 脚本( shell脚本 )需要shell来解释它们。 运行shell脚本时,系统需要启动shell进程才能执行脚本。

问题是,不同的shell之间几乎没有一点点不一致,当涉及到运行脚本时,这些可能是一个真正的问题。 bash有很多脚本function,这些function仅对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(使用bash)/ bin / sh的长期传统。 Dash被认为是一个更轻,更快的shell,它可以有利于启动速度(以及其他需要大量shell脚本的东西,比如包安装脚本)。

Dash与bash完全兼容,基于相同的POSIX标准。 但是,它不实现特定于bash的扩展。 现有的脚本使用#!/bin/sh (系统shell)作为他们的shebang,但需要特定于bash的扩展。 这当前被认为是一个应该由Debian和Ubuntu 修复bug ,它需要/ bin / sh才能在指向dash时工作。

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

编写脚本时应该使用什么

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

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

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

从bash(1)手册页 :

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

例如bash特定语法:

  exec > >(tee logfile.txt) 

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