前言
最近写一些底层一些的东西,简单回顾一下环境变量.
正文
首先我们来看下c 语言的环境变量的位置。
可以看到每个进程都有自己的环境变量,操作系统会复制环境变量的副本给一个新创建的进程。
那么这个副本哪里来呢? 是操作系统自己维护一份在内存中吗?那不是,因为操作系统中进程有亲属关系。具体来说,操作系统会为新进程创建一个新的地址空间,并将父进程环境变量的副本复制到这个新的地址空间中。
这些通过操作系统干的活。这就解释了一个我们觉得比较神奇的东西。
那就是为啥我们在shell里面设置了一些环境变量哈,然后我们启动的一些新的进程就能用上这些环境变量,但是呢,当我们打开另外一个会话的时候,发现两者的环境变量并不一样,好像修改无效。
我们输入pstree,然后查看他们的关系,我们可以找到pstree。
我们可以从进程树来看这个问题,可以看到他们的关系是哈,是两条不同的分支。
也就是说进程启动后,每个进程的环境变量是独立的, 只能影响后面创建的子进程。
然后需要知道的是,这些都基于一个叫做systemd的父进程。
那么我们在程序中如何获得环境变量,去做一些事情呢?
首先操作系统会给进程一张环境表:
#include<stdio.h>
#include<stdlib.h>
extern char **environ;int main(void)
{printf("%p", environ);environ++;return 0;
}
这个environ 就是环境表的起始地址。
这样写是c语言的约定,看下汇编。
所以在编译的时候environ就会被赋值了,是一种约定。
那么如何获取全部的环境变量呢?现在我们知道了初始指针,同样能够知道最后一个指针是null。
那么可以这样做。
#include<stdio.h>
#include<stdlib.h>
extern char **environ;int main(void)
{while (environ!=NULL){printf("%s \n", *environ);environ++;}return 0;
}
遍历一下整个环境遍历表。
但是进程中一般不会去真的遍历整个环境遍历哈,一般只获取我们需要的。
#include<stdio.h>
#include<stdlib.h>
extern char **environ;int main(void)
{char* a = getenv("PATH");printf("%s \n", a);return 0;
}
同样提供了:
结
把一些东西的回顾了。