Ответ 1
Через gdb:
(gdb) attach process_id
(gdb) call putenv ("env_var_name=env_var_value")
(gdb) detach
Это довольно неприятный взлом, и его нужно делать только в контексте сценария отладки, конечно.
В Unix существует ли способ, которым один процесс может изменить другие переменные среды (при условии, что все они управляются одним и тем же пользователем)? Общее решение было бы лучше, но если нет, то как насчет конкретного случая, когда один из них является дочерним по отношению к другому?
Изменить: как с помощью gdb?
Через gdb:
(gdb) attach process_id
(gdb) call putenv ("env_var_name=env_var_value")
(gdb) detach
Это довольно неприятный взлом, и его нужно делать только в контексте сценария отладки, конечно.
Возможно, вы можете сделать это технически (см. другие ответы), но это может вам не помочь.
Большинство программ ожидают, что env vars не могут быть изменены извне после запуска, поэтому большинство из них, вероятно, просто прочитают интересующие вас вары при запуске и инициализируют на основе этого. Поэтому их изменение впоследствии не изменит, так как программа никогда не перечитает их.
Если вы разместили это как конкретную проблему, вы, вероятно, должны придерживаться другого подхода. Если это было просто из любопытства: Хороший вопрос: -).
По существу, нет. Если у вас есть достаточные привилегии (корень или около того) и ткнул вокруг /dev/kmem (память ядра), и вы внесли изменения в среду процесса, и если процесс фактически повторно ссылался на переменную среды впоследствии (то есть процесс еще не взяли копию env var и не использовали именно эту копию), тогда, может быть, если бы вы были удачливы и умны, а ветер дул в правильном направлении, а фаза луны была правильной, возможно, вы можете чего-то добиться.
Цитата: Джерри Пик:
Вы не можете научить старых собак новым трюкам.
Единственное, что вы можете сделать, это изменить переменную среды дочернего процесса до, начиная с нее: она получает копию родительской среды, извините.
Подробнее см. http://www.unix.com.ua/orelly/unix/upt/ch06_02.htm.
Просто комментируйте ответ об использовании /proc. Под linux/proc поддерживается, но он не работает, вы не можете изменить файл /proc/${pid}/environ
, даже если вы root: он абсолютно доступен только для чтения.
Я мог бы придумать довольно надуманный способ сделать это, и он не будет работать для произвольных процессов.
Предположим, что вы пишете свою собственную общую библиотеку, которая реализует 'char * getenv'. Затем вы настраиваете 'LD_PRELOAD' или 'LD_LIBRARY_PATH' env. vars, так что оба ваших процесса запускаются с предустановленной общей библиотекой.
Таким образом, вы, по сути, будете иметь контроль над кодом функции getenv. Тогда вы могли бы делать всевозможные неприятные трюки. Ваш getenv может обращаться к внешнему файлу конфигурации или сегменту SHM для альтернативных значений env vars. Или вы можете выполнить поиск/замену regexp по запрошенным значениям. Или...
Я не могу придумать простой способ сделать это для произвольных запущенных процессов (даже если вы root), не переписывая динамический компоновщик (ld-linux.so).
Или попросите ваш процесс обновить файл конфигурации для нового процесса, а затем либо:
Не знаю, насколько я знаю. На самом деле вы пытаетесь установить связь из одного процесса в другой, который требует одного из методов IPC (разделяемая память, семафоры, сокеты и т.д.). Получив данные одним из этих методов, вы могли бы затем установить переменные среды или выполнить другие действия более непосредственно.
Если ваш unix поддерживает файловую систему /proc, тогда тривиальным является READ env - вы можете прочитать среду, командную строку и многие другие атрибуты любого процесса, которому вы владеете. Меняя это... Ну, я могу думать о пути, но это идея ПЛОХАЯ.
Более общий случай... Я не знаю, но я сомневаюсь, что есть переносимый ответ.
(Отредактировано: мой первоначальный ответ предполагал, что OP хочет ПРОЧИТАТЬ env, а не изменять его)
Не прямой ответ, но... У Раймонда Чена было обоснованное [на основе Windows] это только на днях: -
... Несмотря на то, что есть определенные способы выполнения этого или способы, которые работают с помощью отладчика, нет ничего, что поддерживается для программного доступа к другой командной строке процессов, по крайней мере, ничто, предоставляемое ядром....
Это не является следствием принципа не отслеживания информации, которую вам не нужны. Ядру не нужно получать командную строку другого процесса. Он передает командную строку, переданную в функцию
CreateProcess
, и копирует ее в адресное пространство запущенного процесса в месте, где функцияGetCommandLine
может ее получить. Как только процесс может получить доступ к своей командной строке, выполняются обязанности ядра.Так как командная строка копируется в адресное пространство процессов, процесс может даже записываться в память, содержащую командную строку и модифицирующую ее. Если это произойдет, исходная командная строка будет потеряна навсегда; единственная известная копия была перезаписана.
Другими словами, любые такие средства ядра были бы
Однако наиболее вероятная причина заключается в том, что для такого объекта существуют ограниченные варианты использования.
UNIX полон Inter-process communication. Проверьте, есть ли у вашего целевого экземпляра некоторые. Dbus становится стандартом в "настольном" IPC.
Я изменяю переменные среды внутри Awesome window manager с помощью awesome-client with - это "отправитель" Dbus кода lua.