如何使用 Shebang
什么是 Shebang?
简单来说,就是你在脚本开头看到的这个:
#!/usr/bin/bash
Shebang(也称为 hash-bang、pound-bang 或者 bang)是一个作为脚本文件中的第一行的特殊注释,它告诉系统用哪个解释器来执行脚本。Shebang 后面直接跟着解释器的绝对路径。
在上面的例子中,Shebang 指示系统使用 /usr/bin/bash 作为脚本的解释器。当我们使用如下的命令运行脚本时:
./script.sh
系统就会自动使用 /usr/bin/bash 作为解释器来运行该脚本,即使我们在命令中并没有指定解释器。其作用相当于:
/usr/bin/bash script.sh
然而,如果系统中没有 /usr/bin/bash 这个程序,那么在执行上面的命令时就会出现报错:
zsh: ./script.sh: bad interpreter: /usr/bin/bash: no such file or directory
实际上,即便系统中的某个地方安装有 bash 程序,但因为我们指定的解释器是 /usr/bin/bash,所以只要 bash 没有安装在 /usr/bin 目录下,那么执行脚本的命令 ./script.sh 就会报错。
最佳实践是通过 env 程序来寻找解释器:
#!/usr/bin/env bash
一般来说,每个 *nix 系统在 /usr/bin 目录下都有 env 程序。env 程序的作用是在系统环境变量 PATH 下寻找我们需要的程序,在这个例子中是 bash。也就是说,通过 #!/usr/bin/env xxx 的形式,我们允许需要的程序安装在系统的不同位置,这样就提升了我们脚本的兼容性。它允许了解释器安装在非标准位置的用户也能通过 ./script.sh 命令运行我们的脚本,或者某些希望使用非系统版本解释器的用户能够继续使用自定义的解释器来执行我们的脚本(前提是他在系统环境变量 PATH 的前面指定了自定义解释器的路径)。
然而,不是所有情况都应该使用 #!/usr/bin/env。其中一个例子是我们希望使用虚拟环境下的 Python 解释器来运行我们的脚本:
假设我们编写了一个 Python 脚本,并在其虚拟环境中安装了脚本依赖。这时,我们会希望使用虚拟环境的 Python 解释器来运行我们的脚本,因为这样才能确保运行环境中包含了脚本所需的依赖。
假设我们的虚拟环境安装在脚本文件所在目录下的 .venv 目录中:
#!.venv/bin/python
这样,就确保了用户使用 ./script.py 命令运行我们的脚本时使用的是虚拟环境下的 Python 解释器。这种做法可以省去手动激活虚拟环境的步骤。