从Python内部设置LD_LIBRARY_PATH

Yar*_*tov 20 python linux fontforge

有没有办法在运行时设置指定Python查找共享库?

fontforge.so找到了fontforge_bin并尝试了以下内容

os.environ['LD_LIBRARY_PATH']='fontforge_bin'
sys.path.append('fontforge_bin')
import fontforge
Run Code Online (Sandbox Code Playgroud)

得到

ImportError: fontforge_bin/fontforge.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)

这样lddfontforge_bin/fontforge.so提供了以下

linux-vdso.so.1 =>  (0x00007fff2050c000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f10ffdef000)
libc.so.6 => /lib/libc.so.6 (0x00007f10ffa6c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f110022d000)
Run Code Online (Sandbox Code Playgroud)

小智 18

您的脚本可以在导入模块之前检查环境变量的存在/正确性,然后在os.environ中将其设置为缺失,然后调用os.execv()以使用相同的命令行参数重新启动python解释器但是一组更新的环境变量.

这仅任何其他导入(os和sys除外)之前是可取的,因为潜在的模块导入副作用(如打开的文件描述符或套接字)可能很难干净地关闭.

此代码设置LD_LIBRARY_PATH和ORACLE_HOME:

#!/usr/bin/python
import os, sys
if 'LD_LIBRARY_PATH' not in os.environ:
    os.environ['LD_LIBRARY_PATH'] = '/usr/lib/oracle/XX.Y/client64/lib'
    os.environ['ORACLE_HOME'] = '/usr/lib/oracle/XX.Y/client64'
    try:
        os.execv(sys.argv[0], sys.argv)
    except Exception, exc:
        print 'Failed re-exec:', exc
        sys.exit(1)
#
# import yourmodule
print 'Success:', os.environ['LD_LIBRARY_PATH']
# your program goes here
Run Code Online (Sandbox Code Playgroud)

将该环境变量设置为起始环境的一部分(在父进程或systemd/etc作业文件中)可能更简洁.


paw*_*ech 10

...你可以通过ctypes从你选择的某个文件夹中加载所有库,从而使它们可用,无论LD_LIBRARY_PATH如何.

from ctypes import *
lib1 = cdll.LoadLibrary('/home/username/lib/some_library.so')
Run Code Online (Sandbox Code Playgroud)

或者遍历那个目录中的文件...你明白了,一旦它被加载它就在那里[如果依赖关系也超出了你应该加载它们的默认路径......].

  • 如果您的 so 文件有进一步的依赖项,这将不起作用...... (3认同)
  • 没有为我工作。随后导入使用它的模块时仍然找不到该库。 (2认同)
  • 我确认此解决方案在与问题中描述的场景非常相似的场景中起作用。在 Linux (Ubuntu 16.04) 中。需要在同一本地路径中导入依赖于 libfoo.so 的本机 Python 模块 foo.so。首先,我尝试在 foo.so 中将 RPATH 设置为 `$ORIGIN/.`。只有当我在同一目录中运行脚本时它才有效。 (2认同)

Gle*_*ard 6

LD_LIBRARY_PATH设置动态链接器路径; 通常不能在运行时更改,因为它通常由动态链接器缓存.

但是,这不是Python寻找导入的地方,包括模块导入.改变sys.path是正确的.

# ls foo/
_csv.so
# python
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
>>> import sys
>>> sys.path.insert(0, "foo")
>>> import _csv
>>> _csv.__file__
'foo/_csv.so'
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,您可能希望在库中查看库中是否有任何奇怪的导入路径."ImportError:fontforge_bin/fontforge.so"看起来很奇怪.)