Есть ли способ изменить переменные среды другого процесса в Unix?

В Unix существует ли способ, которым один процесс может изменить другие переменные среды (при условии, что все они управляются одним и тем же пользователем)? Общее решение было бы лучше, но если нет, то как насчет конкретного случая, когда один из них является дочерним по отношению к другому?

Изменить: как с помощью gdb?

Ответ 1

Через gdb:

(gdb) attach process_id

(gdb) call putenv ("env_var_name=env_var_value")

(gdb) detach

Это довольно неприятный взлом, и его нужно делать только в контексте сценария отладки, конечно.

Ответ 2

Возможно, вы можете сделать это технически (см. другие ответы), но это может вам не помочь.

Большинство программ ожидают, что env vars не могут быть изменены извне после запуска, поэтому большинство из них, вероятно, просто прочитают интересующие вас вары при запуске и инициализируют на основе этого. Поэтому их изменение впоследствии не изменит, так как программа никогда не перечитает их.

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

Ответ 3

По существу, нет. Если у вас есть достаточные привилегии (корень или около того) и ткнул вокруг /dev/kmem (память ядра), и вы внесли изменения в среду процесса, и если процесс фактически повторно ссылался на переменную среды впоследствии (то есть процесс еще не взяли копию env var и не использовали именно эту копию), тогда, может быть, если бы вы были удачливы и умны, а ветер дул в правильном направлении, а фаза луны была правильной, возможно, вы можете чего-то добиться.

Ответ 4

Цитата: Джерри Пик:

Вы не можете научить старых собак новым трюкам.

Единственное, что вы можете сделать, это изменить переменную среды дочернего процесса до, начиная с нее: она получает копию родительской среды, извините.

Подробнее см. http://www.unix.com.ua/orelly/unix/upt/ch06_02.htm.

Просто комментируйте ответ об использовании /proc. Под linux/proc поддерживается, но он не работает, вы не можете изменить файл /proc/${pid}/environ, даже если вы root: он абсолютно доступен только для чтения.

Ответ 5

Я мог бы придумать довольно надуманный способ сделать это, и он не будет работать для произвольных процессов.

Предположим, что вы пишете свою собственную общую библиотеку, которая реализует 'char * getenv'. Затем вы настраиваете 'LD_PRELOAD' или 'LD_LIBRARY_PATH' env. vars, так что оба ваших процесса запускаются с предустановленной общей библиотекой.

Таким образом, вы, по сути, будете иметь контроль над кодом функции getenv. Тогда вы могли бы делать всевозможные неприятные трюки. Ваш getenv может обращаться к внешнему файлу конфигурации или сегменту SHM для альтернативных значений env vars. Или вы можете выполнить поиск/замену regexp по запрошенным значениям. Или...

Я не могу придумать простой способ сделать это для произвольных запущенных процессов (даже если вы root), не переписывая динамический компоновщик (ld-linux.so).

Ответ 6

Или попросите ваш процесс обновить файл конфигурации для нового процесса, а затем либо:

  • выполнить уничтожение -HUP для нового процесса, чтобы перечитать обновленный файл конфигурации, или
  • пусть процесс проверяет файл конфигурации на наличие обновлений время от времени. Если изменения найдены, перечитайте файл конфигурации.

Ответ 7

Не знаю, насколько я знаю. На самом деле вы пытаетесь установить связь из одного процесса в другой, который требует одного из методов IPC (разделяемая память, семафоры, сокеты и т.д.). Получив данные одним из этих методов, вы могли бы затем установить переменные среды или выполнить другие действия более непосредственно.

Ответ 8

Если ваш unix поддерживает файловую систему /proc, тогда тривиальным является READ env - вы можете прочитать среду, командную строку и многие другие атрибуты любого процесса, которому вы владеете. Меняя это... Ну, я могу думать о пути, но это идея ПЛОХАЯ.

Более общий случай... Я не знаю, но я сомневаюсь, что есть переносимый ответ.

(Отредактировано: мой первоначальный ответ предполагал, что OP хочет ПРОЧИТАТЬ env, а не изменять его)

Ответ 9

Не прямой ответ, но... У Раймонда Чена было обоснованное [на основе Windows] это только на днях: -

... Несмотря на то, что есть определенные способы выполнения этого или способы, которые работают с помощью отладчика, нет ничего, что поддерживается для программного доступа к другой командной строке процессов, по крайней мере, ничто, предоставляемое ядром....

Это не является следствием принципа не отслеживания информации, которую вам не нужны. Ядру не нужно получать командную строку другого процесса. Он передает командную строку, переданную в функцию CreateProcess, и копирует ее в адресное пространство запущенного процесса в месте, где функция GetCommandLine может ее получить. Как только процесс может получить доступ к своей командной строке, выполняются обязанности ядра.

Так как командная строка копируется в адресное пространство процессов, процесс может даже записываться в память, содержащую командную строку и модифицирующую ее. Если это произойдет, исходная командная строка будет потеряна навсегда; единственная известная копия была перезаписана.

Другими словами, любые такие средства ядра были бы

  • сложно реализовать
  • потенциально проблема безопасности

Однако наиболее вероятная причина заключается в том, что для такого объекта существуют ограниченные варианты использования.

Ответ 10

UNIX полон Inter-process communication. Проверьте, есть ли у вашего целевого экземпляра некоторые. Dbus становится стандартом в "настольном" IPC.

Я изменяю переменные среды внутри Awesome window manager с помощью awesome-client with - это "отправитель" Dbus кода lua.