Python neden sys.path içindeki dizinlerde bulunan paylaşılan nesneleri bulamıyor?


125

İçeri aktarmaya çalışıyorum 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

Şimdi, libcurl.so.4içeride /usr/local/lib. Gördüğünüz gibi, burası 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']

Herhangi bir yardım çok takdir edilecektir.


LD_LIBRARY_PATHDoğru ayarlamadıysanız güncellenmiş cevabımı görün (yorumunuzda eksik bir iki nokta üst üste olduğunu düşündüm).
Vinay Sajip

1
Libcurl.so.4 adında bir yerde bozuk bir sembolik bağlantı var mı? Bana dosyayı buluyor, ancak açamıyor gibi görünüyor. Her şey başarısız olursa, tercümanı sıkıştırın ve başarısız aramayı arayın.
Charles Duffy

Yanıtlar:


158

sys.pathyalnızca Python modülleri aranır. Dinamik bağlantılı kitaplıklar için, aranan yollar içinde olmalıdır LD_LIBRARY_PATH. Senin olmadığını kontrol LD_LIBRARY_PATHiçerir /usr/local/libve bunları yapmazsa, onu ekleyin ve tekrar deneyin.

Biraz daha bilgi ( kaynak ):

Linux'ta, ortam değişkeni LD_LIBRARY_PATH, standart dizinler kümesinden önce kitaplıkların aranması gereken, iki nokta üst üste işaretiyle ayrılmış dizinler kümesidir; bu, yeni bir kitaplıkta hata ayıklarken veya özel amaçlar için standart olmayan bir kitaplık kullanırken yararlıdır. Ortam değişkeni LD_PRELOAD, /etc/ld.so.preload'ın yaptığı gibi, standart kümeyi geçersiz kılan işlevlerle paylaşılan kitaplıkları listeler. Bunlar yükleyici /lib/ld-linux.so tarafından gerçekleştirilir. LD_LIBRARY_PATH birçok Unix benzeri sistemde çalışırken, hepsinde çalışmadığına dikkat etmeliyim; örneğin, bu işlevsellik HP-UX'te mevcuttur, ancak ortam değişkeni SHLIB_PATH olarak mevcuttur ve AIX'de bu işlevsellik LIBPATH değişkeni (aynı sözdizimiyle, iki nokta üst üste ile ayrılmış bir liste) aracılığıyla sağlanır.

Güncelleme: ayarlamak LD_LIBRARY_PATHiçin, ideal olarak sizin ~/.bashrc dosyanızda veya eşdeğer dosyanızda aşağıdakilerden birini kullanın :

export LD_LIBRARY_PATH=/usr/local/lib

veya

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

Boşsa ilk formu (boş dizeye denktir veya hiç mevcut değilse), değilse ikinci formu kullanın. İhracatın kullanımına dikkat edin .


2
Teşekkürler. LD_LIBRARY_PATH ayarlamadı, bu nedenle: $ LD_LIBRARY_PATH = / usr / local / lib $ LD_LIBRARY_PATH / usr / local / lib Ama yine de aynı hatayı alıyorum: $ python -c "import pycurl" Traceback (en son çağrı): Dosya "<string>", satır 1, <module> içinde ImportError: libcurl.so.4: paylaşılan nesne dosyası açılamıyor: Böyle bir dosya veya dizin yok

2
LD_LIBRARY_PATH değişkenini ayarladıktan sonra kullanıcıma kitaplığı okuma izni vermem gerekiyordu. Şimdi nihayet çalışıyor.
José Ricardo

57

Libcurl.so modülünüzün, python kitaplık yolundan farklı ve ayrı olan sistem kitaplığı yolunda olduğundan emin olun.

"Hızlı düzeltme", bu yolu bir LD_LIBRARY_PATH değişkenine eklemektir. Bununla birlikte, bu sistemi geniş (veya hatta hesap çapında) ayarlamak KÖTÜ bir FİKİRdir, çünkü onu bazı programların olmaması gereken bir kitaplık bulacağı veya daha da kötüsü güvenlik açıkları açacağı şekilde ayarlamak mümkündür.

"Yerel olarak yüklenmiş kitaplıklarınız", örneğin / usr / local / lib dizinine kuruluysa, bu dizini /etc/ld.so.conf'a ekleyin (bir metin dosyasıdır) ve "ldconfig" komutunu çalıştırın

Komut bir önbelleğe alma yardımcı programını çalıştıracak, ancak aynı zamanda yükleyici sisteminin çalışması için gerekli olan tüm gerekli "sembolik bağlantıları" da oluşturacaktır. Libcurl için "make install" komutunun bunu halihazırda yapmamış olması şaşırtıcıdır, ancak / usr / local / lib zaten /etc/ld.so.conf içinde değilse bunu yapamazdı.

Not: /etc/ld.so.conf dosyanızın "include ld.so.conf.d / *. Conf" dışında hiçbir şey içermesi mümkündür. Yine de ondan sonra bir dizin yolu ekleyebilir veya dahil edildiği dizinin içinde yeni bir dosya oluşturabilirsiniz. Bundan sonra "ldconfig" komutunu çalıştırmayı unutmayın.

Dikkatli ol. Bunu yanlış yapmak sisteminizi alt üst edebilir.

Ek olarak: python modülünüzün libcurl'un BU sürümüne göre derlendiğinden emin olun. Bazı dosyaları başka bir sistemden kopyaladıysanız, bu her zaman işe yaramayacaktır. Şüpheniz varsa, modüllerinizi çalıştırmayı düşündüğünüz sistemde derleyin.


Teşekkürler - bu işe yaradı. Daha önce LD_LIBRARY_PATH değişkenini değiştirmeye çalıştığım "hızlı düzeltme" girişimimin neden işe yaramadığını merak ediyorum.

2
Bir çok faktöre bağlıdır. İşte bir olasılık: kodunuz apache veya cron'dan çalıştırılıyordu. Bu programlar genellikle ortamı "temizler", bu nedenle ortam değişkenlerini almak için fazladan şeyler yapmanız gerekir. Örneğin, apache'de "SetEnv" veya değişkeni cron için crontab dosyasında doğru olarak ayarlama. Hata olasılıkları sonsuzdur!
Ch'marr

24

Ayrıca, pycurl'yi ilk etapta derlerken kullanıcı ortamınızda LD_RUN_PATH'yi / usr / local / lib olarak da ayarlayabilirsiniz. Bu, / usr / local / lib'yi C uzantı modülünün RPATH özniteliğine yerleştirir, böylece çalışma zamanında LD_LIBRARY_PATH'nin ayarlanması gerekmeden kitaplığı çalışma zamanında nerede bulacağını otomatik olarak bilir.


4
Alternatif olarak, rpath'tapython setup.py build_ext --rpath=/usr/local/lib pişirmek için genişletme modülünü oluştururken kullanın
kynan

10

Aynı sorunu yaşadım. Üretim sunucularımızdaki mevcut curl'yi etkilemeyeceğimden emin olmak için curl 7.19'u / opt / curl / konumuna yükledim. Libcurl.so.4'ü / usr / lib'ye bağladıktan sonra:

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

Hala aynı hatayı alıyorum! Durf.

Ama ldconfig'i çalıştırmak benim için bağlantıyı kurdu ve bu işe yaradı. LD_RUN_PATH veya LD_LIBRARY_PATH'ı ayarlamaya hiç gerek yok. Sadece ldconfig'i çalıştırmamız gerekiyor.


Ya sudo ayrıcalığım yoksa? Ldconfig'i çalıştıramıyorum? O halde yukarıdaki hatayı temizlemenin herhangi bir yolu var mı?
Prasanna

2
@SPRajagopal: sistem özniteliklerini değiştirme yetkiniz yoksa LD_LIBRARY_PATH, yukarıda açıklanan ortam değişkeni yöntemini kullanmanız gerekir . Eğer onu ~/.bashrc(bu ayarın eklenmesi iyi bir fikir IMO'su değildir) içinde ayarlamak istemiyorsanız, bu değişkeni ayarlayan bir kabuk betiği yazabilir, ardından python çalıştırabilir ve sonra bu betiği çağırabilirsiniz.
MadScientist

8

Yukarıdaki cevaplara ek olarak - sadece benzer bir problemle karşılaşıyorum ve tamamen varsayılan yüklü python ile çalışıyorum.

Aradığım paylaşılan nesne kitaplığı örneğini aradığımda LD_LIBRARY_PATH, şöyle bir şey elde ediyorum:

$ 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

Bilhassa, içe aktarımdan şikayet bile etmiyor - kaynak dosyadan şikayet ediyor!

Ancak şunu kullanarak nesneyi yüklemeye zorlarsam 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

... Hemen daha anlamlı bir hata mesajı alıyorum - eksik bağımlılık hakkında!

Bunu buraya not edeyim dedim - şerefe!


OP'nin hatasından önce meydana gelen yeni bir hata olmadığından emin misiniz?
David Knipe

1

Kullandığım python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0ve derlenmiş .bu dosya oluşturma klasörünün altındadır. python setup.py --help build_ext-R ve -I'nin açıklamalarını görmek için yazabilirsiniz


1

Benim için burada işe yarayan şey, proje ortamlarınızı ve paket sürümlerinizi iyi yönetmenizi ve işletim sisteminden ayrı tutmanızı şiddetle tavsiye ettiğim pyenv gibi bir sürüm yöneticisi kullanmaktır .

Bir işletim sistemi güncellemesinden sonra aynı hatayı aldım, ancak pyenv install 3.7-dev(kullandığım sürüm) ile kolayca düzeltildi .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.