在python中导入之前设置LD_LIBRARY_PATH

2024-08-01 12:12:12 发布

您现在位置:Python中文网/ 问答频道 /正文

Python使用PYTHONPATH环境变量来确定它应该在哪些文件夹中查找模块。 您可以通过修改sys.path来使用它,这对纯Python模块非常有用。 但是,当一个模块使用共享对象文件或静态库时,它会在LD_LIBRARY_PATH(linux上)中查找这些文件,但就我所知,这是不容易更改的,并且依赖于平台的。

当然,解决这个问题的快速方法是设置环境变量或调用类似于LD_LIBRARY_PATH=. ./script.py的脚本,但是之后必须为打开的每个新shell重新设置它。 另外,我的例子中的.so文件将始终与.py文件位于同一目录中,但很可能会移动到另一个绝对路径,因此我希望每次调用脚本时都自动设置它们。

如何编辑Python解释器在运行时独立查找库平台的路径?

编辑:

我已经试过了,但是没有成功。


Tags: 模块文件path对象py脚本文件夹编辑
3条回答

我解决这个问题的方法是将其作为Python脚本的第一行(而不是通常的shebang):

exec env LD_LIBRARY_PATH=/some/path/to/lib /path/to/specific/python -x "$0" "$@"

这就是它的工作原理:

  • 如果没有shebang,当前的shell将文件视为shell脚本
  • “exec”确保第一行也是shell执行的来自该文件的最后一个命令
  • “env”用于设置任何环境变量,例如LD_LIBRARY_PATH
  • 可以指定Python解释器的确切路径,或者“env”可以在路径中找到一个
  • “-x”是Python的选项,它导致Python解释器忽略第一行
  • “$0”是脚本名,“$@”由位置参数替换。

Python在获取环境变量的值(如os.environ[‘LD_LIBRARY_PATH’]os.environ[‘PATH’])时,它会将这些值从其父进程的环境(通常是bash)复制到字典中(bash进程的环境get被携带到子进程,即运行Python的实例)。

您可以在bash的env命令输出中看到这个环境变量部分。

您还可以通过在修改任何环境变量后引入无限循环(while 1: pass),从/proc/<pid>/environ中查看/读取这个env数据。

如果在python脚本中修改后,从/proc/<pid>/environ中看到/读取这个变量值/数据,您将看到实际变量的数据没有被修改,尽管python脚本显示了一个已修改的字典键值,但它已更新。

当您在python脚本中修改env变量(如os.environ['LD_LIBRARY_PATH']='/<new_location>')时,实际发生的情况是它只是更新本地字典中的值,而本地字典中的值没有映射到进程的env变量部分。因此,它不会一直传播回来以反映当前流程的环境,因为只有本地字典被修改/更新/填充。

因此,如果希望反射新的环境变量,我们应该使用execv用新的环境变量数据覆盖进程的内存映像。

示例:

new_lib = '/<new_location>'
if not new_lib in os.environ['LD_LIBRARY_PATH']:
    os.environ['LD_LIBRARY_PATH'] += ':'+new_lib
    try:
        os.execv(sys.argv[0], sys.argv)
    except Exception as e:
        sys.exit('EXCEPTION: Failed to Execute under modified environment, '+e)

import xyz
#do something else

限制:理想情况下,python不应允许对os.environ变量进行此类修改。 但由于没有常量字典数据类型,因此允许修改数据变量。修改这些值完全没有用处,因为除非使用execv,否则它在运行进程的实际环境中没有任何有用的反映。

我会用:

import os

os.environ['LD_LIBRARY_PATH'] = os.getcwd()  # or whatever path you want

这只为当前进程的执行持续时间/生存期设置LD_LIBRARY_PATH环境变量。

编辑:似乎需要在启动Python之前设置此项:Changing LD_LIBRARY_PATH at runtime for ctypes

所以我建议使用包装器.sh(或者.py,如果你坚持的话)脚本。另外,正如@chepner所指出的,您可能需要考虑将.so文件安装在标准位置(在virtualenv中)。

另见Setting LD_LIBRARY_PATH from inside Python

相关问题 更多 >