Почему содержимое environment в файловой системе /proc отличается от того, на которое указывает extern environment?
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 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 ответа
Да, я нашел ответ, они не совпадают в случае изменения процесса env во время выполнения.
Я нашел официальную документацию здесь:
/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/environment, они статичны, не будут затронуты во время выполнения.
Данные /proc/$pid/environment показывают состояние env в начале процесса. Если переменные среды были впоследствии изменены (например, через putenv()
), что будет отражено в возвращаемом значении getenv()
но не /proc/$pid/environment. Вы можете увидеть это в действии, скомпилировав и запустив следующую программу в одном терминале и посмотрев ее окружение proc /.../ в другом терминале.
#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);
}
PS Теоретически обновления среды могут быть отражены в /proc/$pid/environment, но на практике я не знаю ни о какой реализации, которая делает это.