在 python 中导入之前设置 LD_LIBRARY_PATH

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23244418/
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-19 02:34:38  来源:igfitidea点击:

Set LD_LIBRARY_PATH before importing in python

pythonimportenvironment-variablessys

提问by iFreilicht

Python uses the PYTHONPATHenvironment-variable to determine in which folders it should look for modules. You can play around with it by modifying sys.path, which works nicely for pure Python-Modules. But when a module uses shared object files or static libraries, it looks for those in LD_LIBRARY_PATH(on linux), but this can't be changed as easily and is platform dependent as far as I know.

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

The quick-fix for this problem is of course to set the environment-variable or invoke the script like LD_LIBRARY_PATH=. ./script.py, but then you'll have to set it again for every new shell you open. Also, the .sofiles in my case will always be in the same directory as the .pyfile, but may very well be moved to another absolute path, so I'd like to set them automatically every time I invoke the script.

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

How can I edit the path in which the Python interpreter looks for libraries platform-independently on runtime?

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

EDIT:

编辑:

I already tried os.environ['LD_LIBRARY_PATH'] = os.getcwd(), but to no avail.

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

采纳答案by Erik Kaplun

I would use:

我会用:

import os

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

This sets the LD_LIBRARY_PATHenvironment variable for the duration/lifetime of the execution of the current process only.

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

EDIT:it looks like this needs to be set before starting Python: Changing LD_LIBRARY_PATH at runtime for ctypes

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

So I'd suggest going with a wrapper .sh(or .pyif you insist) script. Also, as @chepner pointed out, you might want to consider installing your .sofiles in a standard location (within the virtualenv).

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

See also Setting LD_LIBRARY_PATH from inside Python

另请参阅从 Python 内部设置 LD_LIBRARY_PATH

回答by S471

Python, when gets the values of environment variables as in os.environ[‘LD_LIBRARY_PATH']or os.environ[‘PATH'], it copies the values, into a dictionary, from it's parent process's environment, generally bash (bash process's environment get's carried to the child process, the python running instance).

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

you can see this environment variable section with envcommand output from bash.

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

you can also see/read this env data from /proc/<pid>/environ, by introducing an infinite loop(while 1: pass) after modifying any environment variable.

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

If you see/read this variable value/data from /proc/<pid>/environafter modifying it inside the python script, you would get to see that the real variable's data doesn't get modified, though the python script shows a modified dictionary key value, updated.

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

What actually happens when you modify an env variable inside python script, as in os.environ['LD_LIBRARY_PATH']='/<new_location>', is that it just updates the value in local dictionary, which is not mapped to process's env variable section. Hence it won't propagate all the way back to reflect in current process's environment, because ONLY a local dictionarywas modified/updated/populated.

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

Hence if we want to have the new environment variable to be reflected, we should overwrite the memory image of the process with new environment variable data, using execv.

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

Example:

例子:

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

Limitation: Ideally, python should not allow such modification of os.environvariables. But because there is no constant dictionary data type, it allows modification of the data variable. There is absolutely no use of modifying the values, as it does nothing useful to reflect in running process's real environment, unless execvis used.

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

回答by Jarek

My solution to this problem is to put this as the first line of a Python script (instead of the usual shebang):

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

exec env LD_LIBRARY_PATH=/some/path/to/lib /path/to/specific/python -x "
import sys
import os
sys.path.insert(1, os.environ['LD_LIBRARY_PATH'])

" "$@"

And here is how this works:

这是它的工作原理:

  • with no shebang the current shell treats the file as a shell script,
  • "exec" ensures that this first line is also the last command from this file executed by the shell,
  • "env" is used here to set any environment variables, e.g. LD_LIBRARY_PATH,
  • an exact path to Python's interpreter can specified or "env" can find one in PATH,
  • "-x" is a Python's option which causes the first line to be ignored by the Python interpreter,
  • "$0" is the script name, "$@" is substituted by positional parameters.
  • 没有shebang,当前shell将文件视为shell脚本,
  • "exec" 确保第一行也是 shell 执行的这个文件中的最后一个命令,
  • “env”在这里用于设置任何环境变量,例如 LD_LIBRARY_PATH,
  • 可以指定 Python 解释器的确切路径,或者“env”可以在 PATH 中找到一个,
  • “-x”是 Python 的选项,它会导致 Python 解释器忽略第一行,
  • “$0”是脚本名称,“$@”由位置参数代替。

回答by Senal Weerasinghe

I have used it as below,

我已经使用它如下,

import sys
import os

sys.path.insert(1, os.environ['LD_LIBRARY_PATH'])
import X

  • You can import other static libraries which are in "LD_LIBRARY_PATH" after the above code snippet. E.g. Let's assume "X" is a python library which uses a static library in "LD_LIBRARY_PATH". Then you should implement python code as below.
  • 您可以在上述代码片段之后导入“LD_LIBRARY_PATH”中的其他静态库。例如,假设“X”是一个使用“LD_LIBRARY_PATH”中的静态库的python 库。然后你应该实现如下的python代码。
##代码##