更改当前进程环境的LD_LIBRARY_PATH

26 投票
5 回答
31908 浏览
提问于 2025-04-15 13:08

有没有办法改变当前程序的环境变量?

具体来说,我想在一个Python脚本中修改一下LD_LIBRARY_PATH,这样在导入一个依赖于某个xyz.so的模块'x'时,xyz.so就能从我指定的LD_LIBRARY_PATH路径中加载。

有没有其他方法可以动态改变库的加载路径呢?

编辑:我想我需要提一下,我已经尝试过这样的代码: os.environ["LD_LIBRARY_PATH"] = mypath os.putenv('LD_LIBRARY_PATH', mypath)

但是这些方法只会修改新创建的子进程的环境,而不会影响当前的进程,所以模块加载时并不会考虑新的LD_LIBRARY_PATH

编辑2,所以我的问题是,我们能不能改变环境变量或者其他什么,让库加载器能看到这个变化并从那里加载呢?

5 个回答

0

根据我的经验,想要在运行中的Python程序里改变加载器的工作方式是非常棘手的。这可能跟操作系统和版本有关,可能还不一定能成功。有一种可能的解决办法是在某些情况下可以尝试,就是启动一个子进程,通过一个shell脚本来改变环境参数,然后再用这个shell启动一个新的Python程序。

16

根据Employed Russian的回答,这个方法对我有效

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)
39

原因

os.environ["LD_LIBRARY_PATH"] = ...

不工作的原因很简单:这个环境变量控制动态加载器的行为(在Linux上是ld-linux.so.2,在Solaris上是ld.so.1),但是加载器只在进程启动时查看一次LD_LIBRARY_PATH。在那之后,如果你在当前进程中改变LD_LIBRARY_PATH的值,是没有任何效果的(就像这个问题的回答所说的那样)。

你有几个选择:

A. 如果你知道自己会需要来自/some/pathxyz.so,并且可以从一开始就控制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寻找依赖的模块。

撰写回答