为什么/ proc文件系统中environ的内容与extern environ指向的内容不同?

时间:2018-05-15 11:33:59

标签: environment-variables environment getenv environ

在我的C ++ apache / cgi中的getenv()给了我奇怪的东西,然后我检查了/ proc / $ {PID_OF_THE_RUNNING_PROCESS}里面的environ,它们没有匹配,我认为应该这样,我想知道什么是错的/ proc或者是getenv()?

shell@kernel # xargs --null --max-args=1 echo < /proc/${PID_OF_THE_RUNNING_PROCESS}/environ 
PATH=/usr/bin:/bin:/usr/sbin:/sbin
LD_LIBRARY_PATH=/usr/local/httpd-2.2.19/lib:

PID_OF_THE_RUNNING_PROCESS代码

#include<stdio.h>
extern char **environ;

void run()
{
    char* s = *environ;
    printf("declare -x  all env begin\n");    
    for (int i = 1; NULL != s; ++i) {
        printf("declare -x  %s\n", s);
        s = *(environ+i);
    }
    printf("declare -x  all env end\n");
}

PID_OF_THE_RUNNING_PROCESS的控制台日志

declare -x  all env begin
declare -x  FCGI_ROLE=RESPONDER
declare -x  UNIQUE_ID=Wvq-Cn8AAAEAAAkmJlsAAAmM
declare -x  HTTP_HOST=www.example.com
declare -x  HTTP_X_CLIENT_PROTO=https
declare -x  HTTP_X_CLIENT_PROTO_VER=HTTP/1.1
declare -x  HTTP_X_REAL_IP=112.96.194.222
declare -x  HTTP_X_FORWARDED_FOR=112.96.194.222
declare -x  CONTENT_LENGTH=177
declare -x  HTTP_CHARSET=utf-8
declare -x  HTTP_ACCEPT_ENCODING=gzip
declare -x  HTTP_REFERER=https://serviceexample.com/exbb58374cdce267a6/91/page-frame.html
declare -x  CONTENT_TYPE=application/x-www-form-urlencoded
declare -x  HTTP_USER_AGENT=Mozilla/5.0 (Linux; Android 5.1; vivo X6Plus D Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044030 Mobile Safari/537.36 MicroMessenger/6.6.6.1300(0x26060637) NetType/4G Language/zh_CN MicroMessenger/6.6.6.1300(0x26060637) NetType/4G Language/zh_CN
declare -x  PATH=/usr/bin:/bin:/usr/sbin:/sbin
declare -x  SERVER_SIGNATURE=
declare -x  SERVER_SOFTWARE=Apache/2.2.19 (Unix) mod_ssl/2.2.19 OpenSSL/1.0.1t DAV/2 mod_fcgid/2.3.9
declare -x  SERVER_NAME=www.example.com
declare -x  SERVER_ADDR=10.241.94.209
declare -x  SERVER_PORT=80
declare -x  REMOTE_ADDR=10.56.81.214
declare -x  DOCUMENT_ROOT=/data/doc/www.example.com/htdocs
declare -x  SERVER_ADMIN=webmaster@tencent.com
declare -x  SCRIPT_FILENAME=/data/doc/www.example.com/cgi-bin/ex/common/www_ex_time.cgi
declare -x  REMOTE_PORT=46151
declare -x  GATEWAY_INTERFACE=CGI/1.1
declare -x  SERVER_PROTOCOL=HTTP/1.1
declare -x  REQUEST_METHOD=POST
declare -x  QUERY_STRING=
declare -x  REQUEST_URI=/cgi-bin/ex/common/www_ex_time.cgi
declare -x  SCRIPT_NAME=/cgi-bin/ex/common/www_ex_time.cgi
declare -x  HTTP_CONNECTION=close
declare -x  all env end
declare -x  112.96.194.222

2 个答案:

答案 0 :(得分:0)

是的,我找到了答案,如果在运行期间进程发生变化,它们就不一样了 我找到了官方文档here

/proc/[pid]/environ
              This file contains the initial environment that was set when
              the currently executing program was started via execve(2).              
              ......
              If, after an execve(2), the process modifies its environment
              (e.g., by calling functions such as putenv(3) or modifying the
              environ(7) variable directly), this file will not reflect
              those changes.

启动 初始环境 >
我们更改了 env ,比如setenv(),这将反映在extern environ上,我们可以通过验证来验证它,但 / proc / self / environ < / em>,它们是静态的,在运行期间不会受到影响。

答案 1 :(得分:0)

/ proc / $ pid / environ 数据显示进程启动时env变量的状态。如果随后修改了环境变量(例如,通过putenv()),这将反映在getenv()但不是 / proc / $ pid / environ 的返回值中。您可以通过在一个终端中编译和运行以下程序并在另一个终端中查看其proc /.../ environ来查看此操作。

#include <stdio.h>
#include <stdlib.h>

int main() {
    putenv("HOME=WTF");
    char *home = getenv("HOME");
    printf("pid %d  HOME=%s\n", getpid(), home);
    sleep(300);
}

P.S。,理论上对环境的更新可以反映在 / proc / $ pid / environ 中,但实际上我并不知道有任何实现这样做。