在python中导入之前设置LD_LIBRARY_PATH

iFr*_*cht 34 python import environment-variables sys

Python使用PYTHONPATH环境变量来确定它应该在哪些文件夹中查找模块.您可以通过修改来解决它sys.path,它可以很好地用于纯Python模块.但是当一个模块使用共享对象文件或静态库时,它会在LD_LIBRARY_PATH(在linux上)查找它们,但是根据我所知,这不能轻易改变并且是平台相关的.

这个问题的快速修复当然是设置环境变量或调用脚本LD_LIBRARY_PATH=. ./script.py,但是你必须为你打开的每个新shell再次设置它.此外,.so我的情况下的文件将始终与文件位于同一目录中.py,但很可能会移动到另一个绝对路径,所以我想每次调用脚本时自动设置它们.

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

编辑:

我已经尝试过os.environ['LD_LIBRARY_PATH'] = os.getcwd(),但无济于事.

Eri*_*lun 20

我会用:

import os

os.environ['LD_LIBRARY_PATH'] = os.getcwd()  # or whatever path you want
Run Code Online (Sandbox Code Playgroud)

这将LD_LIBRARY_PATH仅为当前进程的执行的持续时间/生命周期设置环境变量.

编辑:看起来这需要在启动Python之前设置:在运行时为ctypes更改LD_LIBRARY_PATH

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

另请参阅从Python内部设置LD_LIBRARY_PATH

  • 抱歉,我应该提到我已经尝试过了,但它不起作用,之后的导入语句仍然会抛出“ImportError”,如果我使用“LD_LIBRARY_PATH=”调用脚本,则不会发生“ImportError”。./script.py`。 (3认同)

S47*_*471 9

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

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

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

如果您/proc/<pid>/environ在 python 脚本中修改它之后看到/读取此变量值/数据,您将看到实际变量的数据没有被修改,尽管 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
Run Code Online (Sandbox Code Playgroud)

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

  • 不,这不应该是只读命令。修改 os.environ 很有用,因为它是传递给子进程的内容(这就是你的 execve 技巧起作用的原因)。Python *不*将环境复制到“dict”中;它通过`getenv`/`putenv`访问进程的环境。您的更大观点仍然是正确的:更改环境不会影响当前流程。尤其是在你的 python 代码运行时,`LD_LIBRARY_PATH` 已经被查询过。来自“man dlopen”:“如果在程序启动时定义了环境变量 LD_LIBRARY_PATH...” (2认同)

Jar*_*rek 9

我对这个问题的解决方案是把它作为Python脚本的第一行(而不是通常的shebang):

exec env LD_LIBRARY_PATH=/some/path/to/lib /path/to/specific/python -x "$0" "$@"
Run Code Online (Sandbox Code Playgroud)

这是如何工作的:

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