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


Answers:


242

bashsh是两个不同的外壳。基本上bashsh,具有更多功能和更好的语法。大多数命令的工作原理相同,但不同。

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

欲了解更多信息,http://man.cx/shhttp://man.cx/bash


24
您的第一段颇具误导性。“ sh”根本不是外壳程序,而是与当前配置的系统外壳程序的符号链接,在Linux系统上通常是bash或破折号(使用后者的最新版本的Ubuntu)。
thomasrutter 2012年

18
/bin/sh早在1977年就曾经是称为bourne shell的shell。bash是/ bin / sh兼容的shell,可以用作posix 兼容的bourne shell替换。 zh.wikipedia.org/wiki/Bourne_shell
Alex

5
bash是事实上的标准(已广泛使用),但不是“标准”;在Ubuntu上的sh使用dash,它是Posix兼容的外壳,因此它确实是标准的。我的建议是尽可能多地使用破折号来编写脚本,尤其是对于服务器端脚本。尽管bash更具表现力,但破折号的运行速度要快得多,并且更安全。
Rick-777

@ Rick-777那么我应该在脚本顶部显式地添加#!/ bin / dash吗?我还编写了脚本,在这些脚本中,我只编写命令并使用./scriptName执行,并且效果很好。#!/ bin / yourShellHere是否必要?
user137717

@ Rick-777在排除任何#!/ bin / shellName的情况下,我已将文件命名为fileName.sh。是否可以在不声明#!/ bin / sh的情况下隐式链接到首选系统外壳?
user137717

82

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

Shell不仅负责绘制您的小提示,而且负责解释命令,尤其是当您放入复杂的逻辑(例如管道,条件等)时。

bash是最常见的shell,用作Linux系统用户的默认shell。它是整个Unix历史上使用的其他shell的精神衍生。它的名字 bash是Bourne-Again Shell的缩写,是对Bourne Shell的致敬,尽管它还结合了C Shell和Korn Shell的功能,但它是为取代Bourne Shell而设计的。

这些天来,它可以运行/bin/bash-任何具有bash的系统都可以在此处访问它。

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

问题是,不同的外壳之间存在微小的不一致,而在运行脚本时,这可能是一个真正的问题。 bash具有很多脚本功能,这些功能仅bash独有,而其他shell则没有。如果您总是要使用bash来运行这些脚本,那很好。其他shell可能会尝试模仿bash或遵循POSIX标准,bash很好地支持了该标准(尽管添加了自己的扩展名)。

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

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

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

即使Ubuntu的系统外壳指向破折号,但作为用户的登录外壳此时仍是bash。也就是说,当您在Linux中的任何地方登录到终端仿真器时,您的登录Shell将为bash。当交互式使用外壳程序时,操作速度并不是什么大问题,并且用户熟悉bash(并且可能在其主目录中具有bash特定的自定义项)。

编写脚本时应使用的内容

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

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


18

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

bash(1)手册页中

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

例如bash特定的语法:

 exec  > >(tee logfile.txt)

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.