Как считать переменные среды процесса

xmlstarlet может сделать это оба пути:

echo '<em>Ampersands & angle brackets need to be encoded.</em>' |
xmlstarlet esc | 
xmlstarlet unesc
46
31.03.2013, 07:13
4 ответа

/proc/$pid/environ действительно обновляет, если процесс изменяет свою собственную среду. Но много программ не потрудились изменять свою собственную среду, потому что это немного бессмысленно: среда программы не видима через нормальные каналы, только через /proc и ps, и даже не каждый вариант Unix имеет этот вид функции, таким образом, приложения не полагаются на него.

Что касается ядра, среда только появляется как аргумент execve системный вызов, который запускает программу. Linux выставляет область в памяти через /proc, и некоторые программы обновляют эту область, в то время как другие не делают. В частности, я не думаю, что любая оболочка обновляет эту область. Поскольку область имеет фиксированный размер, было бы невозможно добавить новые переменные или изменить длину значения.

21
27.01.2020, 19:34
  • 1
    так, эффективно нет никакого способа получить доступ к процессу *envp (массив указателей на параметры среды). @Gilles, может Вы показывать, возможно ли присоединить отладчик и считать массив указателей на параметры среды. –  Nikhil Mulley 15.01.2012, 09:29
  • 2
    @Nikhil Несомненно, это. Но просто потому что Вы пишете PATH=foo в оболочке не означает, что оболочка собирается изменить *envp. В некоторых оболочках это только обновило внутреннюю структуру данных, и это - внешний код выполнения программы, который обновляет *envp. Посмотрите на assign_in_env в variables.c в источнике удара, например. –  Gilles 'SO- stop being evil' 15.01.2012, 19:00
  • 3
    @Gilles: Этот ответ в лучшем случае вводит в заблуждение (-1). Среда в/proc/$$ / окружает, читается из стопки процесса. См. fs/proc/base.c. Это - начальная среда. Это никогда не обновляется и на самом деле не может быть. Среда, что libc setenv использование выделяется на "куче" и инициализируется с содержанием среды в стеке. Если процесс называет libc's fork затем libc делает sys_fork звоните использование "кучи" выделило среду для дочернего процесса. –  Jonathan Ben-Avraham 29.03.2013, 15:24
  • 4
    @JonathanBen-Avraham, Вы правы, что начальная среда не обновляется ни в какой оболочке. Однако та область не только для чтения в соответствии с Linux, я встретился с программами, которые используют его для создания отчетов об их состоянии (отчеты о состоянии через argv более распространены, но оба существуют). версия –  Gilles 'SO- stop being evil' 29.03.2013, 23:23

Это обновляется как и когда процесс получает/удаляет свои переменные среды. У Вас есть ссылка, которая указывает environ файл не обновляется для процесса в его рабочем каталоге под/proc файловой системой?

xargs --null --max-args=1 echo < /proc/self/environ

или

xargs --null --max-args=1 echo < /proc/<pid>/environ

или

ps e -p <pid>

Вышеупомянутое распечатает переменные среды процесса в ps выходной формат, относящийся к обработке текстов (парсинг/фильтрация), требуется, чтобы рассматривать переменные среды как список.

Солярис (не спрошенный, но для ссылки я отправлю здесь):

/usr/ucb/ps -wwwe <pid>

или

pargs -e <pid> 

Править:/proc/pid/environ не обновляется! Я признаю ошибку. Процесс проверки ниже. Однако дети, от которых процесс fork'd, наследовали переменную среды процесса, и это видимо в их соответствующем/proc/self/environ файле. (Используйте строки),

С в оболочке: здесь xargs является дочерним процессом и следовательно наследовал переменную среды и также отражается в /proc/self/environ файл.

[centos@centos t]$ printenv  | grep MASK
[centos@centos t]$ export MASK=NIKHIL
[centos@centos t]$ printenv  | grep MASK
MASK=NIKHIL
[centos@centos t]$ xargs --null --max-args=1 echo < /proc/self/environ  | grep MASK
MASK=NIKHIL
[centos@centos t]$ unset MASK
[centos@centos t]$ printenv  | grep MASK
[centos@centos t]$ xargs --null --max-args=1 echo < /proc/self/environ  | grep MASK
[centos@centos t]$

Проверка его от другой сессии, где терминал/сессия не является дочерним процессом оболочки, где переменная среды установлена.

Проверка от другого терминала/сессии на том же хосте:

terminal1:: Обратите внимание, что printenv является fork'd и является дочерним процессом удара, и следовательно он читает, его собственные окружают файл.

[centos@centos t]$ echo $$
2610
[centos@centos t]$ export SPIDEY=NIKHIL
[centos@centos t]$ printenv | grep SPIDEY
SPIDEY=NIKHIL
[centos@centos t]$ 

terminal2: на том же хосте - не запускают его с в той же оболочке, где вышеупомянутая переменная была установлена, запустите терминал отдельно.

[centos@centos ~]$ echo $$
4436
[centos@centos ~]$ xargs --null --max-args=1 echo < /proc/self/environ | grep -i spidey
[centos@centos ~]$ strings -f /proc/2610/environ | grep -i spidey
[centos@centos ~]$ xargs --null --max-args=1 echo < /proc/2610/environ | grep -i spidey
[centos@centos ~]$ 
21
27.01.2020, 19:34
  • 1
    я делаю export foo=bar на сессии одного удара (pid xxxx), затем сделайте cat /proc/xxxx/environ | tr \\0 \\n на сессии другого удара и я не вижу foo. –   14.01.2012, 20:11
  • 2
    я обновил вышеупомянутый ответ с примером, проверяющим тот же процесс в оболочке. Старые ядра –  Nikhil Mulley 14.01.2012, 20:52
  • 3
    Вы корректны. Я признаю ошибку.Спасибо. Я теперь должен пойти и прочитать свои руководства для проверки переменных среды другого процесса с в группе пользовательского процесса. –  Nikhil Mulley 14.01.2012, 21:35
  • 4
    Еще одна вещь: Я пытался проверить среду, присоединяющую gdb к pid, но все еще никакой ссылке там. Блок переменных среды в памяти перераспределен каждый раз, когда существует изменение и не отражает в его собственном процессе, окружают файл в proc файловой системе, но однако позволяет быть наследованным дочерним процессом. Это означает, что это могло стать легче знать внутренние детали, когда ветвление происходит, как делает дочерний процесс, скопировали переменные среды, как. –  Nikhil Mulley 14.01.2012, 21:48
  • 5
    я надеюсь, что @Gilles пролил бы часть его света факела на этом.. :-) –  Nikhil Mulley 14.01.2012, 22:22

Можно считать начальную среду процесса от /proc/<pid>/environ.

Если процесс изменяет свою среду, то для чтения среды, Вы должны иметь таблицу символов для процесса и использовать ptrace системный вызов (например, при помощи gdb) считать среду из глобального char **__environ переменная. Нет никакого другого способа получить значение любой переменной от рабочего процесса Linux.

Это - ответ. Теперь для некоторых примечаний.

Вышеупомянутое предполагает, что процессом является совместимый POSIX, означая, что процесс управляет своей средой с помощью глобальной переменной char **__environ как указано в Касательно Спецификации.

Начальная среда для процесса передается процессу в буфере фиксированной длины на стопке процесса. (Обычный механизм, который делает это, linux//fs/exec.c:do_execve_common(...).), Так как размер буфера вычисляется, чтобы быть не больше, чем размером, требуемым для начальной среды, Вы не можете добавить новые переменные, не стирая существующие переменные или разбив стек. Так, любой разумный план позволить изменения в среде процесса использовал бы "кучу", где память в произвольных размерах может быть выделена и освобождена, который является точно что GNU libc (glibc) делает для Вас.

Если процесс использует glibc, затем это - совместимый POSIX, с __environ быть объявленным в glibc//posix/environ.c Glibc инициализирует __environ с указателем на память, что это mallocs от "кучи" процесса, затем копирует начальную среду со стека в эту область "кучи". Каждый раз процесс использует setenv функция, glibc делает a realloc скорректировать размер области это __environ точки к разместить новое значение или переменную. (Можно загрузить glibc исходный код git clone git://sourceware.org/git/glibc.git glibc). Для реального понимания механизма, необходимо будет также прочитать код Hurd в hurd//init/init.c:frob_kernel_process() (клон мерзавца 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.

Наконец, POSIX __environ конвенция является конвенцией пространства пользователя. Это не имеет никакого соединения ни с чем в ядре Linux. Можно записать программу пространства пользователя без использования glibc и без __environ глобальный и затем управляют переменными среды однако, Вам нравится. Никто не будет фиксировать Вас за то, что Вы сделали это, но необходимо будет записать собственные функции управления средой (setenv/getenv) и Ваши собственные обертки для sys_exec и вероятно, что никто не сможет предположить, куда Вы помещаете изменения в своей среде.

40
27.01.2020, 19:34

Что ж, следующее не связано с реальными намерениями автора, но если вы действительно хотите "ПРОЧИТАТЬ" /proc//environ, вы можете попробовать

strings /proc/<pid>/environ

, что лучше, чем катоно.

15
27.01.2020, 19:34

Теги

Похожие вопросы