环境变量理解

每次涉及到环境变量总是晕,用Chatgpt做个笔记吧~

一、简述

​ 环境变量是在计算机操作系统中用来存储信息的一种机制,通常被用来存储系统范围的配置信息或应用程序需要的配置信息。环境变量是在操作系统启动时设置的,可以在整个操作系统和其所运行的程序中使用。

​ 环境变量可以存储各种类型的信息,例如路径、用户名、计算机名称、语言设置等等。它们通常以键值对的形式存储,其中键是环境变量的名称,而值是与该键相关联的数据

​ 在安装一些软件时,需要设置环境变量是因为这些软件需要在操作系统中找到特定的程序或库文件来运行。环境变量可以提供这些程序或库文件的路径信息,使得软件能够正确地找到并使用它们。

例如,如果您要安装一个编程语言的开发环境,这个环境需要调用操作系统中的编译器和库文件来编译和运行代码。如果这些程序或库文件没有包含在该环境中,那么该编程环境将无法正常工作。通过设置环境变量,编程环境可以找到这些程序或库文件的位置,并将其添加到其搜索路径中。

另一个例子是当您安装一些常用的命令行工具时,这些工具可能需要在操作系统中使用,而不仅仅是在它们的安装目录下。例如,如果您安装了一个用于版本控制的工具,那么它可能需要访问您的用户配置文件,以便将其存储在正确的位置。通过设置环境变量,这些工具可以找到您的配置文件并正确地读写它们。

二、Linux下的环境变量

1. Linux的环境变量

​ Linux下,可以使用printenvenv显示环境变量:

image-20230624201049954

​ 要查询某一个环境比那辆,可以使用键值对来查询,比如使用 echo $USER:

image-20230624201245009

set用于储存一个 shell 环境中的变量和函数,它将输出当前 shell 中定义的所有变量和函数的列表,如下所示,如下所示,有很多变量和函数:

image-20230624203109668

image-20230624203151358

​ 比如说,上面显示的 BASH_ARGV,BASH_ARGV 是 Bash shell 中的一个特殊数组变量,用于存储传递给脚本或函数的位置参数(命令行参数)。当 BASH_ARGV 的值为 (),即空数组时,表示没有传递任何位置参数给脚本或函数。这意味着当前的脚本或函数没有接收到任何命令行参数。

​ 下面的函数也是在BASH环境中所定义的函数,可以被BASH程序调用。

2.PATH变量

​ 在环境变量中,PATH变量是一个非常重要的变量,它决定了操作系统如何查找可执行文件。PATH变量包含一组用冒号分隔的路径列表,每个路径指向一个包含可执行文件的目录。当在终端中输入一个命令时,操作系统会按照PATH变量中指定的顺序依次搜索这些目录,直到找到对应的可执行文件为止。

​ 例如,如果PATH变量的值为/usr/local/bin:/usr/bin:/bin,当在终端中输入一个命令时,操作系统会先搜索/usr/local/bin目录,如果找到对应的可执行文件,则执行该文件;如果没有找到,则接着搜索/usr/bin目录,再搜索/bin目录,以此类推,直到找到对应的可执行文件或搜索完所有路径。

image-20230625121026661

​ PATH中,不同目录用:相互连接

​ 环境变量 PATH 是用于指定可执行文件的搜索路径,它不会直接影响你对其他类型文件(如纯文本文件)的访问。虽然你可以将目录 /tmp/try/ 添加到 PATH 变量中,但这只影响系统在搜索可执行文件时的查找路径,并不会使其他类型的文件(如纯文本文件)在任意目录都可访问。

3.安装软件

​ 在Linux中,一般情况下,通过包管理器(如apt)安装的软件都被安装在系统预定义的目录中,这些目录一般都已经添加到了PATH变量中,因此可以直接在终端中执行该软件的命令。如果你安装了vim,你可以在终端中输入以下命令来确定vim的位置:

image-20230625121541901

​ 其中,前者对应的是通过which指令直接寻找vim可执行文件的位置;

​ 后者whereis主要用于尽可能多的寻找二进制文件、源文件和手册文件的位置,如上所示,找到了vim的三个版本的二进制文件,其中vim.1.gz 是vim的手册文件,可以通过man vim查看。

​ 在Linux系统中,一个软件包通常由多个文件组成,例如可执行文件、库文件、配置文件等等。在将软件包安装到系统中时,这些文件会被分别放置到不同的目录中。一般来说,可执行文件通常被放置在/usr/bin/目录下,库文件通常被放置在/usr/lib/目录下,配置文件通常被放置在/etc/目录下。

三、命令

1.export命令

​ export命令用于修改一条环境变量,通过语法:

1
export [-n] [-f] [name[=word]] ...
 可以设置键为name的环境变量,值为word。

​ 如果你想手动将一个目录添加到PATH环境变量中,可以使用以下命令:

1
export PATH=$PATH:/path/to/your/directory

​ 其中/path/to/your/directory是你想要添加的目录路径。(之所以要写$PATH:/path/to/your/directory而不是直接写/path/to/your/directory,是因为要通过$PATH保留原来的环境变量,相当于PATH = PATH + “/path/to/your/directory”)

​ 这个命令会将当前的PATH环境变量值赋给PATH变量,然后将目录路径添加到PATH变量的末尾,这样你就可以在终端中执行该目录中的可执行文件了。

​ 需要注意的是,这个修改只会在当前的终端会话中生效。如果你希望永久将该目录添加到PATH环境变量中,可以将上述命令添加到你的shell配置文件中(如.bashrc.zshrc等),这样每次打开终端时都会自动执行该命令,从而保证PATH环境变量的修改可以永久生效。

2. 文件.bashrc与/etc/environment

​ 在Linux系统中,/etc/environment文件是一个系统级别的配置文件,用于设置全局的环境变量。该文件中存储的环境变量可以被所有的用户和进程所访问,无论是在交互式终端中还是在后台进程中都可以生效。

/etc/environment文件是一个纯文本文件,其中每一行都是一个以KEY=VALUE形式表示的环境变量,例如:

1
2
codePATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
LANG="en_US.UTF-8"

​ 当系统启动时,会自动读取/etc/environment文件中的环境变量,并将其设置为全局的环境变量。这些变量可以在任何地方使用,包括shell会话、交互式终端和后台进程等。需要注意的是,/etc/environment文件中的环境变量是全局生效的,如果需要设置用户级别的环境变量,应该将其添加到用户的shell配置文件中(例如.bashrc.zshrc等)。实际上,其中的内容并不多:

image-20230625130946555

.bashrc是Bash shell的一个配置文件,用于设置用户级别的环境变量和shell选项。它位于用户的主目录下,是一个隐藏文件(以.开头),因此默认情况下不会在文件管理器中显示。

​ 当用户登录到系统后,在打开一个新的终端窗口时,Bash shell会自动读取并执行.bashrc文件中的命令。这些命令可以设置一些常用的别名、函数、环境变量和shell选项,使得用户可以更方便地使用shell。

例如,.bashrc文件中常见的一些配置包括:

  • 设置PATH环境变量,以便在终端窗口中能够方便地执行用户安装的程序;
  • 定义一些常用的别名,以简化命令的输入;
  • 定义一些常用的shell函数,以方便地完成一些重复的任务;
  • 设置一些shell选项,如历史命令数目、命令行提示符等。

​ 需要注意的是,.bashrc文件只对Bash shell生效,如果用户使用的是其他shell,如Zsh、Fish等,则需要对应修改相应的配置文件(比如kali修改bashrc就是没用的,因为其默认的shell是zsh)。如下所示:

image-20230625131113322

​ 因此,.bashrc中实际是一大堆命令,这些命令每次打开一个bash就被执行,然后成功设置一大堆环境变量,也就是上文中env命令所显示的。也就是说,**.bashrc本身实际就是一个shell文件**,用于为命令行初始化环境变量。

​ 综上,当一个用户登录到系统时,首先会读取/etc/environment中的全局环境变量,并将其设置为全局的环境变量。然后,当用户打开一个新的终端窗口并登录到shell时,会读取.bashrc中的用户级别环境变量,并将其添加到全局环境变量中。

​ 以PATH这个重要的环境变量为例,当用户打开一个新的终端窗口并登录到shell时,会先读取全局的/etc/environment文件,并将其中的PATH变量设置为全局的环境变量;然后读取用户的.bashrc文件,并将其中的PATH变量添加到全局的环境变量中,形成最终的PATH变量。在此之后,用户可以在命令行中使用PATH变量中包含的路径中的可执行文件。

3.永久添加环境变量

要永久添加一个环境变量,通常需要将它添加到以下文件之一中:

  1. /etc/environment:这是一个全局环境变量文件,适用于所有用户。您需要以超级用户身份编辑此文件,将新变量添加到末尾,如下所示:

    1
    VAR=value
  2. /etc/profile:这是一个全局shell配置文件,可以在启动时加载。您需要以超级用户身份编辑此文件,在文件末尾添加以下行:

    1
    export VAR=value
  3. ~/.bashrc:这是当前用户的bash shell配置文件,可以在启动bash时加载。您可以将以下行添加到文件末尾:

    1
    export VAR=value

    如果您使用的是zsh shell,则需要将上述行添加到~/.zshrc文件末尾。

​ 请注意,如果您在多个文件中设置同一个变量,则后面设置的变量会覆盖之前的设置。另外,如果您添加了新的环境变量,需要注销并重新登录才能使新的变量生效,或者可以使用source命令立即使其生效,例如:

1
$ source ~/.bashrc

4. source命令

source命令用于在当前shell中执行指定文件中的命令。具体来说,source命令会读取指定文件中的命令,并在当前shell中直接执行这些命令,而不是在新的子shell中执行。

​ 通常,source命令用于加载shell配置文件或设置环境变量。例如,如果您在.bashrc文件中添加了新的环境变量,可以使用以下命令使其生效:

1
$ source ~/.bashrc

​ 这样,当前shell会重新加载.bashrc文件,并执行其中的所有命令,包括设置新的环境变量。

​ 需要注意的是,source命令也可以用.符号代替,它们的作用完全相同。例如,以下两个命令具有相同的效果:

1
2
$ source myfile.sh
$ . myfile.sh

​ 使用source.命令可以使您在不启动新的shell进程的情况下立即加载和执行指定文件中的命令。

​ 根据我的理解来说,Source命令是一点用没有的,直接使用. ~/.bashrc,也许是因为英文字母比较好理解吧。

四、实际应用

​ 项目中,在本地对LLVM代码进行了编译,但是直接使用LLVM命令,或引入LLVM库都是不行的,因为没有添加环境变量,然后,项目提供如下脚本:

image-20230625142822107

​ 通过执行这个脚本source env.sh,即,./env.sh,可通过export临时添加环境变量,即定义环境变量LLVM_ROOT文件夹,并将其下bin目录中的内容添加到环境变量。然而每次打开新的命令行都要重新执行一遍很麻烦,因此,可以直接修改.bashrc,而后重新启动一个终端即可:

image-20230625143810111

添加成功。

image-20230625144202590