在 Linux 中管理 Shell 环境与配置

CompTIABeginner
立即练习

介绍

在本实验中,你将学习在 Linux 中管理 Shell 环境和配置的基础知识。首先,你将创建本地变量和环境变量,并使用 echoexportenv 等命令来理解它们在 Shell 会话中作用域和可用性的核心区别。

在此基础上,你将探索变量和别名(alias)是如何在子 Shell 中继承的。你还将学习如何通过 set -o allexport 选项控制变量的自动导出,以及如何通过修改 .bashrc 文件使你的自定义配置在不同会话间保持持久化。

这是一个引导实验,提供分步指令来帮助你学习和练习。请仔细遵循说明完成每个步骤并获得实践经验。历史数据表明,这是一个初学者级别的实验,完成率为 86%。它获得了学习者 100% 的好评率。

创建并区分本地变量与环境变量

在这一步中,你将学习如何创建和管理 Shell 变量。在像 Zsh 这样的 Linux Shell 中,变量用于存储信息。主要有两种类型:本地变量和环境变量。

  • 本地变量(或称 Shell 变量)仅在创建它的当前 Shell 中可用。
  • 环境变量不仅在当前 Shell 中可用,在从该 Shell 启动的任何子进程中也可用。

我们将使用 echoexportenv 命令来操作它们。所有命令都将在终端中执行。

首先,让我们创建一个本地变量。在已经处于 ~/project 目录的终端中,输入以下命令创建一个名为 flower 的变量,并将其赋值为 rose。请注意,等号(=)两边不能有空格。

flower=rose

要验证变量是否已创建,可以使用 echo 命令打印其值。变量名前的美元符号($)告诉 Shell 用变量的值进行替换。

echo $flower

你应该会看到终端打印出变量的值:

rose

现在,让我们检查这个本地变量是否属于 Shell 环境的一部分。env 命令会列出所有的环境变量。我们可以通过管道将输出传递给 grep 来搜索我们的变量。

env | grep flower

该命令不会产生任何输出。这是预期的结果,它证实了 flower 是一个本地变量,而不是环境变量。

接下来,让我们创建一个环境变量。过程类似,但我们要使用 export 命令。该命令会创建一个变量,并将其标记为传递给当前 Shell 的所有子进程。让我们创建一个名为 nut、值为 almond 的环境变量。

export nut=almond

像之前一样,使用 echo 进行验证。

echo $nut

命令将输出 nut 变量的值:

almond

现在,再次使用 env 命令检查它是否存在于环境中。

env | grep nut

这一次,命令找到并显示了该变量,确认 nut 是一个环境变量:

nut=almond

你现在已经成功创建了本地变量和环境变量,并看到了 Shell 环境处理它们的根本区别。我们将保留这些变量设置,以便在接下来的步骤中使用。

测试子 Shell 中的变量与别名继承

在这一步中,你将探索当你从当前 Shell 启动一个新的 Shell 时,变量和别名的行为。这个新的 Shell 被称为「子 Shell」,而原始的 Shell 被称为「父 Shell」。这个概念对于理解 Shell 环境的结构以及脚本如何执行至关重要。我们将测试上一步中的变量 flowernut 是否会被传递(或称「继承」)给子 Shell。

首先,让我们识别当前父 Shell 的进程 ID(PID)。Linux 中的每个进程都有一个唯一的 PID。你可以通过 echo $$ 命令查看它。

echo $$

你的输出将是一个数字,即当前 Shell 的 PID。例如:

123

现在,只需输入 zsh 并按回车键即可启动一个子 Shell。这会在当前进程内部创建一个新的 Shell 进程。

zsh

你现在处于一个新的 Shell 会话中。为了确认这一点,我们可以使用 ps -f 命令,它会显示详细的进程信息,包括父进程 ID(PPID)。

ps -f

查看输出。你会看到两个 zsh 进程。新 zsh 进程的 PID 对应的 PPID 应该与你之前记录的父 Shell 的 PID 相匹配。

UID          PID    PPID  C STIME TTY          TIME CMD
labex        123       1  0 10:00 pts/0    00:00:00 zsh
labex        456     123  0 10:01 pts/0    00:00:00 zsh
labex        457     456  0 10:01 pts/0    00:00:00 ps -f

在这个例子中,新的 Shell(PID 456)是原始 Shell(PPID 123)的子进程。

现在,让我们测试变量。在这个子 Shell 中,尝试显示本地变量 flower 的值。

echo $flower

该命令没有输出。这是因为本地变量仅限于创建它们的 Shell,不会被子 Shell 继承。

接下来,检查环境变量 nut

echo $nut

这一次,Shell 打印出了变量的值:

almond

这证明了环境变量与本地变量不同,它们会被子 Shell 继承。

现在,使用 exit 命令返回父 Shell。

exit

你现在回到了原始 Shell。让我们对别名(alias)进行类似的测试。别名是命令的快捷方式。创建一个名为 ldetc 的别名,用于执行 ls -ld /etc

alias ldetc='ls -ld /etc'

通过输入 alias 验证别名是否已创建。

alias ldetc

你应该能看到别名的定义:

ldetc='ls -ld /etc'

现在,通过运行别名来测试它。

ldetc

该命令将执行 ls -ld /etc 并显示 /etc 目录的详细信息。

drwxr-xr-x 1 root root 4096 Oct 10 10:00 /etc

现在,打开另一个子 Shell 看看别名是否被继承。

zsh

在新的子 Shell 中,尝试使用 ldetc 别名。

ldetc

你会收到一条错误消息,因为别名和本地变量一样,不会被子 Shell 继承。

zsh: command not found: ldetc

返回父 Shell。

exit

最后,让我们使用 unalias 命令从父 Shell 中删除该别名,进行清理。

unalias ldetc

尝试再次列出它以验证是否已删除。

alias ldetc

没有任何返回。

这个练习向你展示了 Shell 行为的一个关键原则:环境变量会被子进程继承,但本地变量和别名则不会。

使用 set -o allexport 控制自动变量导出

在这一步中,你将学习一个强大的 Shell 选项,称为 allexport。通常情况下,当你创建一个变量时,必须显式使用 export 命令才能使其成为环境变量。但是,通过启用 allexport 选项,你可以指示 Shell 自动导出你定义的每一个新变量。这可能是一个方便的快捷方式,特别是在所有变量都需要对子进程可用的脚本中。

Shell 选项是改变 Shell 行为的内部设置。你可以使用 set -o [选项名] 开启它们,使用 set +o [选项名] 关闭它们。

首先,让我们检查 allexport 选项的当前状态。你可以列出所有 Shell 选项并使用 grep 过滤出 allexport

set -o | grep allexport

默认情况下,此选项是关闭的。输出将显示其状态为 off

allexport              off

现在,让我们开启 allexport 选项。

set -o allexport

再次运行检查命令验证设置是否已更改。

set -o | grep allexport

这一次,输出将确认该选项已开启(on):

allexport              on

在启用 allexport 的情况下,你创建的任何变量都将自动成为环境变量。让我们测试一下。创建一个名为 truck 的新变量,而不使用 export 命令。

truck=chevy

现在,使用 env 命令检查 truck 是否存在于环境中。

env | grep truck

你会看到 truck 变量被列出来了,即使你没有使用 export。这是因为 allexport 选项处于激活状态。

truck=chevy

这个功能非常有用,但最好的做法是在不再需要时将其关闭,以避免无意中导出变量。让我们关闭 allexport

set +o allexport

最后,验证它是否已关闭。

set -o | grep allexport

输出将再次显示该选项为 off

allexport              off

从现在开始,你创建的任何新变量默认都将是本地变量,除非你显式使用 export 命令。

使用 .bashrc 文件持久化 Shell 选项

在这一步中,你将学习如何使你的 Shell 定制永久生效。你设置的任何别名、函数或 Shell 选项都是临时的,当你关闭终端会话时它们就会丢失。要永久保存它们,你需要将它们添加到 Shell 配置文件中。

虽然标题提到了 .bashrc(这是 Bash Shell 的配置文件),但我们的实验环境使用的是 Zsh Shell。Zsh 对应的配置文件是 ~/.zshrc。这个文件是一个脚本,每次你打开一个新的交互式 Shell 时它都会自动运行,因此它是存储个人设置的绝佳位置。

我们将通过使 noclobber Shell 选项永久生效来进行练习。noclobber 选项可以防止你在使用输出重定向(>)时意外覆盖现有文件。

首先,让我们使用 nano 文本编辑器将 noclobber 选项添加到你的 ~/.zshrc 文件中。~ 符号是你的主目录 /home/labex 的快捷方式。

nano ~/.zshrc

此命令在 nano 编辑器中打开 ~/.zshrc 文件。使用方向键将光标移动到文件的最后,并添加以下行:

set -o noclobber

现在,保存文件并退出 nano。为此,请按 Ctrl+O(写入),按 Enter 确认文件名,然后按 Ctrl+X 退出。

你现在回到了命令提示符。让我们检查 noclobber 选项在当前 Shell 中是否处于激活状态。

set -o | grep noclobber

输出将是:

noclobber              off

为什么它是关闭的?因为你当前的 Shell 会话尚未读取你刚刚对 ~/.zshrc 文件所做的更改。该文件仅在新的 Shell 启动时才会被读取。

为了证明这一点,让我们启动一个新的子 Shell。

zsh

你现在处于一个新的 Shell 中。让我们在这里检查 noclobber 的状态。

set -o | grep noclobber

这一次,输出将是:

noclobber              on

这证实了新的 Shell 会正确读取 ~/.zshrc 文件并应用设置。现在,退出子 Shell 返回到原始父 Shell。

exit

那么,如何在不关闭并重新打开当前 Shell 的情况下应用更改呢?你可以使用 source 命令,它会在当前 Shell 的上下文中读取并执行文件中的命令。

source ~/.zshrc

source 命令现在已经执行了配置文件中的 set -o noclobber 行。让我们验证 noclobber 现在是否在我们的原始 Shell 中开启了。

set -o | grep noclobber

输出现在将是:

noclobber              on

你已经成功学习了如何通过编辑 ~/.zshrc 文件来持久化 Shell 设置,以及如何使用 source 命令将这些更改应用到当前会话。

总结

在本实验中,你学习了管理 Linux Shell 环境的基本概念。你练习了创建本地变量(仅限于当前 Shell)和环境变量(会被任何子进程继承)。你使用了 echo 显示变量值、export 创建环境变量以及 env 列出环境变量等关键命令。通过启动子 Shell,你进一步探索了继承的概念,测试了哪些变量和别名能成功从父 Shell 传递下来。

此外,你还探索了控制和持久化 Shell 配置的方法。你使用了 set -o allexport 选项来自动导出随后定义的所有变量,简化了使变量对子进程可用的过程。为了确保你的自定义变量、别名和 Shell 选项在未来的所有终端会话中都可用,你学习了如何将这些配置添加到 .bashrc(或 .zshrc)启动文件中,从而使你的环境定制永久生效。