2009-07-08 17 views
90

Tôi đang cố gắng để nhập khẩu pycurl:Tại sao Python không thể tìm thấy các đối tượng được chia sẻ trong các thư mục trong sys.path?

$ 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 

Bây giờ, libcurl.so.4 là trong/usr/local/lib. Như bạn thấy, đây là trong 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'] 

Mọi trợ giúp sẽ được đánh giá cao.

+0

Xem câu trả lời cập nhật của tôi, trong trường hợp bạn không đặt 'LD_LIBRARY_PATH' đúng cách (tôi nghĩ bình luận của bạn có dấu hai chấm bị thiếu). –

+1

Có một liên kết bị hỏng nào đó có tên là libcurl.so.4 không? Có vẻ như tôi đang tìm tập tin nhưng không thể mở nó. Nếu vẫn thất bại, hãy truy tìm thông dịch viên và tìm kiếm cuộc gọi không thành công. –

Trả lời

124

sys.path chỉ được tìm kiếm cho các mô-đun Python. Đối với thư viện được liên kết động, đường dẫn được tìm kiếm phải nằm trong LD_LIBRARY_PATH. Kiểm tra xem LD_LIBRARY_PATH của bạn có bao gồm /usr/local/lib và nếu không, hãy thêm nó và thử lại.

Một số biết thêm thông tin (source):

In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes. The environment variable LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. These are implemented by the loader /lib/ld-linux.so. I should note that, while LD_LIBRARY_PATH works on many Unix-like systems, it doesn't work on all; for example, this functionality is available on HP-UX but as the environment variable SHLIB_PATH, and on AIX this functionality is through the variable LIBPATH (with the same syntax, a colon-separated list).

Cập nhật: thiết LD_LIBRARY_PATH, sử dụng một trong những điều sau đây, tốt nhất là ở bạn ~/.bashrc hoặc tập tin tương đương:

export LD_LIBRARY_PATH=/usr/local/lib 

hoặc

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

Sử dụng biểu mẫu đầu tiên nếu nó trống (tương đương với chuỗi trống hoặc không có gì cả) và biểu mẫu thứ hai nếu không. Lưu ý việc sử dụng xuất.

+2

Cảm ơn. LD_LIBRARY_PATH của tôi đã không được thiết lập, vì vậy: $ LD_LIBRARY_PATH =/usr/local/lib $ LD_LIBRARY_PATH /usr/local/lib Nhưng tôi vẫn nhận được lỗi tương tự: $ python -c "nhập khẩu pycurl" Traceback (cuộc gọi gần đây nhất cuối cùng): Tệp "", dòng 1, trong NhậpError: libcurl.so.4: không thể mở tệp đối tượng được chia sẻ: Không có tệp hoặc thư mục nào như vậy –

+1

Tôi cũng đã cấp quyền cho người dùng của mình đọc thư viện sau khi thiết lập biến LD_LIBRARY_PATH. Bây giờ nó cuối cùng hoạt động. –

46

Đảm bảo mô-đun libcurl.so của bạn nằm trong đường dẫn thư viện hệ thống, khác biệt và tách biệt với đường dẫn thư viện python.

"Sửa nhanh" là thêm đường dẫn này vào biến LD_LIBRARY_PATH. Tuy nhiên, việc thiết lập hệ thống đó rộng (hoặc thậm chí là tài khoản rộng) là một IDEA BAD, vì nó có thể thiết lập nó theo cách mà một số chương trình sẽ tìm thấy một thư viện không nên, hoặc thậm chí tệ hơn, mở các lỗ hổng bảo mật.

Nếu "thư viện cài đặt cục bộ" được cài đặt, ví dụ,/usr/local/lib, hãy thêm thư mục này vào /etc/ld.so.conf (đó là tệp văn bản) và chạy "ldconfig"

Lệnh này sẽ chạy một tiện ích bộ nhớ đệm, nhưng cũng sẽ tạo tất cả các "liên kết tượng trưng" cần thiết để hệ thống tải hoạt động. Thật đáng ngạc nhiên là "make install" cho libcurl đã không làm điều này, nhưng có thể nó không thể nếu/usr/local/lib không có trong /etc/ld.so.conf rồi.

PS: có thể là /etc/ld.so.conf của bạn không chứa gì ngoài "bao gồm ld.so.conf.d/*. Conf". Bạn vẫn có thể thêm một đường dẫn thư mục sau khi nó, hoặc chỉ cần tạo một tệp mới bên trong thư mục mà nó đang được đưa vào. Đừng quên chạy "ldconfig" sau nó.

Hãy cẩn thận. Bắt sai này có thể làm hỏng hệ thống của bạn.

Ngoài ra: đảm bảo mô-đun python của bạn được biên dịch dựa vào phiên bản libcurl đó. Nếu bạn chỉ cần sao chép một số tập tin trên từ một hệ thống khác, điều này sẽ không luôn luôn làm việc. Nếu nghi ngờ, hãy biên dịch các mô-đun của bạn trên hệ thống bạn định chạy chúng.

+0

Cảm ơn bạn - điều này đã hiệu quả. Tôi tự hỏi tại sao "cố định nhanh" trước đây của tôi thay đổi biến LD_LIBRARY_PATH thì không. –

+1

Phụ thuộc vào rất nhiều yếu tố. Đây là một khả năng: mã của bạn đã được chạy từ apache hoặc cron. Những chương trình này thường "dọn dẹp" môi trường, vì vậy bạn phải làm thêm các công cụ để lấy các biến môi trường. Ví dụ, "SetEnv" trong apache, hoặc đặt biến ngay trong tệp crontab cho cron. Khả năng mắc lỗi là vô tận! –

+0

Câu trả lời hay, cảm ơn bạn – glarrain

22

Bạn cũng có thể đặt LD_RUN_PATH thành/usr/local/lib trong môi trường người dùng của mình khi bạn biên dịch pycurl ngay từ đầu. Điều này sẽ nhúng/usr/local/lib vào thuộc tính RPATH của mô-đun mở rộng C.do đó, nó sẽ tự động biết nơi để tìm các thư viện tại thời gian chạy mà không cần phải có LD_LIBRARY_PATH thiết lập tại thời gian chạy.

+0

+1 chỉ là những gì tôi đang tìm kiếm. cảm ơn! –

+3

Cách khác, sử dụng 'thiết lập python.py build_ext --rpath =/usr/local/lib' khi xây dựng mô-đun mở rộng để nướng trong * rpath * – kynan

+0

Cảm ơn đây phải là câu trả lời được chấp nhận –

8

Có cùng vấn đề chính xác. Tôi cài đặt curl 7,19 đến/opt/curl/để đảm bảo rằng tôi sẽ không ảnh hưởng đến curl hiện tại trên các máy chủ sản xuất của chúng tôi. Khi tôi liên kết libcurl.so.4 đến/usr/lib:

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

tôi vẫn nhận được cùng một lỗi! Durf.

Nhưng chạy ldconfig tạo liên kết cho tôi và hoạt động đó. Không cần thiết lập LD_RUN_PATH hoặc LD_LIBRARY_PATH. Chỉ cần chạy ldconfig.

+0

+1 để chạy 'ldconfig', tất cả các lỗi cố định –

+0

Nếu tôi không không có đặc quyền sudo? Tôi không thể chạy ldconfig? Có cách nào để xóa lỗi trên không? – SPRajagopal

+1

@SPRajagopal: nếu bạn không có quyền sửa đổi thuộc tính hệ thống, bạn phải sử dụng phương thức biến môi trường 'LD_LIBRARY_PATH' được mô tả ở trên. Nếu bạn không muốn đặt nó trong '~/.bashrc' (thêm thiết lập đó không phải là một ý tưởng hay) bạn có thể viết một kịch bản lệnh shell để đặt biến này sau đó chạy python, sau đó gọi kịch bản lệnh đó. – MadScientist

7

Là một bổ sung cho câu trả lời ở trên - Tôi chỉ gặp phải vấn đề tương tự và làm việc hoàn toàn với trình cài đặt mặc định python.

Khi tôi gọi là ví dụ về các thư viện đối tượng chia sẻ Tôi đang tìm kiếm với LD_LIBRARY_PATH, tôi nhận được một cái gì đó như thế này:

$ 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 

Đáng chú ý, nó không còn phàn nàn về việc nhập khẩu - nó than phiền về tệp nguồn!

Nhưng nếu tôi buộc tải của các đối tượng sử dụng 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 

... Tôi ngay lập tức nhận được một thông báo lỗi có ý nghĩa hơn - về một sự phụ thuộc mất tích!

Chỉ nghĩ rằng tôi sẽ ghi lại điều này ở đây - chúc mừng!

+0

Bạn có chắc chắn đó không phải là lỗi mới xảy ra trước khi lỗi của OP không? –

0

Tôi sử dụng python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0 và tệp được biên dịch .so nằm trong thư mục xây dựng. bạn có thể nhập python setup.py --help build_ext để xem giải thích về -R và -I