UNIX编程-进程环境变量

Posted by 周思进 on May 29, 2021

问题场景:主进程集成某个第三方库,该库需要读取本地的一个文件,文件路径通过环境变量读取,且主进程是通过脚本执行起来的,那这个环境变量该如何设置呢?

如下两种设置方式都可以在进程中获取到环境变量值
1、在未执行脚本前,在当前 shell 环境下设置好环境变量,然后再执行脚本启动进程。

2、在脚本中启动进程前设置好环境变量

这样能够生效的原因是新进程在创建之时,会继承其父进程的环境副本。


第一种情况实际涉及三个进程,通过 bash 或者 .\ 执行脚本是新起进程执行,该进程会继承父进程的环境变量,而在脚本中执行的进程,会继续继承父进程的环境变量。可以看如下代码示例:

#run.sh
echo "FILE_PATH:"$FILE_PATH

pid=$$
echo "shell pid:"$pid

ppid=`ps -ef|awk '$2=='$pid'{print $3}'`
echo "shell ppid:"$ppid

./a.out



#a.out 代码

int main(int argc, char const *argv[]) {
    char *p = NULL;

    printf("ppid:%d\n", getppid());
    p = getenv("FILE_PATH");
    if (p != NULL)
    {
        printf("FILE_PATH:%s\n", p);
    }

    return 0;
}

运行输出如下:

image


方式二与方式一主要区别在于,方式二脚本里设置的环境变量,只对该脚本所在的 shell 进程有效,当该 shell 进程退出后,设置的环境变量也就失效了,并没有影响到当前 shell 环境变量。那有什么办法将脚本中的环境变量影响到当前 shell 环境变量呢?

可以通过 source 命令执行或通过.空格 加脚本的方式执行,这样就会改变当前环境变量 ,因为这两个命令都是 shell 内建命令,不会新起进程,实际是在当前 shell 进程中执行的。

# run2.sh
export FILE_PATH=/home

echo "shell pid:"$$
./a.out

这里补充说明下,变量的作用环境只对当前 shell 或者进程有效,如果想让子进程使用该 shell 环境变量,需要通过 export 命令导出。

运行结果如下: image


除了上述两种方式,另一种最直接的方式当然就是在进程代码里直接通过 setenv 接口进行环境变量设置即可。

printenv 或者 env 命令可以显示当前 shell 的环境列表,如果想查看某个进程的环境变量,可以查看 /proc/pid/environ 文件。