从 Python 内部设置 LD_LIBRARY_PATH

发布于 2024-11-18 09:24:52 字数 689 浏览 6 评论 0原文

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

我有 fontforge.so 位于 fontforge_bin 并尝试了以下操作

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

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

fontforge_bin/fontforge.so 上执行 ldd给出以下

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)

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

I have fontforge.so located in fontforge_bin and tried the following

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 ldd on fontforge_bin/fontforge.so gives the following

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁吢 2024-11-25 09:24:52

您的脚本可以在导入模块之前检查环境变量是否存在/正确,如果缺少,则在 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

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

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.

This is only advisable before any 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.

This code sets LD_LIBRARY_PATH and 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).

淡淡の花香 2024-11-25 09:24:52

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

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

或者迭代该目录中的文件...您明白了,一旦加载它就在那里为您提供[如果依赖项也超出了默认路径,您也应该加载它们...]。

...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.

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...].

薯片软お妹 2024-11-25 09:24:52

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'

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

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

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

# 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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文