Linux-环境变量
目录
1.基本概念
2.常见环境变量
2.1环境变量相关命令
2.2通过现象看本质
3.本地变量
4.整体理解环境变量、系统和程序
5.获取环境变量的其他方法
5.1 getenv 函数
5.2putenv 函数
6.内建命令
6.总结
1.基本概念
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
2.常见环境变量
环境变量 | 描述 |
---|---|
PATH | 指定命令的搜索路径,当在命令行输入一个命令时,系统会根据该变量所包含的路径依次查找可执行文件 |
HOME | 指定用户的主工作目录,即用户登录到 Linux 系统时的默认目录 |
SHELL | 表示当前使用的 Shell,其值通常为/bin/bash (Bash Shell) |
2.1环境变量相关命令
命令 | 功能描述 |
---|---|
echo | 显示某个环境变量值 |
export | 设置一个新的环境变量 |
env | 显示所有环境变量 |
unset | 清除环境变量 |
set | 显示本地定义的 shell 变量和环境变量 |
2.2通过现象看本质
我们运行程序时,需要加上自己程序运行的路径才能运行,ls、vim这些命令本质上也是程序,为什么他们不需要路径,还是他们已经设置好了路径?
在我们登录Linux系统的时候,很多进程已经加载到bash进程中(内存)。
Linux中,存在一些全局设置,告诉命令解释器,要到哪里寻找可执行程序(命令)。 命令解释器能快速定位并执行各类可执行程序。
PATH | 环境变量 |
$PATH | 打印环境变量的内容 |
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin路径:路径:路径
我们尝试将路径加载到 PATH 是否能达成和系统命令一样的效果呢?
我们说过,在我们登录Linux系统的时候,很多进程已经加载到bash进程中(内存)。这意味着
我们的环境变量是内存级别的,系统的很多配置,会通过bash加载到内存中。
所以我们就算把环境变量不小心修改错误了,也能重启进行恢复。
示例:
直接赋值导致之前所有默认路径被覆盖了。
重启后:
现在开始配置:
将之前我们写的程序,直接复制到/usr/bin 目录下:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>int main(int argc,char *argv[]){if(argc!=2){printf("Usage: %s -[a,b,c,d]\n",argv[0]);}else if(strcmp(argv[1],"-a")==0){printf("This is fiction 1!\n");}else if(strcmp(argv[1],"-b")==0){printf("This is fiction 2!\n");}else if(strcmp(argv[1],"-c")==0){printf("This is fiction 3!\n");}else if(strcmp(argv[1],"-d")==0){ printf("This is fiction 4!\n");} else printf("No this fiction\n");return 0;}
实现了我们对命令的模拟。我们来试试其他方法:
PATH=$PATH:/home/new/command
这和我们在安装编译器等软件配置中环境变量是一样的:
但不同的是现在我们配置的环境变量是内存级别的,我们重新登陆后我们配置的环境变量会消失,我们想要不用每次配置,需要我们找到配置文件。
项目 | .profile | .bashrc |
---|---|---|
作用 | 登录时执行,用于设置环境变量、启动后台进程、初始化操作 | 配置 Bash 行为,如设置别名、定义函数、配置命令提示符等 |
适用范围 | 所有类型的 Shell(如 Dash、Sh 等) | 仅适用于 Bash Shell |
执行时机 | 用户登录时(图形界面、SSH、su - username 切换用户) | 每次打开新的交互式 Bash Shell 时(如新建终端标签页)执行 |
常见内容 | - 设置 PATH 环境变量 - 定义 JAVA_HOME 等用户特定变量 - 启动 ssh-agent 等服务 | - 设置命令别名(如 alias ll='ls -l') - 定义函数(如切换目录后自动 ls) - 配置命令提示符(如 PS1) - 设置 Bash 选项(如 histappend) |
区别 | 登录 Shell 配置,适用于所有 Shell,登录时执行一次 | Bash 专属配置,仅适用于 Bash,每次打开新交互式 Bash 时执行 |
联系 | 部分 Linux 发行版中,.profile 会调用 .bashrc,确保登录 Shell 应用其配置 | 依赖 .profile 在登录场景中被调用,以扩展配置生效范围 |
我们在对应文件添加路径即可实现
其他环境命令演示:
env
其他一些环境变量
unset和export
set
3.本地变量
本地变量只有 bash 内部才有效,无法继承到子进程(export 变成环境变量后可继承)。
本地变量无法找到,echo 可以找到(echo是内建命令)。
4.整体理解环境变量、系统和程序
environ 变量
environ 是一个外部全局变量(extern char **environ;),它指向一个字符串指针数组,这些字符串表示进程的环境变量。
数组的最后一个指针值为 NULL,用于标识数组的结束。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>int main()
{extern char** environ;for(int i=1;environ[i];i++){printf("env[%d]=%s\n",i,environ[i]);}return 0;
}
结果
说明环境变量默认子进程也能拿到。
结构示意图:
这张表和过程和我们刚刚的argv [ ]是差不多的。
bash 进程启动的时候,默认会给子进程形成两张表:
argv [ ] 命令行参数表(用户输入命令行),env [ ] 环境变量表(从 OS 的配置文件)。bash 通过各种方式交给子进程。
所以,我们也可以像之前一样通过 main 函数传入环境变量:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>int main(int argc,char* argv,char*env[])
{for(int i=0;env[i];i++){printf("env[%d]->%s\n",i,env[i]);}return 0;
}
我们导入的环境变量也能被我们的程序(bash子进程)找到:
环境变量具有系统级的全局属性,因为本身环境本身会被子进程继承。
5.获取环境变量的其他方法
5.1 getenv 函数
功能:从当前进程的环境变量中获取指定变量的值。
函数原型:
#include <stdlib.h>
char *getenv(const char *name);
参数:
name:要查找的环境变量名(字符串,如 "PATH"、"HOME")。
返回值:
成功:返回指向该环境变量值的字符串指针(格式为 值,例如 "/usr/bin:/bin")。
失败:若变量不存在,返回 NULL。
示例:
char *path = getenv("PATH"); // 获取PATH环境变量的值
if (path != NULL) {printf("PATH = %s\n", path);
}
5.2putenv 函数
功能:设置或修改当前进程的环境变量。
函数原型:
#include <stdlib.h>
int putenv(char *string);
参数:
string:格式为 "变量名=值" 的字符串(如 "MY_VAR=test"),用于设置新变量或修改已有变量。
返回值:
成功:返回 0。
失败:返回非 0 值(如内存分配失败时)。
示例:
char env_str[] = "MY_VAR=hello"; // 注意:需用数组(非字符串常量)
int ret = putenv(env_str); // 设置MY_VAR环境变量
if (ret == 0) {printf("MY_VAR set successfully\n");
}
5.3 getenv、putenv两者示例
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main() {char *path_value = getenv("PATH");if (path_value == NULL) {return 1;} else {printf("path=%s\n",path_value);}char update[]="PATH=123456";int result=putenv(update);path_value=getenv("PATH");if (path_value == NULL) {return 1;} else {printf("path=%s\n",path_value);}return 0;
}
6.内建命令
在 Shell(如 Bash)中,内建命令(Built-in Commands) 是指由 Shell 自身直接执行的命令,而非独立的可执行程序。它们集成在 Shell 解释器内部,不需要创建新进程来运行,因此执行速度更快,并且能直接操作 Shell 的内部状态(如环境变量、当前目录等)。
特点分类 | 详细说明 |
---|---|
无需创建新进程 | 普通命令(如ls、cp)需要启动新进程执行,而内建命令由当前 Shell 进程直接处理,因此执行效率更高。 |
操作 Shell 内部状态 | 能直接修改 Shell 的内部状态,例如通过export修改环境变量、通过cd切换当前工作目录等,这些修改会直接影响当前 Shell 会话。 |
依赖 Shell 实现 | 不同 Shell(如 Bash、Zsh)的内建命令可能存在差异,具体行为需参考对应 Shell 的官方文档。 |
如export、echo是内建命令 ,由 bash 亲自执行。