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

StackOverflow https://stackoverflow.com/questions/205064

Вопрос

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

Редактировать:Как насчет через gdb?

Это было полезно?

Решение

Через gdb:

(gdb) attach process_id

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

(gdb) detach

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

Другие советы

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

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

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

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

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

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

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

Видишь http://www.unix.com.ua/orelly/unix/upt/ch06_02.htm за подробностями.

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

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

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

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

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

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

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

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

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

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

(Отредактировано:мой первоначальный ответ предполагал, что OP хотел прочитать env, а не изменить его)

UNIX полон межпроцессных взаимодействий.Проверьте, есть ли они в вашем целевом экземпляре.Dbus становится стандартом в "настольном" IPC.

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

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

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

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

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

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

  • сложный в реализации
  • потенциально представляет угрозу безопасности

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top