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

118 python shared-libraries libcurl pycurl

我正在尝试导入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
Run Code Online (Sandbox Code Playgroud)

现在,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']
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

Vin*_*jip 152

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

更多信息(来源):

在Linux中,环境变量LD_LIBRARY_PATH是一组冒号分隔的目录,其中应首先在标准目录集之前搜索库; 这在调试新库或使用非标准库用于特殊目的时非常有用.环境变量LD_PRELOAD列出了具有覆盖标准集的函数的共享库,就像/etc/ld.so.preload那样.这些是由loader /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
Run Code Online (Sandbox Code Playgroud)

要么

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)

如果第一个表单为空(相当于空字符串,或根本不存在),则使用第一个表单,如果不存在,则使用第二个表单.注意使用导出.

  • 谢谢.我的LD_LIBRARY_PATH没有设置,所以:$ LD_LIBRARY_PATH =/usr/local/lib $ LD_LIBRARY_PATH/usr/local/lib但我仍然得到同样的错误:$ python -c"import pycurl"Traceback(最近一次调用最后一次):File "<string>",第1行,在<module> ImportError:libcurl.so.4:无法打开共享对象文件:没有这样的文件或目录 (2认同)
  • 设置LD_LIBRARY_PATH变量后,我还必须授予用户读取库的权限。现在终于可以了。 (2认同)

Ch'*_*arr 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编译的.如果你刚刚从另一个系统复制了一些文件,这不会一直有效.如果有疑问,请在要运行它们的系统上编译模块.

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

Gra*_*ton 24

当您首先编译pycurl时,您还可以在用户环境中将LD_RUN_PATH设置为/ usr/local/lib.这将在/扩展模块.so的RPATH属性中嵌入/ usr/local/lib,以便它在运行时自动知道在哪里找到库,而无需在运行时设置LD_LIBRARY_PATH.

  • 或者,在构建扩展模块以在*rpath*中烘焙时,使用`python setup.py build_ext --rpath =/usr/local/lib` (4认同)

Mat*_*att 11

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

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

我仍然有同样的错误!Durf.

但是运行ldconfig会为我建立联系,这样就可以了.根本不需要设置LD_RUN_PATH或LD_LIBRARY_PATH.只需要运行ldconfig.

  • 用于运行`ldconfig`的+1,所有错误都已修复 (2认同)
  • @SPRajagopal:如果您没有权限修改系统属性,则必须使用上述的`LD_LIBRARY_PATH`环境变量方法.如果您不想在`〜/ .bashrc`中设置它(添加该设置不是一个好主意IMO),您可以编写一个shell脚本来设置此变量然后运行python,然后调用该脚本. (2认同)

sda*_*aau 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
Run Code Online (Sandbox Code Playgroud)

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

但是如果我使用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
Run Code Online (Sandbox Code Playgroud)

...我立即得到一条更有意义的错误消息 - 关于遗漏的依赖!

我以为我会在这里记下这一点 - 干杯!