Изменение текущей рабочей среды LD_LIBRARY_PATH
Можно ли изменить переменные среды текущего процесса?
В частности, в python script я хочу изменить LD_LIBRARY_PATH
так, чтобы при импорте модуля 'x', который зависит от некоторого xyz.so
, xyz.so
берется из моего заданного пути в LD_LIBRARY_PATH
Есть ли другой способ динамического изменения пути, из которого загружается библиотека?
Изменить. Я думаю, мне нужно упомянуть, что я уже пробовал вещи вроде
os.environ [ "LD_LIBRARY_PATH" ] = mypath
os.putenv('LD_LIBRARY_PATH', mypath)
но они изменяют env. для нереложенного подпроцесса, а не текущего процесса, а загрузка модуля не учитывает новый LD_LIBRARY_PATH
Edit2, так что вопрос в том, можем ли мы изменить среду или что-то, чтобы загрузчик библиотеки видел ее и загружал оттуда?
Ответы
Ответ 1
Причина
os.environ["LD_LIBRARY_PATH"] = ...
не работает: эта переменная среды управляет поведением динамического загрузчика (ld-linux.so.2
в Linux, ld.so.1
в Solaris), но загрузчик только смотрит на LD_LIBRARY_PATH
один раз при запуске процесса. Изменение значения LD_LIBRARY_PATH
в текущем процессе после этой точки не влияет (как говорит ответ на этот вопрос).
У вас есть несколько вариантов:
а. Если вы знаете, что вам понадобится xyz.so
из /some/path
, и с самого начала контролируйте выполнение python script, просто установите LD_LIBRARY_PATH
по своему усмотрению (после проверки того, что он еще не установлен), и повторно выполнить себя. Это то, что делает Java
.
В. Вы можете импортировать /some/path/xyz.so
через свой абсолютный путь перед импортом x.so
. Когда вы импортируете x.so
, загрузчик обнаружит, что он уже загрузил xyz.so
, и будет использовать уже загруженный модуль, а не искать его снова.
С. Если вы создаете x.so
самостоятельно, вы можете добавить -Wl,-rpath=/some/path
в свою линию ссылок, а затем импортировать x.so
приведет к тому, что загрузчик будет искать зависимые модули в /some/path
.
Ответ 2
Основываясь на ответе от "Занятый русский", это то, что работает для меня.
oracle_libs = os.environ['ORACLE_HOME']+"/lib/"
rerun = True
if not 'LD_LIBRARY_PATH' in os.environ:
os.environ['LD_LIBRARY_PATH'] = ":"+oracle_libs
elif not oracle_libs in os.environ.get('LD_LIBRARY_PATH'):
os.environ['LD_LIBRARY_PATH'] += ":"+oracle_libs
else:
rerun = False
if rerun:
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
Ответ 3
В моем опыте, пытаясь изменить способ работы загрузчика для запущенного Python, очень сложно; вероятно, зависит от ОС/версии; может не работать. Одной рабочей задачей, которая может помочь в некоторых случаях, является запуск подпроцесса, который изменяет параметр среды с помощью оболочки script, а затем запускает новый Python с помощью оболочки.
Ответ 4
Ну, переменные среды хранятся в словаре os.environ, поэтому, если вы хотите изменить, вы можете сделать
os.environ["PATH"] = "/usr/bin"