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



getenv(( 在我的C++ apache/cgi 给了我奇怪的东西,然后我检查了/proc/${PID_OF_THE_RUNNING_PROCESS} 内部的环境,它们不匹配,我认为他们应该,我想知道/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 beginn");    
for (int i = 1; NULL != s; ++i) {
printf("declare -x  %sn", s);
s = *(environ+i);
}
printf("declare -x  all env endn");
}

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

是的,我找到了答案,如果进程在运行时更改环境,它们就不一样了。
我在这里找到了官方文档:

/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.

启动
请注意初始环境我们更改了环境,比如说,setenv(),这将反映在extern environ上,我们可以演练来验证它,但是/proc/self/environ,它们是静态的,在运行时不会受到影响。

/proc/$pid/environ数据显示进程启动时 env var 的状态。如果环境变量随后被修改(例如,通过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=%sn", getpid(), home);
sleep(300);
}

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

最新更新