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

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

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

Ответы [ 10 ]

124 голосов
/ 17 октября 2008

Через GDB:

(gdb) attach process_id

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

(gdb) detach

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

21 голосов
/ 27 февраля 2009

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

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

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

13 голосов
/ 16 октября 2008

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

6 голосов
/ 15 октября 2008

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

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

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

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

6 голосов
/ 15 октября 2008

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

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

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

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

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

3 голосов
/ 15 октября 2008

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

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

НТН.

ура

Rob

2 голосов
/ 15 октября 2008

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

1 голос
/ 31 мая 2011

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

Я изменяю переменные среды внутри оконного менеджера Awesome, используя awesome-client с "отправителем" Dbus кода lua.

1 голос
/ 27 февраля 2009

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

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

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

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

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

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

Однако наиболее вероятной причиной является просто ограниченное количество вариантов использования такого объекта.

1 голос
/ 15 октября 2008

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

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

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

...