当您在 bash shell 中运行时,有许多东西构成了您的环境,比如提示表单、主目录、工作目录、shell 名称、打开的文件、定义的函数,等等。您的环境包括许多由 bash 或您设置的变量。bash shell 还允许您拥有 shell 变量,可以将其导出 到您的环境,以供运行在 shell 中的其他进程或衍生自当前 shell 的其他 shell 使用。
环境变量和 shell 变量都具有一个名称。可以通过在名称前面加一个 “$” 前缀来引用变量的值。表 2 显示了您将经常遇到的一些 bash 环境变量。
表 2. 一些常见 bash 环境变量
名称 作用
USER 已登录用户的名称
UID 用数字表示的已登录用户的用户 id
HOME 用户的主目录
PWD 当前的工作目录
SHELL shell 的名称
$ 进程 id(或运行的 bash shell 或其他进程的 PID
PPID 启动当前进程的进程的 id(即父进程的 id)
? 上一个命令的退出代码
清单 7 展示了这些常见 bash 变量的内容。
清单 7. 环境和 shell 变量
[ian@echidna ~]$ echo $USER $UID ian 500 [ian@echidna ~]$ echo $SHELL $HOME $PWD /bin/bash /home/ian /home/ian [ian@echidna ~]$ (exit 0);echo $?;(exit 4);echo $? 0 4 [ian@echidna ~]$ echo $$ $PPID 2559 2558
没有使用 bash?
bash shell 是大多数 Linux 发行版上的默认 shell。如果您没有运行在 bash shell 下,可能需要通过以下几种方式之一来实际使用这个 bash shell。
使用chsh -s /bin/bash
命令来修改您的默认 shell。默认设置将在下一次登录时生效。 使用
su - $USER -s /bin/bash
命令创建另一个进程作为当前 shell 的子 shell。新的进程将为使用 bash 的登录 shell。 使用默认的 bash shell 创建一个 id,以用于 LPI 考试准备。
通过输入一个名称并在其后紧接着输入一个等号 (=),您将创建或设置 一个 shell 变量。如果变量存在的话,可以修改它来分配新值。变量需要区分大小写,因此 var1 和 VAR1 表示两个不同的变量。一般来讲,变量(特别是导出的变量)都是大写的,但是这并不是强制要求。理论上来说,$$ 和 $? 属于 shell 参数 而不是变量。它们只能被引用;您不能为它们分配值。
在创建 shell 变量时,您通常需要将其导出 到环境中,这样才可以用于从这个 shell 中启动的其他进程。导出的变量不能 用于父 shell。您使用 export 命令导出变量名。作为 bash 中的一种简单方法,您可以在一个步骤中同时分配值并导出变量。
为了演示分配和导出,让我们在 bash shell 中运行 bash 命令,然后从新的 bash shell 中运行 Korn shell (ksh)。我们将使用 ps 命令显示有关当前运行命令的信息。我们将在本系列的另一篇文章中了解有关 ps 的更多信息。
清单 8. 更多环境和 shell 变量
[ian@echidna ~]$ ps -p $$ -o "pid ppid cmd" PID PPID CMD 2559 2558 -bash [ian@echidna ~]$ bash [ian@echidna ~]$ ps -p $$ -o "pid ppid cmd" PID PPID CMD 2811 2559 bash [ian@echidna ~]$ VAR1=var1 [ian@echidna ~]$ VAR2=var2 [ian@echidna ~]$ export VAR2 [ian@echidna ~]$ export VAR3=var3 [ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 var1 var2 var3 [ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 $SHELL var1 var2 var3 /bin/bash [ian@echidna ~]$ ksh $ ps -p $$ -o "pid ppid cmd" PID PPID CMD 2840 2811 ksh $ export VAR4=var4 $ echo $VAR1 $VAR2 $VAR3 $VAR4 $SHELL var2 var3 var4 /bin/bash $ exit [ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 $VAR4 $SHELL var1 var2 var3 /bin/bash [ian@echidna ~]$ ps -p $$ -o "pid ppid cmd" PID PPID CMD 2811 2559 bash [ian@echidna ~]$ exit exit [ian@echidna ~]$ ps -p $$ -o "pid ppid cmd" PID PPID CMD 2559 2558 -bash [ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 $VAR4 $SHELL /bin/bash
注意:
在序列的开始部分,bash shell 具有 PID 30576。 第二个 bash shell 的 PID 为 16353,它的父 shell 的 PID 为 30576,即最初的 bash shell。 我们在第二个 bash shell 中创建了 VAR1、VAR2 和 VAR3 变量,但是只导出了 VAR2 和 VAR3。 在 Korn shell 中,我们创建了 VAR4。echo 命令仅显示 VAR2、VAR3 和 VAR4 的值,确认 VAR1 没有被导出。当您看到即使在提示改变的情况下,SHELL 变量的值仍然未变,您是否感到吃惊?您不能始终依赖 SHELL 来获得当前正在运行的 shell,但是 ps 命令的确提供了实际的命令。注意,ps 将一个连字符 (-) 放到第一个 bash shell 的前面,表示这是一个登录 shell。 回到第二个 bash shell 中,我们可以看到 VAR1、VAR2 和 VAR3。 最后,我们返回到原始 shel,其中并未包含我们的新变量。前面有关引用的讨论提到您可以使用单引号或双引号。这两者之间有一个重要的区别。shell 将扩展使用双引号 ($quot;) 括起的 shell 变量,而在使用单引号 (') 时不会扩展。在前面的示例中,我们在 shell 中启动了另一个 shell 并且获得一个新的进程 id。使用 -c 选项,您可以将一个命令传递给另一个 shell,后者将执行命令并返回。如果传递一个使用引号括起的字符串作为命令,那么外部 shell 将去掉引号并传递字符串。如果使用的是双引号,那么将在传递字符串之前执行变量扩展,因此产生的结果可能与您期望的不同。shell 和命令将在另一个进程中运行,因此将使用另一个 PID。清单 9 解释了这些概念。顶级 bash shell 的 PID 被突出显示。