曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4686|回复: 0
打印 上一主题 下一主题

getenv, putenv

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-2-19 00:08:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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 。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-8 02:38 , Processed in 0.081307 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表