Tại sao LD_LIBRARY_PATH của tôi không được đặt thiết bị đầu cuối khởi chạy?


8

Tôi có một tập lệnh shell để thiết lập một số biến môi trường và khởi chạy bất kỳ chương trình nào tôi gửi làm đối số:

export PATH=$HOME/local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH
export TESTER="MY TEST VAR"

$@

Khi tôi sử dụng điều này để gọi bashví dụ, nó hoạt động:

kjfletch@flatbed:~$ envrun.sh bash
kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH
/home/kjfletch/local/lib:
kjfletch@flatbed:~$ echo $TESTER
MY TEST VAR

Khi tôi sử dụng nó để gọi một thiết bị đầu cuối ( xterm, aterm, ...) của tôi LD_LIBRARY_PATHbị unset:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Lý do tại sao điều này xảy ra? Làm thế nào tôi có thể ngăn chặn điều này? (Tôi đang chạy Debian 5.0)

Cập nhật

Thiết bị đầu cuối của tôi không gọi bash là thông tin đăng nhập:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHkhông hiển thị trong bất kỳ tệp khởi động bash nào (ngoài .bash_history và ~ / .profile không tồn tại.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 

Có bất kỳ tệp nào trong số các tệp khởi động đó gọi lệnh "nguồn" hoặc "." lệnh để đưa vào các kịch bản khởi động khác? Nếu vậy, một trong số đó có thể là thủ phạm.
Kevin Panko

Không trả lời câu hỏi của bạn, nhưng điều thực sự tốt sẽ là loại bỏ nhu cầu về LD_LIBRARY_PATH (lý do: 1 2 3 ). Ví dụ, bạn có thể chỉnh sửa /etc/ld.so.conf hoặc biên dịch bất kỳ lib nào do người dùng định nghĩa bạn có trong ~ / local theo cách họ biết nơi tìm thư viện của họ (xem các liên kết tôi đã cung cấp).
DevSolar

Câu trả lời:


9

Nhị phân đầu cuối rất có khả năng setgidnhóm utmp. Các nhị phân setuid và setgid không được đặt LD_LIBRARY_PATHvì lý do bảo mật; xem ld.so(8):

Các thư viện chia sẻ cần thiết cần thiết cho chương trình được tìm kiếm theo thứ tự sau

  • Sử dụng biến môi trường LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHcho các chương trình a.out). Ngoại trừ nếu thực thi là một nhị phân setuid / setgid, trong trường hợp đó nó bị bỏ qua.

4

Trong thiết bị đầu cuối (xterm, aterm, v.v.), hãy kiểm tra cách shell được gọi: Shell đăng nhập sẽ hiển thị "-bash" và shell không đăng nhập sẽ hiển thị "bash" khi bạn gọi echo $0.

$ echo $0
-bash
$ bash
$ echo $0
bash

Một bash shell đăng nhập sẽ đọc các thứ tự sau:

  1. / etc / hồ sơ
  2. ~ / .bash_profile
  3. ~ / .bash_login
  4. ~ /.

Kiểm tra xem có bất kỳ tệp nào trong số này tồn tại không và liệu chúng có đặt lại biến không. Bạn cũng sẽ phải theo dõi bất kỳ tập tin nào bao gồm các tập tin.

Nếu bash không được gọi là shell đăng nhập, nó vẫn sẽ đọc các tệp bên dưới nếu được xác định là shell tương tác.

  1. /etc/bash.bashrc
  2. ~ / .bashrc

Một cách đơn giản để xác định loại bash shell được gọi là xác định .bash_profile và .bashrc của bạn và lặp lại "Shell đăng nhập" và "Shell tương tác".

Khi bạn biết loại shell được gọi, bạn có tùy chọn thêm tập lệnh của mình vào tệp .bashrc hoặc .bash_profile trong thư mục chính của bạn. Ngoài ra, bạn có thể vô hiệu hóa thiết lập lại LD_LIBRARY_PATH.

Lưu ý rằng nếu .bashrc hoặc .bash_profile của bạn được bảo vệ bởi một người bảo vệ tương tự như bên dưới, bạn có thể phải gọi tập lệnh của mình bên ngoài nó:

if [ "X$BASH_SOURCED" != "XYES" ]; then
        export BASH_SOURCED=YES

fi

Những người bảo vệ như vậy thường được đặt để ngăn chặn một kịch bản có nguồn gốc nhiều lần trong một phiên.

Chỉnh sửa: Nếu việc chứng minh tedius theo dõi nơi biến đang được đặt lại và bạn có quyền truy cập vào / etc / profile hoặc /etc/bash.bashrc chẳng hạn, bạn có thể tạm thời thêm "set -x" ở gần đầu kịch bản để xem tất cả các lệnh được thực hiện. Đầu ra sẽ khá dài dòng, vì vậy trước tiên hãy thực hiện "set -x" trong trình bao của bạn và chạy một vài lệnh để bạn biết những gì sẽ xảy ra.


+1 Cảm ơn thông tin. Tôi đã cập nhật OP của tôi để đáp lại câu trả lời của bạn.
kjfletch

Bạn có thấy hành vi tương tự nếu bạn nhập một bash shell mới trên cùng một thiết bị đầu cuối bằng cách gõ bash không? Btw, bạn cũng sẽ cần kiểm tra các tệp được gọi từ trong /etc/bash.bashrc và / etc / profile - một trong số đó có thể bỏ đặt biến. Ngoài ra, sử dụng set -xtùy chọn gỡ lỗi để có được một đống mọi thứ được thực hiện kể từ thời điểm shell được tạo.

Kết set -xxuất không tham chiếu đến LD_LIBRARY_PATH. Phantom chưa đặt.
kjfletch

4

bash sẽ sử dụng các tập lệnh khởi động khác nhau tùy thuộc vào cách nó được bắt đầu. Có bảy cách khác nhau để bắt đầu nó, nhưng quan trọng nhất là shell đăng nhập so với shell tương tác không đăng nhập.

Kiểm tra hướng dẫn sử dụng bash để biết thêm chi tiết. Tôi nghi ngờ / etc / profile hoặc ~ / .bash_profile đang làm gì đó để đặt lại biến LD_LIBRARY_PATH.


Chỉnh sửa: Tôi nghĩ rằng bạn đã làm tất cả những gì bạn có thể hợp lý để cho thấy rằng bash không có bất kỳ tập lệnh khởi động nào hủy cài đặt LD_LIBRARY_PATH. Đã đến lúc mang ra những khẩu súng lớn.

Lệnh sau sẽ hiển thị toàn bộ môi trường khi mỗi quá trình khởi động, từ bash đến xterm và bất kỳ điều gì khác có liên quan - bạn có thể sẽ nhận được một lượng lớn đầu ra, vì vậy lưu đầu ra vào tệp là một ý tưởng tốt .

strace -v -f -e trace=process -o strace_output.txt envrun.sh xterm

Bây giờ, tệp straceDefput.txt sẽ hiển thị mỗi lệnh gọi hệ thống được thực hiện bởi tập lệnh của bạn và mọi quy trình con và bạn sẽ có thể xem quy trình nào là lần cuối cùng có LD_LIBRARY_PATH trước khi bị xóa.


2

(Câu hỏi này rất cũ, nhưng tôi chỉ gặp phải vấn đề tương tự, và đang ghi lại giải pháp cho hậu thế :)

Tôi đã gặp vấn đề này với màn hình GNU (bộ ghép kênh đầu cuối), nhưng nó cũng có thể xảy ra với một thiết bị đầu cuối thông thường. Teddy đã đúng trong trường hợp của tôi, màn hình đã được thiết lập sẵn.

$ ls -l /usr/bin/screen
-rwxr-sr-x 1 root 84 361016 Mar 30  2011 /usr/bin/screen
      ^

Giải pháp của tôi là lưu LD_LIBRARY_PATH trước khi thực hiện và khôi phục nó sau đó. Vì vậy, tôi đã tạo một trình bao bọc ~ / bin / màn hình (đặt ~ / bin trên PATH), với các nội dung sau:

#!/bin/bash

# somehow, screen resets LD_LIBRARY_PATH.
# save it here, and restore it in .bashrc
export PRESERVE_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
/usr/bin/screen "$@"

và sau đó làm cho nó thực thi với chmod +x ~/bin/screen. Bạn có thể phải mở một vỏ mới để lấy nó ra để lấy trình bao bọc.

Sau đó, tôi đã thêm như sau vào ~ / .bashrc. Hãy nhớ ~ / .bashrc có nguồn gốc mỗi khi bạn bắt đầu bash, không giống như ~ / .bash_profile chỉ có nguồn gốc khi đăng nhập (thường là khi khởi động hoặc khi bạn đăng nhập qua ssh).

if [[ "$PRESERVE_LD_LIBRARY_PATH" != "" ]]; then
    export LD_LIBRARY_PATH="$PRESERVE_LD_LIBRARY_PATH"
    #echo "restored LD_LIBRARY_PATH"
    export -n PRESERVE_LD_LIBRARY_PATH
fi

Bây giờ, màn hình (hoặc aterm, xterm, ... chỉ cần thay thế nó ở trên) sẽ duy trì $ LD_LIBRARY_PATH như mong muốn.


Bạn cũng có thể khôi phục LD_LIBRARY_PATHtrong .screenrc(thay vì .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"theo sauunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp

0

Có vẻ như bạn có một số tệp .bashrc (hoặc tương đương) trong thư mục chính của bạn xác định biến này. Tôi không biết nhiều chi tiết hơn mặc dù.

Chỉnh sửa Ok, kể từ khi bắt đầu bash hoạt động, tôi đoán không phải là .bashrc. Nhưng có thể một số tệp cấu hình khác sẽ được thực hiện theo cùng một cách, khi bạn khởi động xterm hoặc aterm.


Đây là suy nghĩ ban đầu của tôi. Sau khi tìm kiếm nhiều, không có gì được tìm thấy. Tôi có lợi ích là có $ HOME rất sạch (MỚI).
kjfletch

0

Hầu hết các hệ thống cửa sổ tạo lại quá trình đăng nhập khi chúng khởi chạy một cửa sổ đầu cuối, chủ yếu là do cửa sổ đầu cuối trở thành con của trình quản lý cửa sổ chứ không phải trình khởi chạy.

Vì vậy, hãy đặt nó trong .bash_profile hoặc .bashrc nếu bạn muốn nó hiển thị trong một cửa sổ mới.

Một cách khác là trao xterm (ví dụ) một đối số để chạy tập lệnh khởi động. Đừng thoát ở cuối đoạn script đó ....


Tôi sẽ phải dùng đến điều này tôi nghĩ. Tôi có thể sẽ nguồn các biến môi trường của mình trong cả .xinitrc để trình quản lý cửa sổ của tôi có chúng và trong .bashrc để các cửa sổ đầu cuối của tôi sẽ có chúng.
kjfletch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.