环境变量
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,它可以是 本地变量 或者 环境变量。- 示例:
MY_VAR="Hello World" # 定义自定义变量 echo $MY_VAR # 输出:Hello World本地变量(Local Variable):
- 定义方式: 在当前 Shell 会话中赋值,不使用
export。- 作用范围: 仅在 当前 Shell 会话 内有效,不会被子进程继承。
- 示例:
LOCAL_VAR="I am local" bash # 打开新的子 Shell echo $LOCAL_VAR # 无输出,子 Shell 无法访问父 Shell 的本地变量环境变量(Environment Variable):
- 定义方式: 使用
export命令导出。- 作用范围: 在 当前 Shell 以及所有 子进程 中都可用。
- 示例:
export ENV_VAR="I am environment" bash # 打开新的子 Shell echo $ENV_VAR # 输出:I am environment
3. 查看环境变量
- 查看单个变量
echo $NAME //NAME 为待查看的环境变量名称,例如:echo $PATH
printenv NAME //NAME 为待查看的环境变量名称,例如:printenv USER
- 查看所有环境变量
printenv # 或 env,输出一模一样
4. 设置环境变量
1. 为什么 ls 命令可以直接执行,而我们自己的可执行程序需要带上路径(如 ./)来执行的问题?
原因:PATH。 它是一个环境变量,指定了一个目录列表,系统会在这些目录中搜索用户输入的命令。当你在终端中输入一个命令(例如 ls),系统会按照 PATH 中列出的顺序查找该命令,并执行找到的第一个匹配项。像 ls 这样的命令之所以可以不带路径直接执行,是因为它们所在的目录(通常是 /bin 或 /usr/bin 等)被包含在了系统的 PATH 环境变量中。因此,当你输入 ls 时,系统能够在指定的目录中找到并执行这个命令。
2. 我们自己生成的可执行程序为什么不能直接执行?
当我们创建了自己的可执行程序并尝试在终端运行时,默认情况下当前工作目录(即 . 代表的目录)通常不会包含在 PATH 环境变量中。这说明:当我们在终端输入自己程序的名字时,系统不会自动在当前目录下查找该程序。因此,我们需要使用 ./ 前缀来明确指出要执行的是当前目录下的程序。
3. 如何让自定义的可执行程序无需带路径就能直接运行?
要让自定义的可执行程序无需带路径就能直接运行,你需要将它所在的目录添加到 环境变量 PATH 中。这样,当你在命令行中输入程序名时,系统会在 PATH 指定的目录中查找该可执行程序。以下是详细步骤:
1. 临时生效(仅当前终端有效)
# 假设程序放在 /home/user/myprogram/ 目录下
export PATH="$PATH:/home/user/myprogram"
测试验证:
echo $PATH # 查看 PATH 是否包含目录
myprogram # 直接运行你的程序(无需路径)
取消临时设置:临时添加的路径在会话结束后就会丢失。 如果想手动取消,使用 unset 命令:
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:
echo $SHELL
- 如果返回的结果是
/bin/bash,那说明你使用的是 Bash。- 如果返回的结果是
/bin/zsh,那说明你使用的是 Zsh。
这里以我的 Bash 为例:
vim ~/.bashrc
在文件末尾添加这一行:
export PATH=$PATH:/home/user/myprogram # 或者 export PATH ="$PATH:/home/user/myprograms "
保存并退出编辑器,使配置生效:
source ~/.bashrc # 或 source ~/.bash_profile,重新加载配置文件
测试:
echo $PATH # 查看 PATH 变量,确认是否添加成功
myprogram # 直接执行程序,无需路径
3. 取消永久设置:
如果不再需要这个路径,可以编辑 .bashrc 或 .bash_profile,删除那一行,然后重新执行 source 命令:
vim ~/.bashrc # 删除 export PATH 行
source ~/.bashrc # 使配置生效
5. 注意事项
-
安全性:
- 不要将当前目录
.添加到PATH(如export PATH=".:$PATH"),这会允许当前目录下的任意程序被执行,存在安全风险。
- 不要将当前目录
-
路径优先级:
-
PATH中目录的顺序决定查找优先级。例如:export PATH="/my_dir:$PATH" # 优先搜索 /my_dir export PATH="$PATH:/my_dir" # 最后搜索 /my_dir
-
-
多用户系统:
- 若需所有用户生效,可修改系统级配置文件(如
/etc/profile或/etc/environment),但需 root 权限。
- 若需所有用户生效,可修改系统级配置文件(如
-
误删了
PATH变量怎么办?- 恢复默认
PATH:
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 变量的简写,表示当前用户的主目录。可以在命令行中使用 ~ 来快速访问主目录。例如:
cd ~ # 等同于 cd $HOME,切换到当前用户的主目录
这样,无论处在哪个目录下,~ 都会自动被替换为我们的主目录路径。
每个用户的工作目录(主目录)都是独立且唯一的。 即使是同一台机器上的多个用户,它们的主目录路径也不同,这样可以保证用户数据的隔离和安全。
7. 环境变量的组织方式
8. 如何通过代码获取环境变量
1. 通过命令行的第三个参数获取环境变量
要在 C 语言中获取和操作环境变量,我们可以通过以下几种方式:
- 通过命令行第三个参数(
env[])获取环境变量:这是通过命令行启动程序时传递给main()函数的第三个参数。 - 通过第三方变量
environ获取环境变量:environ是一个外部变量,包含了环境变量的列表。 - 通过系统调用获取或设置环境变量:可以使用
getenv()来获取环境变量的值,使用putenv()来设置环境变量。
main() 函数的第三个参数 char *env[] 是一个指向环境变量的字符串数组,数组中的每个元素都是一个格式为 KEY=VALUE 的字符串。
示例代码:
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
printf("获取命令行参数:\n");
for (int i = 0; i < argc; i++)
{
printf("参数[%d]: %s\n", i, argv[i]);
}
printf("\n获取环境变量:\n");
for (int i = 0; env[i] != NULL; i++)
{
printf("环境变量[%d]: %s\n", i, env[i]);
}
return 0;
}
输出:
2. 通过 environ 获取环境变量
environ 是一个外部全局变量,包含当前环境变量的数组,它是 char **environ 类型。
示例代码:
#include <stdio.h>
extern char **environ;
int main()
{
printf("通过 environ 获取环境变量:\n");
for (int i = 0; environ[i] != NULL; i++)
{
printf("环境变量[%d]: %s\n", i, environ[i]);
}
return 0;
}
输出:
3. 使用 getenv() 和 putenv() 系统调用获取和设置环境变量
常用 getenv 和 putenv 函数来访问特定的环境变量。
getenv():获取指定环境变量的值。putenv():设置一个新的环境变量或修改已有环境变量的值。
示例:获取和设置环境变量
#include <stdio.h>
#include <stdlib.h>
extern int putenv(char *string); // 添加 putenv 的显式声明
int main()
{
// 获取环境变量
char *home = getenv("HOME");
if (home)
{
printf("HOME 环境变量的值: %s\n", home);
}
else
{
printf("HOME 环境变量未设置。\n");
}
// 设置环境变量
putenv("MYVAR=MyCustomValue");
char *myvar = getenv("MYVAR");
if (myvar)
{
printf("MYVAR 环境变量的值: %s\n", myvar);
}
// 修改环境变量
putenv("MYVAR=NewValue");
myvar = getenv("MYVAR");
if (myvar)
{
printf("修改后的 MYVAR 环境变量的值: %s\n", myvar);
}
return 0;
}
解释和输出:
getenv():获取环境变量的值,如果变量存在,返回该变量的值;如果不存在,返回NULL。putenv():设置环境变量,参数是一个格式为KEY=VALUE的字符串。putenv会修改当前进程的环境变量,不需要重新调用setenv()或unsetenv()来更新。
9. 环境变量通常是具有全局属性的
-
获取环境变量: 在程序中,通过
getenv("MYENV")获取环境变量MYENV的值。如果该变量存在,程序会打印出它的值。示例代码:
#include <stdio.h> #include <stdlib.h> 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后,程序能够成功读取到该变量的原因。