xmlstarlet
может сделать это оба пути:
echo '<em>Ampersands & angle brackets need to be encoded.</em>' |
xmlstarlet esc |
xmlstarlet unesc
/proc/$pid/environ
действительно обновляет, если процесс изменяет свою собственную среду. Но много программ не потрудились изменять свою собственную среду, потому что это немного бессмысленно: среда программы не видима через нормальные каналы, только через /proc
и ps
, и даже не каждый вариант Unix имеет этот вид функции, таким образом, приложения не полагаются на него.
Что касается ядра, среда только появляется как аргумент execve
системный вызов, который запускает программу. Linux выставляет область в памяти через /proc
, и некоторые программы обновляют эту область, в то время как другие не делают. В частности, я не думаю, что любая оболочка обновляет эту область. Поскольку область имеет фиксированный размер, было бы невозможно добавить новые переменные или изменить длину значения.
Это обновляется как и когда процесс получает/удаляет свои переменные среды. У Вас есть ссылка, которая указывает 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 ~]$
export foo=bar
на сессии одного удара (pid xxxx), затем сделайте cat /proc/xxxx/environ | tr \\0 \\n
на сессии другого удара и я не вижу foo
.
–
14.01.2012, 20:11
gdb
к pid, но все еще никакой ссылке там. Блок переменных среды в памяти перераспределен каждый раз, когда существует изменение и не отражает в его собственном процессе, окружают файл в proc файловой системе, но однако позволяет быть наследованным дочерним процессом. Это означает, что это могло стать легче знать внутренние детали, когда ветвление происходит, как делает дочерний процесс, скопировали переменные среды, как.
– Nikhil Mulley
14.01.2012, 21:48
Можно считать начальную среду процесса от /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
с указателем на память, что это malloc
s от "кучи" процесса, затем копирует начальную среду со стека в эту область "кучи". Каждый раз процесс использует 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
и вероятно, что никто не сможет предположить, куда Вы помещаете изменения в своей среде.
Что ж, следующее не связано с реальными намерениями автора, но если вы действительно хотите "ПРОЧИТАТЬ" /proc/
, вы можете попробовать
strings /proc/<pid>/environ
, что лучше, чем кат
оно.
PATH=foo
в оболочке не означает, что оболочка собирается изменить*envp
. В некоторых оболочках это только обновило внутреннюю структуру данных, и это - внешний код выполнения программы, который обновляет*envp
. Посмотрите наassign_in_env
вvariables.c
в источнике удара, например. – Gilles 'SO- stop being evil' 15.01.2012, 19:00fork
затем libc делаетsys_fork
звоните использование "кучи" выделило среду для дочернего процесса. – Jonathan Ben-Avraham 29.03.2013, 15:24argv
более распространены, но оба существуют). версия – Gilles 'SO- stop being evil' 29.03.2013, 23:23