进程环境

  

进程环境


  libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明。例如:
  

#include <stdio.h>
int main(void)
{
extern char **environ;
int i;
for(i=0; environ[i]!=NULL; i++)
printf("%s ", environ[i]);
return 0;
}


  由于父进程在调用fork创建子进程时会把自己的环境变量表也复制给子进程,所以a.out(编译以上程序所生成的应用程序)打印的环境变量和Shell进程的环境变量是相同的。
  按照惯例,环境变量字符串都是name=value这样的形式,大多数name由大写字母加下划线组成,一般把name的部分叫做环境变量,value的部分则是环境变量的值。环境变量定义了进程的运行环境,一些比较重要的环境变量的含义如下:

PATH
* 可执行文件的搜索路径。ls命令也是一个程序,执行它不需要提供完整的路径名/bin/ls,然而通常我们执行当前目录下的程序a.out却需要提供完整的路径名./a.out,这是因为PATH环境变量的值里面包含了ls命令所在的目录/bin,却不包含a.out所在的目录。PATH环境变量的值可以包含多个目录,用:号隔开。在Shell中用echo命令可以查看这个环境变量的值:
$ echo $PATH

SHELL
* 当前Shell,它的值通常是/bin/bash。

TERM
* 当前终端类型,在图形界面终端下它的值通常是xterm,终端类型决定了一些程序的输出显示方式,比如图形界面终端可以显示汉字,而字符终端一般不行。

LANG
* 语言和locale,决定了字符编码以及时间、货币等信息的显示格式。

HOME
* 当前用户主目录的路径,很多程序需要在主目录下保存配置文件,使得每个用户在运行该程序时都有自己的一套配置。


  用environ指针可以查看所有环境变量字符串,但是不够方便,如果给出name要在环境变量表中查找它对应的value,可以用getenv函数。
  

#include <stdlib.h>

char *getenv(const char *name);

getenv的返回值是指向value的指针,若未找到则为NULL。


修改环境变量可以用以下函数

#include <stdlib.h>

int setenv(const char *name, const char *value, int rewrite);
void unsetenv(const char *name);

putenv和setenv函数若成功则返回为0,若出错则返回非0。


setenv将环境变量name的值设置为value。如果已存在环境变量name,那么:
若rewrite非0,则覆盖原来的定义;
若rewrite为0,则不覆盖原来的定义,也不返回错误。
unsetenv删除name的定义。即使name没有定义也不返回错误。

例:修改环境变量

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
printf("PATH=%s ", getenv("PATH"));
setenv("PATH", "hello", 1);
printf("PATH=%s ", getenv("PATH"));

return 0;
}


//fork--------------------------------------------------------------------------
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(void) { pid_t pid; int n = 0; printf("this is a test "); /* *上面的语句如果没有 那么就会在子进程中也打印一句 *这个是由于printf的机制造成的,遇到 就出栈, *若没有 那么会在执行下一条语句前出栈, *而下一条语句是fork,此时已经复制主进程的环境,其中包括打印 */ pid = fork();//调用fork时,子进程会从下面的语句开始执行 if(pid > 0) { while(1) { n = 10;//两个n的值是不一样的,那是因为读时共享,写时复制 printf("I am parent n = %d , &n = %p ",n,&n); sleep(2); } } else if(pid == 0) { while(1) { //两个n的地址是一样的,那是因为虚拟地址一样的原因 //但是n的值是不一样的,那是因为读时共享,写时复制 printf("I am child n = %d , &n = %p ",n,&n); sleep(2); } } else { perror("fork"); exit(1); } return 0; }
原文地址:https://www.cnblogs.com/13224ACMer/p/6384904.html