如何在Linux上的Bash中设置环境变量

时间:2020-01-09 10:39:42  来源:igfitidea点击:

Linux上有多种类型的环境变量。了解如何查看它们,为本地和远程登录创建它们,并使它们在重启后不受影响。

环境变量如何工作

启动终端窗口并其中运行shell程序时,将引用变量集合以确保正确配置shell程序。这些变量还确保终端窗口和shell程序可能需要参考的任何信息均可用。这些变量共同具有定义我们在终端窗口中找到的环境的设置,这些设置一直到命令提示符的外观。因此,自然地,它们被称为环境变量。

一些环境变量是系统范围的或者全局的。其他人在整个会话范围内,只能由我们看到。其他人则无法引用会话环境变量。在shell程序中定义了第三组环境变量。语言环境,时区和键盘设置,shell尝试查找命令时搜索的目录集以及默认编辑器都存储在shell环境变量中。

我们将向我们展示如何查看系统中存在的环境变量,并描述如何创建自己的环境变量。我们还将向我们展示如何使它们可用于子进程以及如何在重新启动后保持持久性。

环境与继承

当shell启动时,它将经历初始化阶段。至此,它读取定义shell环境的环境变量。

当从称为子进程的shell启动程序或者命令时,它将继承父进程的环境,但要当心!正如我们将看到的,我们可以创建不会添加到环境中的变量,这样子进程就不会继承它们。

如果子进程是一个shell程序,则该shell程序将从其自己的新鲜变量集进行初始化。因此,如果我们更改当前shell程序中的命令提示符,然后启动子shell程序,则该子shell程序将不会继承父级的修改后的命令提示符。

全局环境变量

按照惯例,环境变量使用大写名称,以下是一些全局环境变量,它们包含的值表示:

  • shell:打开终端窗口时将启动的shell的名称。在大多数Linux发行版中,除非我们将其更改为默认值,否则这将毫无用处。

  • 术语:终端窗口实际上是硬件终端的仿真,其中包含将要仿真的硬件终端的类型。

  • USER:使用系统的当前用户的用户名。

  • PWD:当前工作目录的路径。

  • OLDPWD:移至当前工作目录之前的目录。

  • LS_COLORS:ls突出显示不同文件类型使用的颜色代码列表。

  • 邮件:如果在Linux计算机上设置了"邮件"系统(默认情况下未设置),它将保存当前用户邮箱的路径。

  • PATH:Shell将搜索以查找命令可执行文件的目录列表。

  • LANG:语言,本地化和字符编码设置。

  • HOME:当前用户的主目录。

  • :下划线()环境变量保存最后键入的命令。

我们可以看到其中一些设置为使用比echo更复杂的东西,它将把值写入终端窗口。要查看环境变量持有的值,我们需要在其名称的开头添加一个美元符号($)。

一个不错的感觉是,我们可以使用制表符补全为我们填写环境变量名称。输入名称的几个字母,然后按Tab。变量的名称由shell程序完成。如果那没有发生,我们将需要再输入几个字母以将环境变量与其他命令以相同字母开头的名称区分开来:

echo $SHELL
echo $LANG
echo $HOME
echo $PWD

要创建自己的全局环境变量,请将其添加到/ etc / environment文件中。我们将需要使用sudo来编辑此文件:

sudo gedit /etc/environment

要添加环境变量,请输入其名称,等号(=)和我们想要环境变量保留的值。请勿在等号(=)前后放置空格。环境变量的名称可以包含字母,下划线(_)或者数字。但是,名称的第一个字符不能是数字。

如果值中有空格,请确保将整个值括在引号(")中。

保存文件,然后注销并再次登录。使用echo测试一个新变量是否存在并保存我们设置的值:

echo $WEBSITE

因为这是一个全局环境变量,并且所有人都可以使用,所以用户mary在下一次登录时可以引用该环境变量:

echo $WEBSITE

要一次查看所有环境变量,请输入printenv。有很多输出,因此将其通过" sort"传递到" less"是有意义的:

printenv | sort | less

环境变量的排序列表以less为我们显示。

我们可以通过grep通过输出查找与特定主题相关的环境变量。

printenv | grep GNOME

Shell环境变量

这些是bash中用于指示或者记录其行为和功能的一些shell环境变量。使用终端时,某些值会更新。例如,COLUMNS环境变量将被更新以反映我们可能对终端窗口的宽度所做的更改:

  • BASHOPTS:启动bash时使用的命令行选项。

  • BASH_VERSION:bash版本号,是由单词和数字组成的字符串。

  • BASH_VERSINFO:bash版本为数字。

  • 列:终端窗口的当前宽度。

  • DIRSTACK:已由pushd命令添加到目录堆栈中的目录。

  • HISTFILESIZE:"历史"文件中允许的最大行数。

  • HISTSIZE:内存中允许的" history"行数。

  • HOSTNAME:计算机的主机名。

  • IFS:内部字段分隔符用于分隔命令行上的输入。默认情况下,这是一个空格。

  • PS1:环境变量PS1包含主,默认和命令提示符的定义。可以在命令提示符的定义中包含一组称为转义序列的标记。它们代表诸如主机名和用户名,当前工作目录和时间之类的东西。

  • PS2:当命令跨越多行并且需要更多输入时,将显示辅助命令提示符。 " PS2"环境变量包含此辅助提示的定义,默认情况下,该提示大于号(>)。

  • shell:我们可以使用set选项设置shell选项。

  • UID:当前用户的用户标识。

让我们检查一下以下这些shell变量:

echo $BASH_VERSION
echo $HOSTNAME
echo $COLUMNS
echo $HISTFILESIZE
echo $UID

为了完整起见,以下是我们可以在命令提示符定义中使用的标记:

  • \ t:当前时间,格式为HH:MM:SS。

  • \ d:当前日期,表示为工作日,月份,日期。

  • \ n:换行符。

  • \ s:shell的名称。

  • \ W:当前工作目录的名称。

  • \ w:当前工作目录的路径。

  • \ u:登录人员的用户名。

  • \ h:计算机的主机名。

  • #:shell中的每个命令都有编号。这使我们可以在命令提示符下查看命令的编号。这与该命令在"历史记录"列表中的编号不同。

  • \ $:对于普通用户,将提示的最终字符设置为美元符号($),对于root用户,将其设置为井号(#)。这通过检查用户的UID起作用。如果为零,则用户为root。

我们可以在.bashrc文件中找到PS1环境变量的定义。

创建会话环境变量

要创建自己使用的环境变量,请将其添加到.bashrc文件的底部。如果我们想让环境变量可用于远程会话(例如SSH连接),则还需要将它们添加到.bash_profile文件中。

这两个文件的环境变量定义的格式相同。要将定义添加到.bash_profile文件中,请在yourhome目录中键入以下内容:

gedit .bashrc

我们添加了一个名为" INHERITED_VAR"的环境变量。请注意该行开头的单词export。

完成编辑后,保存并关闭文件。我们可以注销然后再次登录,或者可以使shell使用点命令(`)重新读取.bash_profile文件,如下所示:

. .bashrc

现在,让我们在命令行上创建一个环境变量:

LOCAL_VAR="This session only"

如果我们使用echo,我们可以看到两个环境变量都可以访问:

echo $LOCAL_VAR
echo $INHERITED_VAR

我们会注意到环境变量INHERITED_VAR的定义在行的开头带有单词export。这意味着环境变量将被当前shell的子进程继承。如果我们使用bash命令启动另一个,我们可以在子shell内再次检查两个变量:

bash
echo $LOCAL_VAR
echo $INHERITED_VAR

如我们所见,INHERITED_VAR在子shell中是可访问的,而LOCAL_VAR则不可。我们只是得到一个空白行。

尽管export将环境变量部分添加到子进程继承的环境中,但是INHERITED_VAR不是全局环境变量。例如,用户mary无法引用它:

echo $INHERITED_VAR

要关闭我们的子级" bash"会话,我们使用" exit":

exit

继承的环境也会影响脚本。这是一个简单的脚本,它将我们三个环境变量的值写入终端窗口:

#!/bin/bash

echo "WEBSITE" $WEBSITE
echo "LOCAL_VAR" $LOCAL_VAR
echo "INHERITED_VAR" $INHERITED_VAR

将该文件保存到名为" envtest.sh"的文件中,然后使用以下命令使其可执行:

chmod +x envtest.sh

运行脚本时,它可以访问三个环境变量中的两个:

./envtest.sh

该脚本可以查看" WEBSITE"全局环境变量和" INHERITED_VAR"导出环境变量。即使脚本在创建变量的同一shell中运行,它也无法访问LOCAL_VAR。

如果需要,可以从命令行导出环境变量。我们将对我们的LOCAL_VAR执行此操作,然后再次运行脚本:

export LOCAL_VAR
./envtest.sh

环境变量已添加到当前shell程序的环境中,因此它出现在脚本继承的环境中。该脚本也可以引用该环境变量。

远程连接

全局环境变量可用于远程登录会话,但是如果我们希望远程使用本地定义的环境变量,则必须将它们添加到.bash_profile文件中。我们可以在.bashrc和.bash_profile文件中设置相同的环境变量,并使用不同的值。例如,可以通过脚本进行选择,以便为本地或者远程使用系统的人员修改其行为。

(冒着混乱的风险,还有一个.profile文件。它也可以保存环境变量定义。但是,如果存在.bash_profile`文件,则不会读取.profile文件。因此,使用bash兼容的方式最安全的做法是使用.bash_profile文件。)

要编辑.bash_profile文件,我们将再次使用gedit

gedit .bash_profile

我们将使用相同的值添加相同的环境变量。

保存更改并关闭" gedit"。

在另一台计算机上,我们将与测试计算机建立" SSH"连接。

ssh [email protected]

建立连接后,我们将再次运行脚本:

./envtest.sh

作为远程登录初始化的一部分,已读取.bash_profile文件,并且我们和脚本均可访问INHERITED_VAR环境变量。

取消环境变量

要取消设置环境变量,请使用"取消设置"命令。如果我们取消设置全局环境变量" WEBSITE"和导出的环境变量" INHERITED_VAR",则它们将不再在命令行或者子进程中可用:

unset WEBSITE
unset INHERITED_VAR
./envtest.sh
echo $WEBSITE

需要注意的一点是,这只会在此会话中更改全局环境变量的可用性。同时登录的另一个人仍然可以访问该全局环境变量的实例。他的实例在登录过程中已初始化并从/ etc / environment文件中读取,并且独立于其他任何人的变量副本。

例如,用户mary仍然可以访问WEBSITE环境变量并读取其值,即使用户dave在其会话中未设置它:

echo $WEBSITE

环境控制

环境变量可用于让脚本和应用程序知道其行为。它们可用于存储设置或者少量数据。例如,脚本可以使用其他脚本可以引用的值填充环境,而不必将其写入文件。