setenv()定义在<stdlib.h>,设置或者更新环境变量。
int setenv(const char *name, const char *value, int overwrite);
成功返回0,失败返回-1并设置错误码。
如果没有该name项则设置。有则更新。
我想谈一谈的是该环境变量是否和 环境变量文件如 .bashrc 有关
由于之前开发过程是通过修改~/.bashrc文件,控制环境变量,所以对于setenv()做一个学习研究。
setenv()是通过修改进程内存空间的形式来修改环境变量,一般不会影响其他的进程,不过子进程除外。因为进程拥有地址空间是独立分开的,这也是虚拟内存的一个作用。不是线程安全函数。
原理 setenv() 流程:
- 检查输入参数: 检查参数是否有效。
- 查找和修改:
- 如果 overwrite 参数为非零值,setenv() 将查找环境变量列表,并修改其值。
- 如果 overwrite 参数为零且环境变量已存在,函数将不进行更改。
- 内存分配:
- 根据需要,setenv() 可能会在内部申请空间来存储新的环境变量名和它的值(通常是在 heap 上)。
- 如果分配成功,新的环境变量将被添加到环境变量列表中。
- 更新环境变量列表: setenv() 将新的值添加到环境变量列表,后续的调用(比如 getenv())能够访问到更新后的环境变量。
- 错误处理: 如果在过程中遇到任何错误,尤其是在内存分配方面,函数会返回 -1并设置 errno。
验证:修改一下环境变量试试效果如何?
使用命令查看一下文件~/.bashrc文件
然后运行之后再次查看一下~/.bashrc文件
事实是无任何变化。
实际上该函数操作的是内存,而非文件。程序运行时每次都会载入环境到虚拟内存。C/C++内存模型如下
可见,命令行参数和环境变量一同布局在进程顶部空间。此处空间一般是固定大小,无法修改,如果有新的环境变量加入,会在堆上申请空间并存储。
进程的环境变量可以通过全局变量访问,定义形式char **environ其定在<unistd.h>。遍历方法:
#include <stdio.h>
#include <unistd.h>
extern char **environ; // 声明 environ
int main() {
// 遍历并打印所有环境变量
for (char **env = environ; *env != NULL; env++) {
printf("%s\n", *env);
}
return 0;
}
所以,对于测试或者其它的一些依赖修改环境变量的程序,可以在其内部调用setenv这类函数进行动态修改,不会影响系统配置文件,很友好。