Python nối thêm vào LD_LIBRARY_PATH

Lưu ý nhỏ này là về một trong những biến môi trường bị “lạm dụng” nhiều nhất trên các hệ thống Unix. LD_LIBRARY_PATH. Nếu được sử dụng đúng cách, nó có thể rất hữu ích, nhưng rất thường xuyên – không thể nói là hầu hết thời gian – mọi người áp dụng nó sai cách, và đó là họ đang chuốc lấy rắc rối

Vì vậy, nó làm gì?

LD_LIBRARY_PATH báo cho bộ tải liên kết động (ld. vì vậy - chương trình nhỏ này khởi động tất cả các ứng dụng của bạn) nơi tìm kiếm các thư viện chia sẻ động mà một ứng dụng được liên kết với. Có thể liệt kê nhiều thư mục, được phân tách bằng dấu hai chấm (. ), và danh sách này sau đó được tìm kiếm trước (các) đường dẫn tìm kiếm được biên dịch sẵn và các vị trí tiêu chuẩn (thường là /lib, /usr/lib,…)

Điều này có thể được sử dụng cho

  • thử nghiệm các phiên bản mới của thư viện dùng chung dựa trên ứng dụng đã được biên dịch
  • định vị lại các thư viện dùng chung, e. g. để bảo tồn các phiên bản cũ
  • tạo một khép kín, có thể di dời (. ) cho các ứng dụng lớn hơn, sao cho chúng không phụ thuộc vào (thay đổi) thư viện hệ thống – nhiều nhà cung cấp phần mềm sử dụng phương pháp đó

Nghe có vẻ rất hữu ích, vấn đề là ở đâu?

Vâng, nó rất hữu ích – nếu bạn áp dụng nó theo cách mà nó được tạo ra, giống như ba trường hợp trên. Tuy nhiên, nó thường được sử dụng như một cái nạng để khắc phục sự cố mà lẽ ra có thể tránh được bằng các cách khác (xem bên dưới). Nó thậm chí còn trở nên tồi tệ hơn, nếu cái nạng này được áp dụng trên toàn cầu vào người dùng (hoặc hệ thống của. ) môi trường. các ứng dụng được biên dịch với các cài đặt đó sẽ phụ thuộc vào cái nạng này – và nếu cuối cùng nó bị lấy đi, chúng sẽ bắt đầu vấp ngã (i. e. không chạy được)

Ngoài ra còn có những hàm ý khác

  1. Bảo vệ. Hãy nhớ rằng các thư mục được chỉ định trong LD_LIBRARY_PATH được tìm kiếm trước đó (. ) các vị trí tiêu chuẩn? . Đó là một lý do tại sao các tệp thực thi setuid/setgid bỏ qua biến đó
  2. Hiệu suất. Trình tải liên kết phải tìm kiếm tất cả các thư mục được chỉ định, cho đến khi nó tìm thấy thư mục chứa thư viện dùng chung – đối với TẤT CẢ các thư viện dùng chung, ứng dụng được liên kết với. Điều này có nghĩa là rất nhiều cuộc gọi hệ thống để mở (), sẽ không thành công với “ENOENT (Không có tệp hoặc thư mục như vậy)”. Nếu đường dẫn chứa nhiều thư mục, số lần gọi không thành công sẽ tăng tuyến tính và bạn có thể biết điều đó ngay từ khi khởi động ứng dụng. Nếu một số (hoặc tất cả) thư mục nằm trong môi trường NFS, thời gian khởi động ứng dụng của bạn có thể thực sự lâu – và nó có thể làm chậm toàn bộ hệ thống
  3. không nhất quán. Đây là vấn đề phổ biến nhất. LD_LIBRARY_PATH buộc một ứng dụng tải một thư viện dùng chung mà nó không được liên kết với nó và điều đó rất có thể không tương thích với phiên bản gốc. Điều này có thể rất rõ ràng, tôi. e. ứng dụng gặp sự cố hoặc có thể dẫn đến kết quả sai, nếu thư viện được chọn không hoàn toàn hoạt động như phiên bản gốc đã làm. Đặc biệt là cái sau đôi khi khó gỡ lỗi

Làm cách nào để kiểm tra thư viện động nào đã được tải?

Có lệnh ldd, cho bạn biết thư viện nào cần thiết cho tệp thực thi được liên kết động, ví dụ:. g

$ ldd /usr/bin/file
        linux-vdso.so.1 =>  (0x00007fff9646c000)
        libmagic.so.1 => /usr/lib64/libmagic.so.1 (0x00000030f9a00000)
        libz.so.1 => /lib64/libz.so.1 (0x00000030f8e00000)
        libc.so.6 => /lib64/libc.so.6 (0x00000030f8200000)
        /lib64/ld-linux-x86-64.so.2 (0x00000030f7a00000)

Đây là chế độ xem 'tĩnh', vì ldd không giải quyết các phụ thuộc và thư viện sẽ được tải khi chạy, e. g. bởi một thư viện phụ thuộc vào người khác. Để có cái nhìn tổng quan về các thư viện được tải trong thời gian chạy, bạn có thể sử dụng lệnh pldd

$ ldd /bin/bash
        linux-vdso.so.1 =>  (0x00007ffff63ff000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003108a00000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00000030f8600000)
        libc.so.6 => /lib64/libc.so.6 (0x00000030f8200000)
        /lib64/ld-linux-x86-64.so.2 (0x00000030f7a00000)
$ pldd 24362
24362:  -bash
/lib64/ld-2.12.so
/lib64/libc-2.12.so
/lib64/libdl-2.12.so
/lib64/libtinfo.so.5.7
/usr/lib64/gconv/ISO8859-1.so
/lib64/libnss_files-2.12.so

Như bạn có thể thấy, có thêm hai. các tệp so được tải trong thời gian chạy, không có trong danh sách 'tĩnh'

Note: pldd is originally a Solaris command, that usually is not available on Linux. However, there is a Perl-script available (and installed on our machines) that extracts this information from the /proc//maps file.

Làm cách nào để tránh những sự cố đó với LD_LIBRARY_PATH?

Một câu trả lời rất đơn giản sẽ là. “Chỉ cần không sử dụng LD_LIBRARY_PATH. ” Câu trả lời thực tế hơn là, “bạn càng sử dụng ít, bạn càng có lợi”

Dưới đây là danh sách các cách tránh LD_LIBRARY_PATH, lấy cảm hứng từ tài liệu tham khảo [1] bên dưới. Giải pháp tốt nhất là từ trên xuống, đến phương sách cuối cùng

  • Nếu bạn tự biên dịch (các) ứng dụng của mình, bạn có thể giải quyết vấn đề bằng cách chỉ định vị trí chính xác của các thư viện được chia sẻ và yêu cầu trình liên kết thêm chúng vào đường chạy của tệp thực thi của bạn, chỉ định đường dẫn trong tùy chọn trình liên kết '-rpath'.
    cc -o myprog obj1.o .. objn.o -Wl,-rpath=/path/to/lib \
       -L/path/to/lib -lmylib

    Trình liên kết cũng đọc biến môi trường LD_RUN_PATH, nếu được đặt và do đó bạn có thể chỉ định nhiều đường dẫn một cách dễ dàng mà không phải sử dụng tùy chọn trình liên kết ở trên

    export LD_RUN_PATH=/path/to/lib1:/path/to/lib2:/path/to/lib3
    cc -o myprog obj1.o .. objn.o -L/path/to/lib1 -lmylib1 \
       -L/path/to/lib2 -lmylib2 ...

    Trong cả hai trường hợp, bạn có thể kiểm tra với ldd, rằng tệp thực thi của bạn sẽ tìm đúng thư viện khi khởi động (xem bên trên). Nếu có thông báo 'không tìm thấy' trong đầu ra ldd, bạn đã làm sai điều gì đó và nên xem lại Makefile và/hoặc cài đặt LD_RUN_PATH của mình

  • Có các công cụ xung quanh, để sửa/thay đổi đường chạy trong tệp thực thi nhị phân, e. g. chrpath trong Linux. Vấn đề với phương pháp này là không gian trong tệp thực thi có chứa thông tin này (i. e. chuỗi xác định đường dẫn) không thể mở rộng, tôi. e. bạn không thể thêm thông tin bổ sung – chỉ ghi đè lên một đường dẫn hiện có. Hơn nữa, nếu không có đường chạy nào tồn tại trong tệp thực thi, thì không có cách nào để thay đổi nó. Đọc trang man cho chrpath để biết thêm thông tin
  • Nếu bạn không thể sửa tệp thực thi, hãy tạo tập lệnh bao bọc gọi tệp thực thi đó bằng cài đặt LD_LIBRARY_PATH phù hợp. Theo cách đó, cài đặt chỉ hiển thị với ứng dụng này – và các ứng dụng bắt đầu bằng ứng dụng đó. Cái sau có thể dẫn đến vấn đề không nhất quán ở trên, mặc dù.
    #!/bin/sh
    LD_LIBRARY_PATH=/path/to/lib1:/path/to/lib2:/path/to/lib3
    export LD_LIBRARY_PATH
    exec /path/to/bin/myprog $@
  • Kiểm tra LD_LIBRARY_PATH từ dòng lệnh.
    $ env LD_LIBRARY_PATH=/path/to/lib1:/path/to/lib2:/path/to/lib3 ./myprog

    Cái này chỉ đặt LD_LIBRARY_PATH cho lệnh này. Đừng làm

    $ export LD_LIBRARY_PATH=/path/to/lib1:/path/to/lib2:/path/to/lib3
    $ ./myprog

    vì điều này sẽ gây ô nhiễm môi trường trình bao cho tất cả các lệnh liên tiếp

  • Không bao giờ đặt LD_LIBRARY_PATH trong hồ sơ đăng nhập của bạn. Bằng cách đó, bạn sẽ hiển thị tất cả các ứng dụng mà bạn bắt đầu với ứng dụng này - có thể có vấn đề - đường dẫn

Thật không may, một số ISV cung cấp phần mềm đặt cài đặt LD_LIBRARY_PATH chung vào cấu hình hệ thống trong quá trình cài đặt hoặc họ yêu cầu người dùng thêm các cài đặt đó vào cấu hình của họ. Chỉ cần nói không. Hãy thử nếu bạn có thể giải quyết vấn đề bằng cách khác, e. g. bằng cách tạo tập lệnh bao bọc hoặc yêu cầu nhà cung cấp khắc phục sự cố này

Làm cách nào để thêm đường dẫn vào LD_LIBRARY_PATH?

Hiển thị hoạt động trên bài đăng này. .
Chuyển đến thư mục nhà và chỉnh sửa. Hồ sơ
Place the following line at the end. export LD_LIBRARY_PATH=.
Lưu và thoát
Thực hiện lệnh này. sudo ldconfig

Làm cách nào để đặt LD_LIBRARY_PATH trong Windows?

5. 1 Đường dẫn thư viện dùng chung .
1 cửa sổ. Để đặt biến môi trường PATH vĩnh viễn trên Windows, hãy làm. Bảng điều khiển → Hệ thống → Nâng cao → Biến môi trường. .
2 Linux systems. Set on command line when invoking MATLAB: [user@host:~]$ LD_LIBRARY_PATH=[$LD_LIBRARY_PATH:]/tpath/shared & .. .
3 MATLAB 7. 8+ trên Linux 64-bit

LD_LIBRARY_PATH nghĩa là gì?

Biến môi trường LD_LIBRARY_PATH báo cho các ứng dụng Linux, chẳng hạn như JVM, nơi tìm các thư viện dùng chung khi chúng nằm trong một thư mục khác với thư mục được chỉ định trong phần tiêu đề của chương trình

Đường dẫn và LD_LIBRARY_PATH là gì?

Biến môi trường PATH chỉ định đường dẫn tìm kiếm cho lệnh, trong khi LD_LIBRARY_PATH chỉ định đường dẫn tìm kiếm thư viện dùng chung cho trình liên kết . Các giá trị mặc định ban đầu của PATH và LD_LIBRARY_PATH được chỉ định trong tệp bản dựng trước khi khởi động procnto.