为什么Python无法找到sys.path目录中的共享对象?


124

我正在尝试导入pycurl

$ python -c "import pycurl"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libcurl.so.4: cannot open shared object file: No such file or directory

现在,libcurl.so.4在中/usr/local/lib。如您所见,这是在sys.path

$ python -c "import sys; print(sys.path)"
['', '/usr/local/lib/python2.5/site-packages/setuptools-0.6c9-py2.5.egg', 
'/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', 
'/usr/local/lib/python2.5/plat-linux2', '/usr/local/lib/python2.5/lib-tk', 
'/usr/local/lib/python2.5/lib-dynload', 
'/usr/local/lib/python2.5/sitepackages', '/usr/local/lib', 
'/usr/local/lib/python2.5/site-packages']

任何帮助将不胜感激。


如果您的设置不LD_LIBRARY_PATH正确,请查看我更新的答案(我认为您的注释中缺少冒号)。
Vinay Sajip,2009年

1
在名为libcurl.so.4的某个地方是否存在断开的符号链接?在我看来,它正在查找文件,但无法打开它。如果其他所有方法均失败,则跟踪解释器并查找失败的调用。
查尔斯·达菲,2009年

Answers:


158

sys.path仅搜索Python模块。对于动态链接库,搜索的路径必须位于中LD_LIBRARY_PATH。检查您是否LD_LIBRARY_PATH包含了/usr/local/lib,如果没有,请添加并重试。

一些更多信息(来源):

在Linux中,环境变量LD_LIBRARY_PATH是用冒号分隔的目录集,在其中应首先搜索库,然后再搜索标准目录集;这在调试新库或出于特殊目的使用非标准库时很有用。环境变量LD_PRELOAD列出了具有覆盖标准集的功能的共享库,就像/etc/ld.so.preload一样。这些由加载程序/lib/ld-linux.so实现。我应该指出,虽然LD_LIBRARY_PATH在许多类Unix系统上都可以使用,但它并不是在所有系统上都可以使用。例如,此功能在HP-UX上可用,但作为环境变量SHLIB_PATH,在AIX上是通过变量LIBPATH(使用相同的语法,用冒号分隔的列表)来提供的。

更新:要设置LD_LIBRARY_PATH,最好在您的~/.bashrc 文件或等效文件中使用以下之一:

export LD_LIBRARY_PATH=/usr/local/lib

要么

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

如果第一种形式为空(等于空字符串,或者根本不存在),则使用第二种形式,如果不是,则使用第二种形式。注意使用导出


2
谢谢。我的LD_LIBRARY_PATH未设置,因此:$ LD_LIBRARY_PATH = / usr / local / lib $ LD_LIBRARY_PATH / usr / local / lib但我仍然遇到相同的错误:$ python -c“ import pycurl” Traceback(最近一次调用是最近的):文件“ <string>”,<模块> ImportError中的第1行:libcurl.so.4:无法打开共享对象文件:没有这样的文件或目录

2
设置LD_LIBRARY_PATH变量后,我还必须授予用户读取库的权限。现在终于可以了。
何塞·里卡多

56

确保您的libcurl.so模块位于系统库路径中,该路径与python库路径不同且独立。

“快速修复”是将此路径添加到LD_LIBRARY_PATH变量。但是,设置整个系统(甚至帐户范围)是一个糟糕的想法,因为可以通过某种方式设置它,以使某些程序会找到它不应该或者甚至更不希望打开安全漏洞的库。

如果您的“本地安装的库”安装在例如/ usr / local / lib中,请将此目录添加到/etc/ld.so.conf(这是一个文本文件),然后运行“ ldconfig”

该命令将运行缓存实用程序,但还将创建加载程序系统运行所需的所有必要“符号链接”。令人惊讶的是,libcurl的“ make install”尚未执行此操作,但如果/ usr / local / lib不在/etc/ld.so.conf中,则可能无法执行此操作。

PS:您的/etc/ld.so.conf可能只包含“ include ld.so.conf.d / *。conf”而不包含任何内容。您仍然可以在其后添加目录路径,或者只是在包含该目录的目录中创建一个新文件。不要忘记在它之后运行“ ldconfig”。

小心。弄错了会损坏您的系统。

另外:确保您的Python模块针对该版本的libcurl进行编译。如果您只是从其他系统复制了一些文件,则此方法将永远无法正常工作。如有疑问,请在要运行它们的系统上编译模块。


谢谢-这行得通。我不知道为什么我以前尝试过的“快速修复”更改LD_LIBRARY_PATH变量没有。

2
取决于很多因素。这是一种可能:您的代码是从apache或cron运行的。这些程序通常“清除”环境,因此您必须做一些额外的工作才能获取环境变量。例如,apache中的“ SetEnv”,或在crontab文件中为cron设置变量。错误的可能性是无限的!
Ch'marr

24

最初编译pycurl时,还可以在用户环境中将LD_RUN_PATH设置为/ usr / local / lib。这会将/ usr / local / lib嵌入C扩展模块。的RPATH属性中,以便它在运行时自动知道在哪里可以找到该库,而不必在运行时设置LD_LIBRARY_PATH。


4
或者,python setup.py build_ext --rpath=/usr/local/lib在构建扩展模块以在rpath中
kynan

10

有完全相同的问题。我将curl 7.19安装到/ opt / curl /中,以确保不会影响生产服务器上的当前curl。将libcurl.so.4链接到/ usr / lib之后:

须藤ln -s /opt/curl/lib/libcurl.so /usr/lib/libcurl.so.4

我仍然遇到相同的错误!杜尔夫

但是运行ldconfig可以使链接变得很有效。完全不需要设置LD_RUN_PATH或LD_LIBRARY_PATH。只需运行ldconfig。


如果我没有sudo特权怎么办?我无法运行ldconfig?那有什么办法可以清除上面的错误呢?
Prasanna

2
@SPRajagopal:如果您没有权限修改系统属性,则必须使用上述LD_LIBRARY_PATH环境变量方法。如果您不想在您的计算机中进行设置~/.bashrc(添加该设置不是IMO的好主意),则可以编写一个Shell脚本来设置此变量,然后运行python,然后调用该脚本。
MadScientist 2013年

8

作为上述答案的补充-我只是遇到了类似的问题,并且完全使用默认安装的python进行工作。

当我调用要使用的共享库的示例时LD_LIBRARY_PATH,会得到如下信息:

$ LD_LIBRARY_PATH=/path/to/mysodir:$LD_LIBRARY_PATH python example-so-user.py
python: can't open file 'example-so-user.py': [Errno 2] No such file or directory

值得注意的是,它甚至不抱怨导入-它抱怨源文件!

但是如果我使用LD_PRELOAD以下命令强制加载对象:

$ LD_PRELOAD=/path/to/mysodir/mypyobj.so python example-so-user.py
python: error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory

...我立即收到一条更有意义的错误消息-有关缺少的依赖项!

只是以为我会在这里写下来-干杯!


您确定这不是OP错误之前发生的新错误吗?
David Knipe

1

我使用的python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0是已编译的.so文件,该文件位于build文件夹下。您可以键入python setup.py --help build_ext以查看-R和-I的解释


1

对我来说,这里的工作是使用版本管理器,例如pyenv,我强烈建议您对项目环境和程序包版本进行良好的管理,并使其与操作系统的版本分开。

操作系统更新后,我也遇到了同样的错误,但是很容易用pyenv install 3.7-dev(我使用的版本)修复。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.