当前位置: 首页 > 科技观察

Bash环境变量的那些事

时间:2023-03-13 14:33:02 科技观察

初学者可以在本教程中了解环境变量。Bash变量,尤其是讨厌的环境变量,是一个老生常谈的话题。我们也应该对它有一个详细的了解,这样才能为我们所用。现在打开终端,让我们开始吧。环境变量HOME(LCTT译注:双关语)不仅是脱帽休憩的地方,也是Linux中的一个变量。它是当前用户的主目录的路径:echo$HOME上面的命令将显示当前用户的主目录。目录路径,通常在/home/<您的用户名>下。顾名思义,变量的值可以根据上下文改变。其实Linux系统中每个用户的HOME变量都是不一样的。当然,你也可以自己修改HOME变量的值:HOME=/home/<你的用户名>/Documents上面的命令会将HOME变量设置为你的Documents目录。需要注意三点:=号和它两边的内容之间不能有空格。空格在shell中有特殊的含义,不能在任何地方任意加空格。如果需要给变量赋值,直接使用变量名即可。但如果需要读取或使用变量的值,则需要在变量前加一个$符号。更改HOME变量有些冒险。有很多程序依赖于HOME变量,更改HOME变量可能会导致一些不可预知的结果。例如,如上更改HOME变量,然后执行不带任何参数的cd命令,正常情况下会跳转到用户的主目录,但此时会跳转到指定的HOME变量下目录。上面第3点中环境变量的改变是不持久的。终端关闭再打开,或者新建终端后,echo$HOME命令的输出仍然是初始值,而不是重新自定义的值。在讨论如何永久改变一个环境变量之前,我们先来看看另一个比较重要的环境变量。PATH变量在PATH变量中存放了一系列的目录,是可执行程序所在的目录。正是因为有PATH变量的存在,你才不需要知道应用程序安装在什么目录下,而shell却可以正确的找到这些应用程序。如果查看PATH变量的值,它可能如下所示:$echo$PATH/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin每两个目录之间用冒号隔开:.如果应用程序的目录不在PATH变量中,则需要声明应用程序的目录,以便shell在运行时能够找到它。/home/<用户名>/bin/my_program.sh比如上面的命令会执行当前用户bin/目录下的my_program.sh文件。有一个普遍的问题:如果不想把系统的bin/目录弄乱,又不想自己的文件被别人运行,又不想每次都必须输入完整路径当你运行它时,你可以在你的主目录中创建一个单独的bin/目录:mkdir$HOME/bin然后将这个目录添加到PATH变量中:PATH=$PATH:$HOME/bin然后/home/<用户名>/bin/目录将出现在PATH变量中。但如前所述,此更改只会在当前shell中生效。一旦当前shell关闭,环境变量的值就会恢复到原来的状态。如果想让修改对当前用户继续生效,不能直接在shell中执行相应的修改。相反,您应该将这些更改写入一个文件中,该文件将在您每次启动shell时运行。该文件是当前用户主目录中的.bashrc文件。文件名前面的点表示这是一个隐藏文件,普通的ls命令是不会显示这个文件的,但是只要在ls命令中加上-a参数就可以看到这个文件。您可以使用文本编辑器打开.bashrc文件,例如kate、gedit、nano或vim(但不是LibreOfficeWriter,它是一个文字处理器,与以前的文本编辑器完全不同)。打开.bashrc文件后,会看到里面放置了一些shell命令,用于为当前用户设置环境。在文件末尾添加一个新行并输入以下内容:exportPATH=$PATH:$HOME/bin保存并关闭.bashrc文件,您应该会看到export语句的效果。执行如下命令使修改立即生效:source.bashrc刚才执行的source命令使.bashrc文件在当前shell中立即生效,对后面打开的shell也有效。所以另一种等效的方法是退出并重新进入shell,但是这样太麻烦了。现在,你的shell可以自动找到/home//bin/下的程序,你不需要写出完整的程序路径来执行这个目录下的程序。自定义变量当然,您也可以定义自己的变量。我们刚才看到的变量名都是大写的。其实变量名的定义是比较灵活的。定义一个新变量的过程非常直观,直接赋值即可:new_variable="Hello"然后可以通过以下方式读取定义变量的值:echo$new_variable程序的正常工作离不开各种变量,比如把一个选项设置为on,或者让程序找到需要的代码库,就需要用到变量。在bash中运行程序时,会生成一个子shell。这个子shell与执行原始程序的父shell并不完全相同。它只是继承父shell的部分内容,默认不继承父shell中的变量。因为默认情况下变量是局部的,所以出于安全原因,一个shell的局部变量不能被另一个shell读取,即使是子shell也不能。这是一个例子。先定义一个变量:robots="R2D2&C3PO"然后执行:bashnow在bashshell中创建一个子shell。执行这条命令,看看是否还能读取刚刚定义的变量:echo$robots你会发现无法读取。仍然在这个子shell中,为robots变量分配一个不同的值:robots="Thesearen'ttheonesyouarelookingfor"再读一遍:$echo$robotsThesearen'ttheoneyouarelookingfor退出这个子shell:exit然后查看robots变量的值:$echo$robotsR2D2&C3P0这个特性可以有效避免配置过程中的混乱,同时也会带来一个问题:如果程序中需要设置变量,但是由于子shellshell无法正常访问这个变量的原因,如何解决?这时候就需要用到export了。重复刚才的过程,不过这次不是通过robots="R2D2&C3PO"设置变量,而是使用export命令:exportrobots="R2D2&C3PO"现在你会发现进入子shell后,robots变量的值of仍然是最初分配的值。需要注意的是,虽然子shell会继承通过export导出的变量,但是如果在子shell中重新赋值该变量,并不会影响父shell中对应的变量。如果想查看通过export导出的所有变量,可以执行以下命令:export-p自定义变量会显示在这个列表的末尾。这个列表还有一些常用的变量:比如USER的值为当前用户的用户名,PWD的值为当前用户当前所在的目录,OLDPWD的值为上次访问的目录当前用户的。所以如果你执行:cd-,你会切换到上次访问的目录,因为cd命令读取的是OLDPWD变量的值。您还可以使用env命令查看所有环境变量。如果你想unexport一个变量,可以加-n参数:export-nrobots接下来了解环境变量的知识,你已经到了可能对自己和他人造成危险的程度,接下来需要了解如何使用Alias让环境更安全、更友好来保护自己。