大多数技术社区成员喜欢通过命令行界面 (CMD) 或 shell 与系统进行交互。通常,这会让他们的工作变得更轻松。例如,您可以创建一个 shell 命令来自动执行多项任务,而无需在 GUI 的多个按钮中点击。
当您启动 shell 或 CMD 程序时,它会编译多条信息。这些信息设置了程序如何访问底层系统资源以及整体行为。您可以将其存储在名为“环境”的地方。环境由表示键值对的字符串组成。在本教程中,我们将使用 Ubuntu 20.04 VPS 作为示例来指导您设置环境变量或 shell 变量。本指南也适用于其他 Linux 发行版。
环境变量和 Shell 变量有什么区别?
当您启动会话时,系统会从系统的设置和配置文件中收集信息。然后,这些信息可供 shell 进程及其子进程使用。这些信息是以下格式的一组键值对:
|
1 2 3 |
KEY=value KEY="Some value" KEY=data1:data2 |
变量的名称(即键)是区分大小写的。然而,按照惯例,通常将它们写为大写。这有助于您在其他上下文中区分它们。使用冒号 ‘:’ 字符,您可以为同一个变量分配多个值。同样重要的是,确保在 = 两边不要留空格。键就是变量,分为两类:环境变量和 shell 变量。环境变量包含系统范围内定义的所有变量,并且对每个子 shell 或进程都可用。它们有助于将信息传递到您通过 shell 命令启动的进程中。Shell 变量仅包括在特定 shell 会话中定义的变量。此外,它们仅包括专门在其 shell 实例中可用的变量。
列出环境变量和 Shell 变量
默认情况下,终端提供了两个命令来列出环境变量和 shell 变量:env 或 printenv。它们在默认状态下显示相同的信息。以下是这些命令的示例输出:
使用 env:

使用 printenv:

如您所见,输出是相同的。区别在于当您想要特定键的值时。这时您将使用带有变量名称 of printenv:

要查看多个值,您可以向 printenv 命令传递多个参数。这些值将按照您输入参数的顺序显示:

您也可以使用带有变量名称的 echo 命令来显示变量的值:

env 命令允许您通过传递变量定义来修改程序运行的环境,其语法如下:
|
1 |
env VAR1="var 1 value" command_to_run command_options |
这允许您覆盖值或设置可由子进程使用的新值。如上所示,printenv 和 env 命令列出了环境变量。这些已经是为系统进程定义的。如果您想查看 shell 变量列表,可以使用 set 命令。在不带任何变量的情况下输入 set 将返回所有环境变量、shell 变量、局部变量和 shell 函数的列表:

变量可能太多。如果需要,您可以使用以下命令对它们进行分页:
|
1 |
set | less |
您可以通过指定 set 命令在 POSIX 中执行来进一步清理输出,从而不打印 shell 函数。这里我们在子 shell(命令处理器的独立实例)中执行,以防止该命令更改当前环境:
|
1 |
(set -o posix; set) |
以上列出了系统上可用的所有环境和 shell 命令。您可以使用以下命令来精简输出,尝试仅获取 shell 变量:
|
1 |
comm -23 <(set -o posix; set | sort) <(env | sort) |
上述命令的示例输出如下:

虽然该命令可能包含一些环境变量,但它将帮助您区分 Shell 变量和环境变量。这是因为 set 命令会用引号括起变量的值,而 printenv 和 env 命令则不会。Shell 变量对于为会话设置持久值非常有用,同时又不会将更改永久写入文件。
常用环境变量
USER – 当前登录的用户。
SHELL – 将解释您输入的命令的 Shell。默认是 bash,但您可以更改它。
HOME – 当前用户的家目录。
TERM – 指定要模拟的终端类型。显示当前模拟的终端。
PWD – 当前工作目录。
OLDPWD – 上一个工作目录。这有助于在您输入 cd 命令切换目录时,Shell 能够切换回上一个目录。
EDITOR – 在终端中输入 edit 时的默认文件编辑器。
LS_COLORS – 定义在输入 ls 命令时用于添加彩色输出的颜色代码。它有助于区分文件类型并向用户提供信息。
LOGNAME – 当前用户的名称。
MAIL – 定义当前用户邮箱的路径。
LANG – 定义当前的区域设置。
PATH – 指定执行命令时要搜索的目录列表。在执行命令期间,系统会搜索这些目录并使用找到的第一个可执行文件。
_ – 上一次执行的命令。
常用 Shell 变量:
BASH_VERSION – 人类可读输出格式的 bash 版本。
BASH_VERSINFO – 机器可读输出格式的 bash 版本。
BASHOPTS – 执行 bash 时使用的选项列表。对于确定 Shell 环境是否会按预期运行非常有用。
COLUMNS – 用于在屏幕上绘制输出的列宽数。
DIRSTACK – 可通过 pushd 和 popd 命令使用的目录栈。
HOSTNAME – 计算机当前的主机名。
HISTFILESIZE – 文件中存储的命令历史记录行数。
HISTSIZE – 内存中允许的命令历史记录行数。
IFS – 用于分隔命令行输入的内部字段分隔符。默认情况下为空格。
SHELLOPTS-用于设置 Shell 选项。
UID-当前用户的 UID。
PS1– 主命令提示符定义。这用于定义启动 Shell 会话时提示符的外观。
PS2 – 声明当命令跨越多个行时的辅助提示符。
设置环境和 Shell 命令
首先,如前所述,我们将保持变量名全部大写。接下来,我们将介绍如何创建 Shell 变量。最后,我们将创建环境变量。
创建 Shell 变量
让我们从通常的 hello world 开始。在终端中输入以下内容:
|
1 |
MY_FIRST_VAR=’Hello World!’ |
使用引号是因为变量中含有空格。请注意,我们使用了单引号,因为感叹号是一个特殊字符,应该被转义或放入单引号中。现在,您已经创建了第一个 Shell 变量。它仅在当前 Shell 会话中可用。Shell 变量对子 Shell 和进程不可用。您可以使用带有 grep 的 set 命令将其打印到终端:

或者使用 echo 显示该值,并使用 $ 符号和变量名来引用它:

如果您尝试使用 printenv 进行打印,它将不会显示任何输出。这有助于您确认这不是一个环境变量:

创建环境变量
之前创建的 Shell 变量可以使用 export 命令转换为环境变量。首先,您创建一个 Shell 变量。然后,要创建环境变量,您需要使用 export 命令。执行此命令后,该变量将对子 Shell 和进程可用:
|
1 |
export MY_FIRST_VAR |
现在,如果您使用 printenv 命令进行测试,应该会看到该变量和值:

您还可以使用以下语法一步创建环境变量:
|
1 |
export MY_SECOND_VAR='这是我的第二个变量' |
环境变量只会传递给子 shell,而不会传递给父 shell。这有助于防止子进程影响调用它们的程序的环境。
降级和取消设置变量
如果您一直按照本教程操作到这一步,那么您仍然将 MY_FIRST_VAR 定义为环境变量。您可以通过输入带有 –n 标志的 echo 命令将其改回 shell 命令:
|
1 |
export -n MY_FIRST_VAR |
如果使用 printenv 进行测试,将没有输出。但是,echo 命令会显示它,因为它仍然是一个 shell 命令:

您可以使用 unset 命令取消设置 shell 变量或环境变量。您可以使用 echo 确认它不再存在。如您所见,它没有显示任何输出:

在登录时设置环境变量
许多程序的执行都依赖于环境变量。由于每次想要执行程序时都设置变量效率低下,Linux 提供了一种定义它们并将其保存到文件中的方法。这样,它们就可以在登录时自动设置。Shell 会根据会话的启动方式读取不同的配置文件。下面将对这些内容进行讨论:
Shell 会话的类型及其区别
- 登录 Shell 会话 – 从验证用户开始。当您通过 SSH 或终端会话登录时,该会话即被建立。
- 非登录 Shell 会话 – 当您在已验证的 shell 中启动新的 shell 时开始。您可以使用 bash 命令启动新的 shell。不需要身份验证信息。
- 交互式 Shell 会话 – 与终端会话相关联的 shell 会话。
- 非交互式 Shell 会话 – 未与终端会话相关联的 shell 会话 – 在后台运行。
会话分为登录或非登录,以及交互式或非交互式。当您登录并通过 SSH 开始 shell 会话时,那将是一个登录且交互式的 shell 会话。当您在终端上运行脚本时,它通常在非登录、非交互式会话中运行。Shell 会话也可以是两者的结合。那么,会选择哪个配置文件呢?
登录会话首先读取 /etc/profile 目录中的配置文件。其次,它会检查用户家目录中用户特定的配置文件。在 ~/.bash_profile、~/.bash_login 和 ~/.profile 中,只有找到的第一个文件会被读取,其他所有文件都会被忽略。非登录会话将首先读取 /etc/bash.bashrc,然后是 ~/.bashrc。非交互式会话读取名为 BASH_ENV 的环境变量,以获取用于定义新环境的文件名。
实现环境变量
设置变量时,请始终根据我们上面的讨论注意将它们放在哪个文件中。通过确保某些变量仅在某些会话中可用,这将提供灵活性。您不希望在某个会话中缺失关键变量。
在某些情况下,我们希望变量同时存在于登录和非登录会话中。幸运的是,大多数 Linux 发行版默认已将登录配置配置为读取非登录配置,并使其对您的进程可用。因此,您只需在非登录配置文件中定义变量即可。通常,我们设置特定于用户的环境变量,并希望我们的设置在登录和非登录 shell 会话中都可用。出于这个原因,我们将使用 ~/.bashrc 文件。我们将使用 nano 来编辑该文件。在终端中输入以下内容以打开该文件:
|
1 |
nano ~/.bashrc |
在打开的配置文件中,您已经可以看到几个变量。您可以像使用命令行时那样添加环境变量。只需输入以下命令:
|
1 |
export KEYNAME=value. |
您可以将它们添加到文件中的任何位置——在新行中,且不要在循环函数内部。然后,保存并关闭文件。您启动的任何下一个 shell 会话都将读取该文件。如果您希望当前的 shell 读取您刚刚添加的设置而无需重新启动它,您可以使用以下命令:
|
1 |
source ~/.bashrc |
您应该在以下任一文件中添加系统级环境变量:/etc/profile、/etc/bash.bashrc 或 /etc/environment。
总结
最后,您现在可以设置 shell 变量和环境变量,并享受这些工具为您的 VPS 带来的强大功能!它有很多优势,例如自动运行某些进程,或需要身份验证信息的自动部署配置,将变量传递给子进程等等。环境变量可以帮助您在公共仓库中隐藏敏感数据(如身份验证信息)以及其他数据。有了这个基础,您可以创建复杂的脚本,通过命令行自动执行,而无需用户不断输入。
祝您使用愉快!
评论
暂无评论。发表第一条评论吧。