Linux /proc/<pid>/environ
не обновляется (насколько я понимаю, файл содержит исходную среду процесса).
Как я могу прочитать текущую среду процесса ?
источник
Linux /proc/<pid>/environ
не обновляется (насколько я понимаю, файл содержит исходную среду процесса).
Как я могу прочитать текущую среду процесса ?
/proc/$pid/environ
обновляется, если процесс изменяет свою собственную среду. Но многие программы не беспокоятся об изменении собственной среды, потому что это немного бессмысленно: среда программы не видна через обычные каналы, только через /proc
и ps
, и даже не в каждом варианте Unix есть такая функция, поэтому приложения не полагаются в теме.
Что касается ядра, окружение появляется только в качестве аргумента execve
системного вызова, запускающего программу. Linux раскрывает область в памяти /proc
, и некоторые программы обновляют эту область, а другие - нет. В частности, я не думаю, что какая-либо оболочка обновляет эту область. Поскольку область имеет фиксированный размер, было бы невозможно добавить новые переменные или изменить длину значения.
PATH=foo
в оболочке, не означает, что оболочка будет изменена*envp
. В некоторых оболочках обновляется только внутренняя структура данных, и обновляется код выполнения внешней программы*envp
. Посмотритеassign_in_env
вvariables.c
в источнике Баш, например.fork
то libc выполняетsys_fork
вызов, используя выделенную кучу среду для дочернего процесса.argv
более распространены, но оба существуют).Вы можете прочитать исходную среду процесса из
/proc/<pid>/environ
.Если процесс изменяет свою среду, то для чтения среды необходимо иметь таблицу символов для процесса и использовать
ptrace
системный вызов (например, с помощьюgdb
) для чтения среды из глобальнойchar **__environ
переменной. Нет другого способа получить значение любой переменной из запущенного процесса Linux.Это ответ. Теперь о некоторых заметках.
Выше предполагается, что процесс совместим с POSIX, что означает, что процесс управляет своей средой, используя глобальную переменную,
char **__environ
как указано в Ссылочной спецификации .Начальная среда для процесса передается процессу в буфере фиксированной длины в стеке процесса. (Обычный механизм, который делает это
linux//fs/exec.c:do_execve_common(...)
.) Поскольку размер буфера рассчитывается не больше, чем размер, необходимый для начальной среды, вы не можете добавить новые переменные, не удалив существующие переменные или не разрушив стек. Таким образом, любая разумная схема, позволяющая вносить изменения в среду процесса, будет использовать кучу, в которой можно выделять и освобождать память произвольных размеров, что в точности делает для вас GNUlibc
(glibc
).Если процесс использует
glibc
, то он является POSIX-совместимым,__environ
поскольку объявление вglibc//posix/environ.c
Glibc инициализируется__environ
указателем на памятьmalloc
из кучи процесса, а затем копирует исходную среду из стека в эту область кучи. Каждый раз, когда процесс используетsetenv
функцию,glibc
выполняетrealloc
настройку размера области, на которую__environ
указывает новое значение или переменная. (Вы можете скачать исходный код glibc с помощьюgit clone git://sourceware.org/git/glibc.git glibc
). Чтобы по-настоящему понять механизм, вам также нужно прочитать код Hurd вhurd//init/init.c:frob_kernel_process()
(git clone git: //git.sv.gnu.org/hurd/hurd.git hurd).Теперь, если новый процесс редактируется только
fork
без последующейexec
перезаписи стека, тогда происходит волшебство копирования аргумента и средыlinux//kernel/fork.c:do_fork(...)
, когдаcopy_process
подпрограммы вызываютdup_task_struct
выделение стека нового процесса путем вызоваalloc_thread_info_node
, который вызываетsetup_thread_stack
(linux//include/linux/sched.h
) для нового процесса, использующегоalloc_thread_info_node
.Наконец,
__environ
соглашение POSIX является соглашением пространства пользователя . Он не имеет ничего общего с ядром Linux. Вы можете написать программу пользовательского пространства без использованияglibc
и без__environ
глобальных параметров, а затем управлять переменными среды по своему усмотрению. Никто не арестует вас за это, но вам придется написать свои собственные функции управления средой (setenv
/getenv
) и свои собственные оболочки,sys_exec
и, вероятно, никто не сможет угадать, куда вы вносите изменения в вашу среду.источник
/proc/[pid]/
имеют странную кодировку (кто-то другой может знать, что и почему). Для меня простоcat environ
вывести переменные окружения в действительно трудном для чтения формате.cat environ | strings
решил это для меня.Он обновляется по мере того, как и когда процесс получает / удаляет свои переменные окружения. У вас есть ссылка, в которой говорится, что
environ
файл не обновляется для процесса в его каталоге процессов в / proc файловой системы?или
или
Выше будет печатать переменные среды процесса в
ps
выходном формате, обработка текста (анализ / фильтрация) требуется, чтобы увидеть переменные среды в виде списка.Солярис (не спрашивал, но для справки выложу здесь):
или
РЕДАКТИРОВАТЬ: / proc / pid / environment не обновляется! Я стою исправлено. Процесс проверки ниже. Однако потомки, от которых процесс является fork, наследуют переменную среды процесса, и это видно в их соответствующем файле / proc / self / environment. (Используйте строки)
В оболочке: здесь xargs является дочерним процессом и, следовательно, наследует переменную окружения, а также отражается в его
/proc/self/environ
файле.Проверка его из другого сеанса, где терминал / сеанс не является дочерним процессом оболочки, в которой установлена переменная среды.
Проверка из другого терминала / сеанса на том же хосте:
Terminal1:: Обратите внимание, что printenv является fork'd и является дочерним процессом bash, и, следовательно, он читает свой собственный файл окружения.
терминал2: на том же хосте - не запускайте его в той же оболочке, где была установлена вышеуказанная переменная, запускайте терминал отдельно.
источник
export foo=bar
в одном сеансе bash (pid xxxx), затем делаюcat /proc/xxxx/environ | tr \\0 \\n
в другом сеансе bash, и я не вижуfoo
.gdb
к pid, но там до сих пор нет ссылок. Блок переменных среды в памяти перераспределяется всякий раз, когда происходит изменение, и не отражается в файле окружения своего собственного процесса в файловой системе proc, но, тем не менее, позволяет наследоваться дочерним процессом. Это означает, что это может быть легче узнать внутренние детали, когда происходит разветвление, как дочерний процесс получает переменные среды, скопированные как есть.Что ж, следующее не связано с реальными намерениями автора, но если вы действительно хотите «ПРОЧИТАТЬ»
/proc/<pid>/environ
, вы можете попробоватьчто лучше, чем
cat
это.источник
strings
. Будь проще.xargs --null
.tr '\0' '\n' < /proc/$$/environ | ...