bash myscript.sh 在bash中运行,但第一行是#!/usr/bin/sh

bash myscript.sh 在bash中运行,但第一行是#!/usr/bin/sh

我有一个类似于以下脚本的脚本:

#!/usr/bin/sh

var="ABC"
if [ $var == "ABC" ]
then
   echo True
else
   echo False
fi

上面的代码在 Solaris Sparc 和 Solaris X64 中不起作用。它显示==未定义。如果我替换==为,上面的代码工作正常=

奇怪的是,如果我通过以下方法运行上面的代码而不进行任何更改,它就可以工作。

#bash test.sh

根据我的理解,即使使用 bash,该脚本也不应该工作,因为我正在使用的脚本顶部#!/bin/sh不支持== 作为比较运算符。

谁能解释一下为什么当我运行上面提到的脚本时它确实有效。

注意:我知道 bash 确实可以识别===

答案1

脚本的第一行称为该#!行(有时称为“舍邦”线)。

仅当直接执行脚本时才使用它,如

./test.sh

解释

当您运行可执行文件时,操作系统会查看前两个字节来判断程序的类型。

当你跑步时

./test.sh

操作系统看到 的前两个字节./test.sh#!,因此它知道该程序是一个脚本。

它读取该行的其余部分以查看应使用哪个 shell 1来运行脚本。在本例中,该行的其余部分是/usr/bin/sh,因此它运行/usr/bin/sh test.sh2

当你跑步时

bash test.sh

/usr/bin/bash它在3中找到 bash 。它发现 的前两个字节/usr/bin/bash不是#!,因此它/usr/bin/bash test.sh甚至不看第一行就运行test.sh.

在这两种情况下,sh实际上bash都会忽略 shebang 行,因为任何以 开头的行#都是注释。唯一#有这种神奇效果的是操作系统,而不是shell。

更多信息:

脚注:

  1. 事实上,它可以是任何程序,不一定是 shell。
  2. 其实更像是execl("./test.sh", "/usr/bin/sh", "./test.sh", NULL)
  3. /bin/sh在大多数 Linux 系统上,但问题是关于 Solaris。

答案2

使用 bash 运行脚本 (running bash test.sh) 意味着该脚本是使用 bash 解释的,而不是 Bourne shell (/bin/sh)。这就是它起作用的原因。 Bash 忽略 #!/bin/sh 因为它是注释。这只是你的操作系统的程序加载器如果您在没有 bash 的情况下运行 shell 脚本(./test.sh例如运行),则会启动 /bin/sh 。

相关内容