如果我写了,



#!/bin/bash
echo "foo"


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

#1 楼

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

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

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

评论


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

–胸骨
2012年9月5日在1:16



/ bin / sh以前是1977年的一个叫做bourne shell的外壳。bash是/ bin / sh兼容的外壳,可以用作posix兼容的bourne shell替换。 zh.wikipedia.org/wiki/Bourne_shell

–亚历山大·吴
2014年9月18日下午6:57

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

–Rick-777
2014-09-29 17:19

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

–user137717
15年8月27日在20:42

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

–user137717
15年8月27日在20:44

#2 楼

在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来运行。脚本可以在第一行中指定#!/bin/bash,这意味着该脚本应始终使用bash运行,而不是另一个shell。

/ bin / sh是代表系统外壳程序的可执行文件。实际上,通常将其实现为指向可执行文件的符号链接,无论该shell是系统shell还是该可执行文件。系统外壳是系统脚本应使用的默认外壳。在Linux发行版中,长期以来,这通常是bash的符号链接,以至于始终将/ bin / sh链接到bash或bash兼容的shell已成为一种惯例。但是,在过去的几年中,Debian(和Ubuntu)决定将系统外壳程序从bash切换为破折号(类似的外壳程序),打破了Linux(以及GNU)将bash用于/ bin / sh的悠久传统。 Dash被视为更轻便,速度更快的Shell,可以提高启动速度(以及其他需要大量Shell脚本(例如软件包安装脚本)的东西)。 bash,基于相同的POSIX标准。但是,它没有实现bash特定的扩展。现有的脚本使用#!/bin/sh(系统外壳程序)作为它们的shebang,但是需要特定于bash的扩展。当前认为这是应该由Debian和Ubuntu修复的错误,它们要求/ bin / sh指向破折号时才能工作。

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

编写时应使用的内容脚本

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

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

#3 楼

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

从bash(1)手册页中:


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

例如bash特定的语法: > bash符号链接到位。

#4 楼

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

评论


好吧,简短但准确的答案。还行

– Sergiy Kolodyazhnyy
18/12/24在11:11