013 环境变量

013 环境变量
小米里的大麦环境变量
1. 什么是环境变量?
环境变量(Environment Variables)是操作系统中用于指定系统运行环境参数的一组动态键值对。每个环境变量由一个 名称(键) 和一个 值 组成,用于存储应用程序或系统需要访问的配置信息。例如:
- 名称:
PATH
- 值:
/usr/bin:/usr/local/bin
环境变量的作用类似于操作系统的“配置开关”,可以影响程序的运行行为、路径搜索、资源访问等。
1. 环境变量的分类
根据作用范围和修改权限,环境变量可分为两类:
1. 用户环境变量(User Variables)
- 作用范围:仅对当前用户生效。
- 用途:存储用户个性化配置(如用户专属的软件路径)。
2. 系统环境变量(System Variables)
- 作用范围:对所有用户和系统进程生效。
- 用途:存储全局配置(如系统工具路径、公共依赖库路径)。
3. 临时环境变量
- 作用:仅在当前终端会话或子进程中有效。
2. 和环境变量相关的命令
echo
:显示某个环境变量值export
:设置一个新的环境变量env
:显示所有环境变量unset
: 清除环境变量set
:显示本地定义的 shell 变量和环境变量
2. 常见环境变量及用途
变量名 | 作用 | 示例值 |
---|---|---|
PATH | 执行文件的查找的路径,目录与目录中间用 : 分隔。注意:文件查找是按 PATH 变量内的目录来查询的,所以,目录顺序很重要 |
/usr/bin:/usr/local/bin |
HOME | 当前用户的家目录(根目录) | /home/user |
USER | 当前用户名 | user |
SHELL | 告知我们目前这个环境使用的 SHELL 是哪个程序?默认 Shell 程序路径 | /bin/bash (Linux 默认使用) |
LANG | 系统语言和字符编码 | en_US.UTF-8 |
PWD | 当前工作目录 | /home/user/projects |
还有 自定义变量: 你可以定义自己的变量来影响程序行为。示例:MY_VAR=123
[!CAUTION]
自定义变量和本地变量在概念上有些相似,但它们并不完全相同。
- 自定义变量:手动创建的变量,默认是 本地变量。
- 本地变量:默认不使用
export
,只在当前 Shell 生效,子进程无法访问。- 环境变量:通过
export
声明,子进程也能访问。✅ 判断标准: 是否用
export
导出,决定了变量是本地的还是环境的。
自定义变量:
- 定义方式: 直接赋值,或者使用
export
命令声明。- 作用范围: 根据是否使用
export
,它可以是 本地变量 或者 环境变量。- 示例:
1
2 MY_VAR="Hello World" # 定义自定义变量
echo $MY_VAR # 输出:Hello World本地变量(Local Variable):
- 定义方式: 在当前 Shell 会话中赋值,不使用
export
。- 作用范围: 仅在 当前 Shell 会话 内有效,不会被子进程继承。
- 示例:
1
2
3 LOCAL_VAR="I am local"
bash # 打开新的子 Shell
echo $LOCAL_VAR # 无输出,子 Shell 无法访问父 Shell 的本地变量环境变量(Environment Variable):
- 定义方式: 使用
export
命令导出。- 作用范围: 在 当前 Shell 以及所有 子进程 中都可用。
- 示例:
1
2
3 export ENV_VAR="I am environment"
bash # 打开新的子 Shell
echo $ENV_VAR # 输出:I am environment
3. 查看环境变量
- 查看单个变量
1 | echo $NAME //NAME为待查看的环境变量名称,例如:echo $PATH |
- 查看所有环境变量
1 | printenv # 或 env,输出一模一样 |
4. 设置环境变量
1. 为什么 ls
命令可以直接执行,而我们自己的可执行程序需要带上路径(如 ./
)来执行的问题?
原因:PATH
。 它是一个环境变量,指定了一个目录列表,系统会在这些目录中搜索用户输入的命令。当你在终端中输入一个命令(例如 ls
),系统会按照 PATH
中列出的顺序查找该命令,并执行找到的第一个匹配项。像 ls
这样的命令之所以可以不带路径直接执行,是因为它们所在的目录(通常是 /bin
或 /usr/bin
等)被包含在了系统的 PATH
环境变量中。因此,当你输入 ls
时,系统能够在指定的目录中找到并执行这个命令。
2. 我们自己生成的可执行程序为什么不能直接执行?
当我们创建了自己的可执行程序并尝试在终端运行时,默认情况下当前工作目录(即 .
代表的目录)通常不会包含在 PATH
环境变量中。这说明:当我们在终端输入自己程序的名字时,系统不会自动在当前目录下查找该程序。因此,我们需要使用 ./
前缀来明确指出要执行的是当前目录下的程序。
3. 如何让自定义的可执行程序无需带路径就能直接运行?
要让自定义的可执行程序无需带路径就能直接运行,你需要将它所在的目录添加到 环境变量 PATH
中。这样,当你在命令行中输入程序名时,系统会在 PATH
指定的目录中查找该可执行程序。以下是详细步骤:
1. 临时生效(仅当前终端有效)
1 | # 假设程序放在 /home/user/myprogram/ 目录下 |
测试验证:
1 | echo $PATH # 查看 PATH 是否包含目录 |
取消临时设置:临时添加的路径在会话结束后就会丢失。 如果想手动取消,使用 unset
命令:
1 | unset PATH # 或者将 PATH 恢复为原始值 |
2. 永久生效(对所有终端和子进程生效)
如果希望即使重启终端或计算机后仍然有效,可以将 export
命令添加到用户的启动文件中(如 .bashrc
、.bash_profile
或 .zshrc
等),这样每次打开终端时就会自动设置。
根据自己使用的 Shell 选择配置文件:
- Bash:
~/.bashrc
或~/.bash_profile
- Zsh:
~/.zshrc
[!NOTE]
简单解释一下:
Bash 是最常见的默认 shell,适合日常使用和脚本编写。
Zsh 是更强大、功能丰富的 shell,特别适合喜欢定制和使用插件的用户。
Xshell 作为终端模拟器,可以连接到 Linux 服务器,使用的 shell 是由服务器设置的,可以是 Bash 或 Zsh。
可以通过以下命令来查看当前使用的是哪个 shell:
1 echo $SHELL
- 如果返回的结果是
/bin/bash
,那说明你使用的是 Bash。- 如果返回的结果是
/bin/zsh
,那说明你使用的是 Zsh。
这里以我的 Bash
为例:
1 | vim ~/.bashrc |
在文件末尾添加这一行:
1 | export PATH=$PATH:/home/user/myprogram # 或者export PATH="$PATH:/home/user/myprograms" |
保存并退出编辑器,使配置生效:
1 | source ~/.bashrc # 或 source ~/.bash_profile,重新加载配置文件 |
测试:
1 | echo $PATH # 查看 PATH 变量,确认是否添加成功 |
3. 取消永久设置:
如果不再需要这个路径,可以编辑 .bashrc
或 .bash_profile
,删除那一行,然后重新执行 source
命令:
1 | vim ~/.bashrc # 删除 export PATH 行 |
5. 注意事项
安全性:
- 不要将当前目录
.
添加到PATH
(如export PATH=".:$PATH"
),这会允许当前目录下的任意程序被执行,存在安全风险。
- 不要将当前目录
路径优先级:
PATH
中目录的顺序决定查找优先级。例如:1
2export PATH="/my_dir:$PATH" # 优先搜索 /my_dir
export PATH="$PATH:/my_dir" # 最后搜索 /my_dir
多用户系统:
- 若需所有用户生效,可修改系统级配置文件(如
/etc/profile
或/etc/environment
),但需 root 权限。
- 若需所有用户生效,可修改系统级配置文件(如
误删了
PATH
变量怎么办?- 恢复默认
PATH
:
1
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- 恢复默认
6. 理解 HOME
环境变量
在 Linux 系统中,每个用户都有一个专属的工作目录,称为 主目录(Home Directory)。这个目录是用户登录系统后的默认位置,用户可以在其中存储个人文件、配置文件等。
HOME
是一个环境变量,存储了当前用户的主目录路径。- 每当登录到系统时,系统会分配一个 主目录,通常位于
/home/用户名
,例如,假设我的用户名是hcc
,那么我的主目录就是/home/hcc
。
在终端中,使用命令 echo $HOME
,系统会返回当前登录用户的主目录路径:
1. 主目录的作用
- 默认工作目录:
- 当登录到系统时,通常会自动进入主目录。这个目录是我们个人的空间,通常可以放置配置文件、文档、程序文件等。
- 保存用户的配置文件:
- 在主目录下,用户的配置文件(如
.bashrc
、.zshrc
等)存放在那里。这样,无论我们从哪个位置打开终端,都会读取这些文件的配置。
- 在主目录下,用户的配置文件(如
- 用户的私有空间:
- 每个用户在系统中都有自己的主目录,确保用户数据和配置是隔离的,不会互相干扰。
2. HOME
和 ~
的关系
~
是 HOME
变量的简写,表示当前用户的主目录。可以在命令行中使用 ~
来快速访问主目录。例如:
1 | cd ~ # 等同于 cd $HOME,切换到当前用户的主目录 |
这样,无论处在哪个目录下,~
都会自动被替换为我们的主目录路径。
每个用户的工作目录(主目录)都是独立且唯一的。 即使是同一台机器上的多个用户,它们的主目录路径也不同,这样可以保证用户数据的隔离和安全。
7. 环境变量的组织方式
8. 如何通过代码获取环境变量
1. 通过命令行的第三个参数获取环境变量
要在 C 语言中获取和操作环境变量,我们可以通过以下几种方式:
- 通过命令行第三个参数(
env[]
)获取环境变量:这是通过命令行启动程序时传递给main()
函数的第三个参数。 - 通过第三方变量
environ
获取环境变量:environ
是一个外部变量,包含了环境变量的列表。 - 通过系统调用获取或设置环境变量:可以使用
getenv()
来获取环境变量的值,使用putenv()
来设置环境变量。
main()
函数的第三个参数 char *env[]
是一个指向环境变量的字符串数组,数组中的每个元素都是一个格式为 KEY=VALUE
的字符串。
示例代码:
1 |
|
输出:
2. 通过 environ
获取环境变量
environ
是一个外部全局变量,包含当前环境变量的数组,它是 char **environ
类型。
示例代码:
1 |
|
输出:
3. 使用 getenv()
和 putenv()
系统调用获取和设置环境变量
常用 getenv
和 putenv
函数来访问特定的环境变量。
getenv()
:获取指定环境变量的值。putenv()
:设置一个新的环境变量或修改已有环境变量的值。
示例:获取和设置环境变量
1 |
|
解释和输出:
getenv()
:获取环境变量的值,如果变量存在,返回该变量的值;如果不存在,返回NULL
。putenv()
:设置环境变量,参数是一个格式为KEY=VALUE
的字符串。putenv
会修改当前进程的环境变量,不需要重新调用setenv()
或unsetenv()
来更新。
9. 环境变量通常是具有全局属性的
获取环境变量: 在程序中,通过
getenv("MYENV")
获取环境变量MYENV
的值。如果该变量存在,程序会打印出它的值。示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
char *env = getenv("MYENV"); // 获取环境变量
if (env)
{
printf("%s\n", env); // 如果环境变量存在,则打印
}
return 0;
}没有结果: 程序首次运行时,显示没有结果,表示
MYENV
环境变量并未被设置。设置环境变量: 通过执行
export MYENV="hello world"
命令,设置环境变量MYENV
,并再次运行程序,结果成功打印了hello world
,表示环境变量是可以在当前进程中继承并使用的。
注意: 如果我们直接在命令行中设置 MYENV="helloworld"
而不使用 export
,在我们的 C 程序中是无法获取到这个环境变量的。
解释:
export
是用来 将环境变量传递给子进程 的命令。如果在命令行中仅设置了MYENV="helloworld"
,这个环境变量只在当前 shell 会话中有效,但不会影响到子进程或其他程序。- 使用
export
后,环境变量会被子进程继承并传递,这就是为什么在使用export
设置了MYENV
后,程序能够成功读取到该变量的原因。