Linux 从 Python 内部设置 LD_LIBRARY_PATH

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6543847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:51:52  来源:igfitidea点击:

Setting LD_LIBRARY_PATH from inside Python

pythonlinuxfontforge

提问by Yaroslav Bulatov

Is there a way to set specify during runtimewhere Python looks for shared libraries?

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

I have fontforge.solocated in fontforge_binand tried the following

我已经fontforge.so找到fontforge_bin并尝试了以下

os.environ['LD_LIBRARY_PATH']='fontforge_bin'
sys.path.append('fontforge_bin')
import fontforge

and get

并得到

ImportError: fontforge_bin/fontforge.so: cannot open shared object file: No such file or directory

Doing lddon fontforge_bin/fontforge.sogives the following

这样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)

回答by Glenn Maynard

LD_LIBRARY_PATHsets the dynamic linker path; that generally can't be changed at runtime, since it's usually cached by the dynamic linker.

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

That's not where Python looks for imports, though, including module imports. Changing sys.pathis correct.

然而,这不是 Python 寻找import 的地方,包括模块导入。改变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'

(By the way, you may want to ldd the library to see if you have any odd import paths in the library. "ImportError: fontforge_bin/fontforge.so" looks strange.)

(顺便说一句,您可能想要 ldd 库以查看库中是否有任何奇怪的导入路径。“ImportError: fontforge_bin/fontforge.so”看起来很奇怪。)

回答by pawelmech

...well sort of you could load all libraries from some folder of your choosing via ctypes and thus make them available for you regardless of the LD_LIBRARY_PATH.

...好吧,您可以通过 ctypes 从您选择的某个文件夹加载所有库,从而使它们可供您使用,而不管 LD_LIBRARY_PATH。

from ctypes import *
lib1 = cdll.LoadLibrary('/home/username/lib/some_library.so')

or iterate through the files in that dir... you get the idea, once it is loaded it is there for you [if the dependencies are also out of the default path you should load them too...].

或遍历该目录中的文件......你明白了,一旦加载它就在那里[如果依赖项也在默认路径之外,你也应该加载它们......]。

回答by Will Pierce

Your script can check for the existence/properness of the environment variable before you import your module, then set it in os.environ if it is missing, and then call os.execv()to restart the python interpreter using the same command line arguments but an updated set of environment variables.

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

This is only advisable beforeany other imports (other than os and sys), because of potential module-import side-effects, like opened file descriptors or sockets, which may be challenging to close cleanly.

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

This code sets LD_LIBRARY_PATH and ORACLE_HOME:

此代码设置 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

It's probably cleaner to set that environment variable as part of the starting environment (in the parent process or systemd/etc job file).

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