使用 C 语言的 setenv 函数访问环境变量
本文将介绍在 C 语言中使用 setenv
函数导出环境变量的几种方法。
在 C 语言中使用 setenv
函数导出环境变量
在 Unix-base 系统上运行的每个程序都有一个环境,它收集了主要由 shell 和其他用户空间程序使用的变量值对。程序可以用 getenv
函数检索单个环境变量及其值。但如果要定义一个新的变量或改变现有的变量,则应调用 setenv
函数。它需要三个参数,第一个和第二个参数是 char
指针,分别指向变量名和它的值。第三个参数的类型是 int
,它指定如果环境中已经存在给定变量的值是否应该被覆盖。这个参数的非零值表示覆盖行为,零值表示相反。
但请注意,遍历所有定义的环境变量,需要访问名为-environ
的特殊全局变量,它是一个以 NULL 结尾的字符串数组。另外,也可以声明 main
函数,第三个参数 envp
来访问变量。在下面的例子中,我们在调用 setenv
函数之前和之后同时打印 eniron
和 envp
指针。请注意,调用后,envp
指针的值是一样的,而 environ
的值已经改变了。
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
int main(int argc, const char *argv[], const char *envp[]) {
printf("environ: %p\n", environ);
printf("envp: %p\n", envp);
setenv("NEW_VAR", "new_value", 1);
puts("----Added NEW_VAR----");
printf("environ: %p\n", environ);
printf("envp: %p\n", envp);
exit(EXIT_SUCCESS);
}
输出:
environ: 0x7fffa05a7fe8
envp: 0x7fffa05a7fe8
----Added NEW_VAR----
environ: 0x5646431276b0
envp: 0x7fffa05a7fe8
使用 envp
变量在 C 语言中遍历定义的环境变量
前面的代码例子说明了为什么应该避免在调用 setenv
函数后使用 main
函数参数 envp
检索环境变量。当调用 setenv
函数时,环境被重新定位,但 envp
仍然指向旧环境。下面的示例代码通过用 setenv
调用定义一个新的变量,然后遍历 envp
指针数组来演示错误的行为。请注意,如果找到名为 NEW_VAR
的变量,我们还利用 goto
语句跳转到循环的末端。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[], const char *envp[]) {
if (setenv("NEW_VAR", "new_value", 1) != 0) {
perror("setenv");
exit(EXIT_FAILURE);
}
if (envp != NULL) {
for (size_t i = 0; envp[i] != NULL; ++i) {
if (strcmp(envp[i], "NEW_VAR=new_value") == 0) {
puts(envp[i]);
goto END;
}
}
printf("No such variable found!\n");
} END:
exit(EXIT_SUCCESS);
}
输出:
No such variable found!
使用 environ
变量在 C 语言中遍历定义的环境变量
由于前面的解决方案找不到新定义的变量,我们应该使用外部声明的 environ
变量。在这种情况下,我们包含了多个预处理器条件语句,以使代码在不同的系统中可移植,但在大多数基于 UNIX 的系统中只需要 extern char **environ
。一旦声明,我们就可以使用我们在上一个例子中实现的相同的循环来遍历变量列表。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined (_POSIX_) || defined (__USE_POSIX)
extern char **environ;
#elif defined(_WIN32)
_CRTIMP extern char **_environ;
#endif
int main(void) {
if (setenv("NEW_VAR", "new_value", 1) != 0) {
perror("setenv");
exit(EXIT_FAILURE);
}
if (environ != NULL) {
for (size_t i = 0; environ[i] != NULL; ++i) {
if (strcmp(environ[i], "NEW_VAR=new_value") == 0) {
puts(environ[i]);
goto END;
}
}
printf("No such variable found!\n");
} END:
exit(EXIT_SUCCESS);
}
输出:
NEW_VAR=new_value
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn