您经常会遇到以下开头的 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!
那么为什么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 行有所不同。
这就是为什么使用 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 脚本的开头。 如果您有任何问题或建议,请随时发表评论。