我有一个类似于以下脚本的脚本:
#!/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.sh
2。
当你跑步时
bash test.sh
/usr/bin/bash
它在3中找到 bash 。它发现 的前两个字节/usr/bin/bash
不是#!
,因此它/usr/bin/bash test.sh
甚至不看第一行就运行test.sh.
在这两种情况下,sh
实际上bash
都会忽略 shebang 行,因为任何以 开头的行#
都是注释。唯一#
有这种神奇效果的是操作系统,而不是shell。
更多信息:
脚注:
- 事实上,它可以是任何程序,不一定是 shell。
- 其实更像是
execl("./test.sh", "/usr/bin/sh", "./test.sh", NULL)
。 /bin/sh
在大多数 Linux 系统上,但问题是关于 Solaris。
答案2
使用 bash 运行脚本 (running bash test.sh
) 意味着该脚本是使用 bash 解释的,而不是 Bourne shell (/bin/sh)。这就是它起作用的原因。 Bash 忽略 #!/bin/sh 因为它是注释。这只是你的操作系统的程序加载器如果您在没有 bash 的情况下运行 shell 脚本(./test.sh
例如运行),则会启动 /bin/sh 。