C程序可以通过使用 putenv() 函数和 getenv() 函数访问环境变量。
两个函数的原型:
#include <stdlib.h>
char *getenv(const char *name);
int putenv(const char *string);
环境变量由形如 name=value 这样的字符串构成。对于给定名称的字符串(变量),getenv() 函数对整个环境进行搜索,并返回和其相关联的值。如果所要求的变量不存在,那么返回 null 。如果变量存在,但没有值,getevn()执行成功后返回一个空串, 这个空串的第一个字节就是 null 。由 getenv() 返回的字符串在 getenv 所拥有的静态存储器中,所以想要进一步使用这个字符串,那么应该将其拷贝保存在另外一个串中,因为在下一次调用 getenv() 时会覆盖上次的得到的值。
putenv 函数把形如 name=value 的字符串增加到当前的环境中。如果因为可用内存泄露而无法扩展环境,函数就会失败并返回 -1。当这种情况发生时,错误变量 error 讲会被设置为 ENOMEM。
示例程序:
01 #include <stdlib.h>
02 #include <stdio.h>
03 #include <string.h>
04
05 int main(int argc, char *argv[])
06 {
07 char *var, *value;
08
09 if(argc == 1 || argc > 3) {
10 fprintf(stderr, "usage: environ var [value]\n");
11 exit(1);
12 }
13
14 var = argv[1];
15 value = getenv(var);
16
17 if(value)
18 printf("Variable %s has value %s\n", var, value);
19 else
20 printf("Variable %s has no value\n", var);
21
22 if(argc == 3) {
23 char *string;
24 value = argv[2];
25 string = malloc(strlen(var) + strlen(value)+2);
26 if(!string) {
27 fprintf(stderr, "out of memory\n");
28 exit(1);
29 }
30
31 strcpy(string,var);
32 strcat(string,"=");
33 strcat(string,value);
35
36 if(putenv(string) != 0) {
37 fprintf(stderr,"putenv failed\n");
38 free(string);
39 exit(1);
40 }
41
42 value = getenv(var);
43 if(value)
44 printf("New value of %s is %s\n", var, value);
45 else
46 printf("New value of %s is null??\n", var);
47 }
48
49 exit(0);
50 }
运行测试: [root@localhost C]# ./environ.exe HOME #得到当前的 HOME 变量值
Variable HOME has value /root
[root@localhost C]# ./environ.exe FRED #因为没有 FRED 这个环境变量,故提示无法找到
Variable FRED has no value
[root@localhost C]# ./environ.exe FRED hello #对 FRED 进行赋值(hello)
Variable FRED has no value
New value of FRED is hello
[root@localhost C]# ./environ.exe FRED #当前进程结束了,这个值也随之消失
Variable FRED has no value
注意:环境对程序来说仅是本地的! 在程序中所作的改变并不会反映到外面来,这是因为变量值不会从子进程(我们的程序)繁殖到父进程(shell)
在程序中,使用了 strcpy() 函数,这个函数复制时,会把字符串赋值到目的地末了还加个NULL('\0');
strlen() 函数计算字符串长度时并不包含字符串末位的 "\0" 。
在使用 strcat(string,"="); 函数进行连接时,“=” 符号会覆盖掉 string 中末位的 '\0' ,然后再在 "=" 号后面再添加一个 "\0" .
所以上面在給 string 指针配分所要指向的内存空间时还要 +2 个字节宽度(),一个字节存放 "=" 号,另一个字节存放 "\0" ,所以有 malloc(strlen(var) + strlen(value)+2);
getenv() 也可以获取经过 export 出来的自定义环境变量。比如先用 export 出一个名为 ELFDEF 的自定义变量: [beyes@SLinux C]$ export SELDEF=just_for_testing
[beyes@SLinux C]$ echo $SELDEF
just_for_testing
然后运行下面程序获得此变量:
[C++] 纯文本查看 复制代码
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf ("%s\n", getenv("SELDEF"));
return 0;
}
运行输出: [beyes@SLinux C]$ ./getenv
just_for_testing
实际上,getenv() 的使用要先判断一下获取是否成功,如果所要获取的变量不存在的话,它回返回一个 NULL ,这样的话像上面程序里直接 printf 输出势必会造成段错误。
如 export 这种用法,只是一种临时设置一个环境变量,当你关闭当前终端后,该变量也就随之消失。可以简单的说,这种临时设定的变量是和进程相关的。
假设我们像上面已经在 shell 里 export 出 SELDEF 这个环境变量,然后再运行下面的程序,最后再 echo 一下 $SELDEF 这个变量:
[C++] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
if (putenv("SELDEF=set_by_putenv_function") != 0) {
perror ("putenv");
exit (EXIT_FAILURE);
}
printf ("%s\n", getenv("SELDEF"));
return (0);
}
运行输出:[beyes@SLinux C]$ ./putenv
set_by_putenv_function
[beyes@SLinux C]$ echo $SELDEF
just_for_testing 由于 shell 执行一个程序是必定是使用了 exec 系统调用,那么在运行 putenv 时,在 putenv 中相当于另起了一个 shell,所以在 putenv 里设置的 SELDEF 和你当前所处的 shell 里的 SELDEF 并不是同一个变量。所以,当 putenv 这个程序退出时,再 echo 一次 SELDEF 看到的值仍然是 just_for_testing 。 |