#!/ bin / sh和#!/ bin / bash之间有什么区别?
如果我写,
#!/bin/bash echo "foo"
要么
#!/bin/sh echo "foo"
两者都相同。 我看过一些以#!/bin/sh
或#!/bin/bash
开头的脚本。 它们之间有什么区别吗?
bash
和sh
是两个不同的shell。 基本上bash
是sh
,具有更多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符号链接也是如此。