Linux Shell 脚本中的 Shebang 是什么?

您经常会遇到以下开头的 shell 脚本:

#!/bin/bash

#! 被称为shebang或hashbang。 shebang 在 shell 脚本中扮演着重要的角色,特别是在处理不同类型的 shell 时。

在本教程中,您将学习:

  • 什么是社邦?
  • 它如何在 shell 脚本中发挥重要作用?

shell脚本中的shebang是什么?

shebang 是 #(井号键)和 ! (感叹号)。 这个字符组合在脚本的第一行使用时具有特殊的含义。 它用于指定默认情况下运行给定脚本的解释器。

因此,如果脚本的第一行是:

#!/bin/bash

这意味着口译员应该是 bash 贝壳。 如果第一行是:

#!/bin/zsh

这意味着要使用的解释器是 Z shell。

这 #! 肯定是特别的,因为 # 用于 shell 脚本中的注释,但在这里它有特殊的含义。

为什么 shebang 在 shell 脚本中很重要?

事情就是这样。 后跟 shell 可执行文件的 shebang 对于脚本不是必需的。

如果你写一个这样的简单脚本:

echo "Namaste, folks!"

并赋予它执行权限并使用 . 运算符,它将由您的登录 shell 运行。

[email protected]:~$ cat sample 
echo "Namaste, folks!"
[email protected]:~$ chmod u+x sample 
[email protected]:~$ ./sample 
Namaste, folks!
Shebang 在 shell 脚本中不是强制性的

那么为什么shell脚本包含#!/bin/bash 脚本开头的行?

因为有几个 shell 可用于 Linux 和 UNIX 系统。 虽然这些 shell 具有大多数通用语法,但它们确实具有不同的语法或不同的处理方式。

这就是为什么在脚本中指定正确的 shell 解释器变得很重要的原因,否则某些脚本在不同的 shell 中运行时可能会产生不同的结果。

让我用一个简单的方法向你展示 example.

用 shebang 指定 shell 解释器的重要性

我编写了一个带有一系列分布的示例 shell 脚本。 然后该脚本在索引 2 处显示发行版。

distros=("Ubuntu" "Fedora" "SUSE" "Debian")
echo "Distro at index 2 is: ${distros[2]}"

我没有添加 shebang 行来指定任何 shell 解释器。 这意味着当我执行此脚本时,它将由默认 shell 运行(bash 在我的情况下):

[email protected]:~$ echo $0
bash

你能猜出脚本的输出吗?

[email protected]:~$ ./arrays.sh 
Distro at index 2 is: SUSE

它在索引 2 处显示 SUSE,因为在 Bash 和许多其他编程和脚本语言中数组索引从 0 开始。 但在 Z shell 中并非如此。 在 Z shell 中,数组索引从 1 开始。

我的系统上安装了 Z shell。 我更改了脚本并添加了 shebang 行以指定该脚本应默认由 Z shell 运行。

#!/bin/zsh

distros=("Ubuntu" "Fedora" "SUSE" "Debian")
echo "Distro at index 2 is: ${distros[2]}"

当我现在运行脚本时,你能猜到输出吗?

[email protected]:~$ ./arrays.sh 
Distro at index 2 is: Fedora
带有 shebang 的 Shell 脚本

你现在注意到不同了吗? 这是相同的脚本,但添加了 shebang 行有所不同。

这就是为什么使用 shebang 运算符指定正确的 shell 解释器很重要的原因。 作为系统管理员,您可能会在编写 shell 脚本时牢记特定的 shell,无论是 bash, ksh 或 zsh。 但是您不能确定将运行脚本的系统是否具有与您相同的默认 shell。 现在事情是有道理的,对吧?

如果显式指定 shell,Shebang 将被忽略

为什么我强调“默认”外壳? 因为 shebang 指定了运行脚本的解释器。

但是,您可以明确指定 shell,在这种情况下,shebang 行将被忽略。

shebang究竟是如何工作的?

当您在脚本的第一行中使用 shebang 时,您是在告诉 shell 使用指定的命令运行给定的脚本。

基本上, #!/bin/zsh 相当于:

/bin/zsh script_name

我告诉过你,如果脚本的第一行以 shebang 开头,这意味着你正在指定 shell 解释器。

这只是部分正确。 实际上,这就是shebang角色的目的。 但是 shebang 行不必必须具有 shell 的可执行文件。 它可以是任何东西。

为了 example我要换 #!/bin/zsh#!/bin/cat. /bin/cat 是 cat 命令的可执行文件。

#!/bin/cat

distros=("Ubuntu" "Fedora" "SUSE" "Debian")
echo "Distro at index 2 is: ${distros[2]}"

这意味着现在这个脚本将运行 cat 命令并显示脚本的内容。

社帮线可以包含任何东西

只要它指向可执行命令,它就会起作用。 如果你放一些随机的东西,它会抛出错误。

我将shebang线更改为:

#!/home/abhishek

显然,它不指向任何命令的可执行文件,因此会引发错误的解释器错误。

[email protected]:~$ cat arrays.sh 
#!/home/abhishek

distros=("Ubuntu" "Fedora" "SUSE" "Debian")
echo "Distro at index 2 is: ${distros[2]}"
[email protected]:~$ ./arrays.sh 
bash: ./arrays.sh: /home/abhishek: bad interpreter: Permission denied

结论

在结束本文之前,让我再回答几个问题:

  • 重要的是中间没有空格 #!. 你不能这样使用它: # !/bin/bash.
  • 大多数系统允许之间的空间 #!/bin/bash 但是,避免在 #!/bin/bash.
  • #! 必须在第一行,否则 shebang 行将被视为注释。 你甚至不能在它之前有一个空行。

我希望你能更好地理解为什么#! 用于 Linux 中 shell 脚本的开头。 如果您有任何问题或建议,请随时发表评论。