Linux 进程和环境变量

8 min read

进程和环境变量

进程是一个程序执行的上下文集合,这个集合包括程序代码、数据段、堆栈、环境变量、内核标识进程的数据结构等。一个进程可以生成另一个进程,生成的进程称为子进程,那么相应的就有父进程,所谓子子孙孙无穷尽也。

子进程父进程处会继承一些遗传因素,其中就包括本文的主题环境变量

环境变量是一组特殊的字符型变量,由于具有继承性质,环境变量也经常用于父子进程传递参数用

fork和exec

在unix系统中进程通过依次调用fork()exec()系统调用来实现创建一个子进程。

fork其实就是克隆,因为fork()会复制整个进程,包括进程运行到哪句代码,这意味着新的进程会继续执行fork()后面的代码,父进程也会运行fork()后面的代码,从fork()开始父子进程才分道扬镳。

如果fork返回>0,那么说明在父进程中,如果fork返回==0,说明在子进程中

精确的说exec是一组函数的统称,并且exec的准确定义是,用磁盘上的一个新的程序替换当前的进程的正文段、数据段、堆栈段。所以exec并不产生新的进程,而是替换。如此一来进程将从新代码的main开始执行,相当于另外运行了一个完全不同的程序,但保留了原来环境变量。

依据本文的主题,可以把exec函数分为两类,

一类是可以设置并传递新环境变量的,

一类是不能传递新环境变量的,只能继承原环境变量的。

换句话说,在运行新的程序时,是有机会改变新程序的环境变量的,而不只是继承。

shell

shell并没有什么特殊,也是一个进程,当我们在命令行中敲入一个命令,并且按下Enter后,shell这个进程会通过fork和exec为我们创建一个子进程(存在一小部分命令不需要启动子进程,称为build-in命令)并且等待(waitpid)这个子进程完成退出。那么进程的内存镜像显然就包含本文的主题环境变量

set env export 区别

set其实跟进程创建无关,也跟环境变量无关,它只是当前shell进程内部维护的变量(本地变量),用于变量的引用和展开,不能遗传和继承。

source执行脚本,意味着fork和exec不会被调用,当前shell直接对test.sh解释执行。这样的话,如果此时test.sh中有export(即putenv),那么将会改变当前shell的环境变量。

env不是shell的build-in命令,所以shell执行env的时候还是需要创建子进程的