曲径通幽论坛

标题: getenv, putenv [打印本页]

作者: beyes    时间: 2009-2-19 00:08
标题: getenv, putenv
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 。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2