Почему Python не может найти общие объекты, которые находятся в каталогах в sys.path?

Я пытаюсь импортировать 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']

Любая помощь будет оценена.


person Community    schedule 08.07.2009    source источник
comment
См. Мой обновленный ответ, если вы неправильно установили LD_LIBRARY_PATH (я думал, что в вашем комментарии отсутствует двоеточие).   -  person Vinay Sajip    schedule 09.07.2009
comment
Есть ли сломанная символическая ссылка где-нибудь с именем libcurl.so.4? Мне кажется, он находит файл, но не может его открыть. Если все остальное не помогает, ограничьте интерпретатор и найдите вызов, который не дает сбоя.   -  person Charles Duffy    schedule 10.07.2009


Ответы (7)


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

or

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

Используйте первую форму, если она пуста (эквивалентна пустой строке или вообще отсутствует), и вторую форму, если это не так. Обратите внимание на использование экспорта.

person Vinay Sajip    schedule 08.07.2009
comment
Спасибо. Мой 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: невозможно открыть файл общих объектов: нет такого файла или каталога - person ; 08.07.2009
comment
Мне также пришлось предоставить моему пользователю разрешение на чтение библиотеки после установки переменной LD_LIBRARY_PATH. Теперь это наконец-то работает. - person José Ricardo; 31.07.2013

Убедитесь, что ваш модуль libcurl.so находится в пути к системной библиотеке, который отличается и отличается от пути к библиотеке python.

«Быстрое решение» - добавить этот путь к переменной LD_LIBRARY_PATH. Однако установка этой системы (или даже учетной записи) является ПЛОХОЙ ИДЕЕЙ, поскольку ее можно настроить таким образом, чтобы некоторые программы находили библиотеку, которую не должны, или, что еще хуже, открывать дыры в безопасности.

Если ваши «локально установленные библиотеки» установлены, например, в / usr / local / lib, добавьте этот каталог в /etc/ld.so.conf (это текстовый файл) и запустите «ldconfig»

Команда запустит утилиту кэширования, но также создаст все необходимые «символические ссылки», необходимые для работы системы загрузчика. Удивительно, что команда "make install" для libcurl этого еще не сделала, но возможно, что не может, если / usr / local / lib уже не находится в /etc/ld.so.conf.

PS: возможно, ваш /etc/ld.so.conf не содержит ничего, кроме «include ld.so.conf.d / *. Conf». Вы все равно можете добавить путь к каталогу после него или просто создать новый файл внутри каталога, из которого он включается. Не забудьте после него запустить "ldconfig".

Будь осторожен. Неправильный ответ может испортить вашу систему.

Дополнительно: убедитесь, что ваш модуль python скомпилирован с ЭТОЙ версией libcurl. Если вы просто скопировали некоторые файлы из другой системы, это не всегда сработает. В случае сомнений скомпилируйте свои модули в системе, в которой вы собираетесь их запускать.

person Ch'marr    schedule 08.07.2009
comment
Спасибо, это сработало. Интересно, почему моя предыдущая попытка быстрого исправления изменения переменной LD_LIBRARY_PATH не сделала этого. - person ; 09.07.2009
comment
Зависит от множества факторов. Вот одна возможность: ваш код запускался из apache или cron. Эти программы обычно очищают среду, поэтому вам нужно делать дополнительные вещи, чтобы получить переменные среды. Например, SetEnv в apache или установка переменной прямо в файле crontab для cron. Возможности для ошибок безграничны! - person Ch'marr; 04.09.2009

Вы также можете установить LD_RUN_PATH в / usr / local / lib в своей пользовательской среде при первой компиляции pycurl. Это встроит / usr / local / lib в атрибут RPATH модуля расширения C. Таким образом, он автоматически знает, где найти библиотеку во время выполнения, без необходимости устанавливать LD_LIBRARY_PATH во время выполнения.

person Graham Dumpleton    schedule 10.07.2009
comment
В качестве альтернативы используйте python setup.py build_ext --rpath=/usr/local/lib при создании модуля расширения для запекания в rpath - person kynan; 27.07.2013

Была точно такая же проблема. Я установил curl 7.19 в / opt / curl /, чтобы убедиться, что я не повлияю на текущий curl на наших производственных серверах. Как только я связал libcurl.so.4 с / usr / lib:

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

У меня все еще та же ошибка! Дурф.

Но запуск ldconfig сделал для меня связь, и это сработало. Нет необходимости устанавливать LD_RUN_PATH или LD_LIBRARY_PATH вообще. Просто нужно было запустить ldconfig.

person Matt    schedule 05.03.2010
comment
Что делать, если у меня нет привилегии sudo? Я не могу запустить ldconfig? Тогда есть ли способ сбросить указанную выше ошибку? - person sprajagopal; 04.07.2013
comment
@SPRajagopal: если у вас нет прав на изменение системных атрибутов, вы должны использовать метод переменной среды LD_LIBRARY_PATH, описанный выше. Если вы не хотите устанавливать его в своем ~/.bashrc (добавление этого параметра не является хорошей идеей, IMO), вы можете написать сценарий оболочки, который устанавливает эту переменную, затем запускает python, а затем вызывает этот сценарий. - person MadScientist; 07.08.2013

В дополнение к приведенным выше ответам - я просто сталкиваюсь с аналогичной проблемой и полностью работаю с установленным по умолчанию 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

... Я сразу получаю более содержательное сообщение об ошибке - об отсутствующей зависимости!

Просто подумал, что запишу это здесь - ура!

person sdaau    schedule 11.06.2012
comment
Вы уверены, что это не новая ошибка, которая возникает до ошибки OP? - person David Knipe; 23.02.2017

Я использую python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0, а скомпилированный файл .so находится в папке сборки. вы можете ввести python setup.py --help build_ext, чтобы увидеть объяснения -R и -I

person ScutterKey    schedule 22.04.2016

Для меня здесь работает диспетчер версий, такой как pyenv, который я настоятельно рекомендую получить среды проекта и версии пакетов хорошо управляются и отделены от операционной системы.

У меня была такая же ошибка после обновления ОС, но она была легко исправлена ​​с помощью pyenv install 3.7-dev (той версии, которую я использую).

person elcortegano    schedule 21.04.2020