清单 11 展示了 shell 处理变量和环境的各种行为。虽然本文主要关注 bash,但是您最好知道并非所有 shell 都具有相同的行为。此外,shell 将根据它们是否是登录 shell 来做出不同的行为。目前,我们将登录 shell 定义为您在登录到一个系统时获得的 shell;如果愿意的话,您可以启动其他 shell 来作为登录 shell。上面使用 env -i 启动的三个 shell 并不是登录 shell。尝试向 shell 命令本身传递 -l 选项,看看使用登录 shell 会出现什么结果。
现在让我们来尝试在这些非登录 shell 中显示 SHELL 变量的值:
当 bash 启动后,它将设置 SHELL 变量,但是并不会自动将变量导出到环境。 当 ksh 启动后,它不会设置 SHELL 变量。然而,引用一个未定义的环境变量相当于引用一个具有空值的变量。 当 tcsh 启动后,它并不会设置 SHELL 变量。在这种情况下,默认的行为不同于 ksh (以及 bash),因为在我们尝试使用并不存在的变量时,将报告一个错误。您可以使用 unset 命令来取消一个变量并从 shell 变量列表中移除它。如果变量被导出到环境中,那么将从环境中删除这个变量。可以使用 set 命令来对 bash(或其他 shell)的行为进行许多控制。Set 是一个内置在 shell 中的功能,因此各种选项都是特定于 shell 的。在 bash 中,-u 选项将使 bash 报告一个有关未定义变量的错误,而不是将它们作为已定义的空变量。可以使用 - 对 set 启用各种选项,并使用 + 来关闭选项。可以使用 echo $- 显示当前设置的选项。
清单 12. Unset 和 set
[ian@echidna ~]$ echo $- himBH [ian@echidna ~]$ echo $VAR1 [ian@echidna ~]$ set -u;echo $- himuBH [ian@echidna ~]$ echo $VAR1 -bash: VAR1: unbound variable [ian@echidna ~]$ VAR1=v1 [ian@echidna ~]$ VAR1=v1;echo $VAR1 v1 [ian@echidna ~]$ unset VAR1;echo $VAR1 -bash: VAR1: unbound variable [ian@echidna ~]$ set +u;echo $VAR1;echo $- himBH
如果使用不包含任何选项的 set 命令,它将显示所有 shell 变量及变量值(如果有的话)。还有另一个命令 declare,可以用它创建、导出和现实 shell 变量的值。可以通过手册页研究其他各种 set 选项和 declare 命令。我们稍后将讨论 。
最后将要介绍的命令是 exec。可以使用 exec 命令来运行将替换当前 shell 的另一个程序。启动 13 启动了一个子 bash shell 并使用 exec 来将它替换为一个 Korn shell。从 Korn shell 退出后,您将回到初始的 bash shell(本例为 PID 2852)中。
清单 13. 使用 exec
[ian@echidna ~]$ echo $$ 2852 [ian@echidna ~]$ bash [ian@echidna ~]$ echo $$ 5114 [ian@echidna ~]$ exec ksh $ echo $$ 5114 $ exit [ian@echidna ~]$ echo $$ 2852