Python 更改当前流程环境';s LD_库_路径

Python 更改当前流程环境';s LD_库_路径,python,shared-libraries,environment-variables,Python,Shared Libraries,Environment Variables,是否可以更改当前流程的环境变量 更具体地说,在python脚本中,我想更改LD\u LIBRARY\u路径,以便在导入依赖于某个xyz.so的模块“x”时,xyz.so从LD\u LIBRARY\u路径中的给定路径中获取 是否有其他方法可以动态更改加载库的路径 编辑:我想我需要指出的是,我已经尝试过类似的方法 os.environ[“LD_LIBRARY_PATH”]=mypath os.putenv('LD\u LIBRARY\u PATH',mypath) 但这些改变了环境。对于生成的子进程

是否可以更改当前流程的环境变量

更具体地说,在python脚本中,我想更改
LD\u LIBRARY\u路径
,以便在导入依赖于某个
xyz.so
的模块“x”时,
xyz.so
从LD\u LIBRARY\u路径中的给定路径中获取

是否有其他方法可以动态更改加载库的路径

编辑:我想我需要指出的是,我已经尝试过类似的方法 os.environ[“LD_LIBRARY_PATH”]=mypath os.putenv('LD\u LIBRARY\u PATH',mypath)

但这些改变了环境。对于生成的子进程,不是当前进程,模块加载不考虑新的LD-LabyAythPixe


Edit2,所以问题是我们可以更改环境或其他东西,以便库加载器看到它并从那里加载吗?

好的,环境变量存储在字典os.environ中,所以如果您想更改,可以这样做

os.environ["PATH"] = "/usr/bin"

根据我的经验,试图改变加载程序在运行Python时的工作方式是非常棘手的;可能与操作系统/版本相关;可能不行。在某些情况下,一个可能有帮助的解决方法是启动一个子进程,使用shell脚本更改环境参数,然后使用shell启动一个新的Python。

原因

os.environ["LD_LIBRARY_PATH"] = ...
不工作很简单:此环境变量控制动态加载程序的行为(
ld linux.so.2
在linux上,ld.so.1在Solaris上),但加载程序只在进程启动时查看一次
ld\u LIBRARY\u PATH
。在该点之后,在当前进程中更改
LD_LIBRARY_PATH
的值没有任何效果(正如问题的答案所说)

您确实有一些选择:

A.如果您知道您将需要
xyz.so
/some/path
开始,并从一开始就控制python脚本的执行,那么只需根据您的喜好设置
LD_LIBRARY_path
(检查是否已设置),然后重新执行您自己的脚本。这就是
Java
所做的

B.在导入
x.so
之前,可以通过其绝对路径导入
/some/path/xyz.so
。然后导入
x.so
时,加载程序将发现它已加载
xyz.so
,并将使用已加载的模块,而不是再次搜索它


C.如果您自己构建
x.so
,您可以将
-Wl,-rpath=/some/path
添加到其链接行,然后导入
x.so
将导致加载程序在
/some/path

中查找依赖模块,这对我来说是有效的

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)

我认为您必须确保在模块x的import语句之前设置os.ENVIRO[“LD_LIBRARY_PATH”]。请参见编辑,我已经尝试了此操作,但此操作不起作用。如我在回答中所述,以这种方式设置LD_LIBRARY_PATH不会影响当前进程。这不是重复的吗?实际上,您并不是问如何更改环境,而是问如何更改python从何处加载库。ok!我会说这是重复的,但它不是abt python关于改变环境的,例如,在一个加载动态库a的c应用程序中,我们可以改变环境以便从我们选择的路径加载a吗?B看起来像是一个我可以使用的选项。选项B如何实现?我认为OP暗示了
/some/path/xyz。因此
是Python模块所依赖的共享库<因此
本身不包含Python模块。我有一个类似的情况,不知道有什么方法可以按照您描述的方式导入库。@JasonR选项B可以使用
import dl;dl.open(“/some/path/xyz.so”)
未完成;谢谢事实证明,
dl
模块在Python2.6中是不推荐使用的,但是您可以对
importcTypes执行相同的操作;ctypes.cdll.LoadLibrary(“/some/path/xyz.so”)
@Gregory:是的。我使用了我在上面的评论中指出的语法,使用了
ctypes
,对我来说效果很好。您的Python模块可能还依赖于其他一些未正确加载的共享库。execve技巧正是我所需要的,它可以正常工作,请向上投票!