[DevOps翻译]`#!/usr/bin/bash`和`#!/usr/bin/env bash`的区别

692 阅读3分钟

本文由 简悦SimpRead 转码,原文地址 www.baeldung.com

探索#!/usr/bin/bash和#!/usr/bin/env bash shebang行之间的区别,了解......。

  1. 概述

Shebang是由一个哈希符号和一个感叹号(#!)组成的字符序列。在Linux、Solaris、macOS、BSD和其他基于Unix的系统中,它通常被用作脚本文件的第一行,用来指定执行文件中存在的命令的解释器。

在本教程中,我们将找出 #!/usr/bin/bash#!/usr/bin/env bash 之间的区别,同时,我们将讨论它们的优缺点。

  1. 设置

使用像nano这样的文本编辑器,让我们创建并打开一个可执行文件 sample.sh:

$ nano sample.sh

然后,我们在文件中加入以下内容。

#!/usr/bin/bash
echo "Baeldung is Awesome!"

我们还需要使用_chmod_命令使该脚本文件可执行。

$ chmod u+x sample.sh

这里, u+x 标志授予当前用户(u)以执行(x)的权限。

我们将在本教程中使用这个文件来测试 #!/usr/bin/bash#!/usr/bin/env bash shebang行的行为。

  1. 使用 #!/usr/bin/bash

#!/usr/bin/bash 是脚本文件中的一个shebang行,用于设置 '/bin' 目录中的bash,作为执行文件中命令的默认shell。

它定义了一个绝对路径 /usr/bin/bash 到Bash shell。这通常是几乎所有基于Unix的操作系统中Bash shell的默认位置。

要知道Bash在我们系统中的位置,我们可以使用which命令。

$ which bash
/usr/bin/bash

由于我们创建的 sample.sh 已经包括了这个shebang行,我们来运行它。

$ ./sample.sh
Baeldung is Awesome!

我们还可以使用 #!/usr/bin/bash shebang行来向shell解释器传递额外的参数。

#!/usr/bin/bash -r

这个shebang行被用来执行Bash解释器的命令。-r 选项可以启用受限的shell模式。

当我们想准确地指向解释器的绝对路径时,推荐使用 #!/usr/bin/bash shebang。它还具有相对较高的安全性,而且我们可以传递额外的参数

缺点是,它的可移植性较差,因为不同的系统可以将解释器安装在不同的位置。 也很难记住所有解释器的绝对路径,尤其是在安装了多个解释器的系统中,包括 pythonzshcshkshshtcsh

  1. 使用 #!/usr/bin/env bash

正如我们前面提到的,**#!/usr/bin/env bash 也是脚本文件中的一个shebang行,用于用Bash shell执行命令。

它使用env命令来显示系统中存在的环境变量,然后用定义的解释器执行命令。

env 命令的工作原理是指示系统通过$PATH变量寻找指定的解释器,并使用找到的第一个出现。在基于Unix的系统中,它位于 "/usr/bin/env" 目录下。

我们可以使用 which 命令来验证它在我们系统中的位置。

$ which env
/usr/bin/env

让我们用 env 来显示所有当前由shell定义的环境变量。

$ env
SHELL=/bin/bash
SESSION_MANAGER=local/user-PC:@/tmp/.ICE-unix/2839,unix/user-HP-Pavilion-g6-Notebook-PC:/tmp/.ICE-unix/2839
QT_ACCESSIBILITY=1
COLORTERM=truecolor
...truncated

接下来,让我们用grep来显示来自 env 命令的 $PATH

$ env | grep PATH
WINDOWPATH=2
PATH=/home/username/.rbenv/shims:/home/username/.rbenv/bin:/home/username/.local/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/usr/games:/usr/local/games:/snap/bin

从上面的输出中,我们可以看到 $PATH 包含指向 /bin 和其他目录的符号链接,用冒号分隔。

为了测试这个shebang行,让我们首先修改 sample.sh 文件的第一行。

#!/usr/bin/env bash

然后,我们可以执行这个脚本文件。

$ ./sample.sh
Baeldung is Awesome!

通过 /usr/bin/env 运行脚本文件的好处是可以自动搜索当前环境中的默认版本的解释器。 这样,我们就不需要在系统中的特定位置搜索,因为其他系统中的路径可能不同。

我们还可以指定要使用的解释器的版本。下面是一个指定Bash解释器版本的格式示例。

#!/usr/bin/env bashX.x

#!/usr/bin/env bash shebang提供了更多的可移植性,因为我们不需要写出解释器的绝对路径。

但是,它不支持多参数。这是因为声明的解释器和它的选项被解析为一个参数

此外,在我们的环境中有多个版本的解释器的情况下, 可能会出错,因为它使用在 $PATH 中找到的第一个_bash_ 实例。

  1. 比较

下面是一个显示这些shebang行之间比较的表格。

#!/usr/bin/bash#! /usr/bin/env bash
提供了更多的安全性提供了更多的可移植性
更具体。因为我们必须声明
解释器的确切路径
自动搜索环境中第一次出现的
解释器
可以支持在声明解释器之后传递的额外参数不能支持额外参数,因为
系统将它们作为一条命令来读取
  1. 结论

在这篇文章中,我们已经探讨了 #!/usr/bin/bash#!/usr/bin/env bash shebang行之间的区别。我们还研究了它们的优点和缺点。

我们可以使用它们中的任何一个来执行Bash shell或其他shell脚本中的命令。然而,当安全问题是优先考虑的时候,建议使用 #!/usr/bin/bash,如果我们要寻求可移植性的话,建议使用 #!/usr/bin/env bash

如果你在Linux生态系统中有几年的经验,并且你有兴趣与社区分享这些经验,请看一下我们的[贡献指南](www.baeldung.com/linux/contr…


www.deepl.com 翻译