LD_LIBRARY_PATH가 시작 터미널을 설정 해제하는 이유는 무엇입니까?


8

일부 환경 변수를 설정하고 인수로 보내는 모든 프로그램을 시작하는 쉘 스크립트가 있습니다.

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

$@

bash예를 들어 이것을 사용하여 호출 하면 작동합니다.

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

내가 터미널 전화를 사용할 때 ( xterm, aterm, ...) 내는 LD_LIBRARY_PATH해제 가져옵니다

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

왜 이런 일이 발생합니까? 이걸 어떻게 막을 수 있습니까? (데비안 5.0을 사용하고 있습니다)

최신 정보

내 터미널은 로그인으로 bash를 호출하지 않습니다.

kjfletch@flatbed:~$ echo $0
bash

LD_LIBRARY_PATHbash 시작 파일에 표시되지 않습니다 (.bash_history와 ~ / .profile 제외).

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

"start"명령 또는 "."을 (를) 호출하는 시작 파일이 있습니까? 다른 시작 스크립트를 가져 오는 명령? 그렇다면 그 중 하나가 범인 일 수 있습니다.
Kevin Panko

귀하의 질문에 대답하지 않습니다,하지만 정말 좋은 일이 제거하는 것이 필요 LD_LIBRARY_PATH에 대해 (이유 : 1 2 3 ). 그들이 것을 당신은, 예를 들어, 편집 /etc/ld.so.conf를, 또는 컴파일을 위해 당신은 방법으로 ~ / 지역에서 가질 수 어떤 사용자 정의 libs가 알고 자신의 라이브러리를 (내가 준 링크 참조) 어디서 찾을 수 있는지.
DevSolar

답변:


9

터미널 바이너리는 setgid그룹화 될 가능성이 높습니다 utmp. LD_LIBRARY_PATH보안상의 이유로 Setuid 및 setgid 바이너리는 설정되지 않습니다 . 참조 ld.so(8):

프로그램에 필요한 공유 라이브러리는 다음 순서로 검색됩니다.

  • 환경 변수 사용 LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHa.out 프로그램의 경우). 실행 파일이 setuid / setgid 바이너리 인 경우를 제외하고는 무시됩니다.

4

터미널 (xterm, aterm 등)에서 쉘 호출 방법을 확인하십시오. 호출 할 때 로그인 쉘에 "-bash"가 표시되고 비 로그인 쉘에 "bash"가 표시됩니다 echo $0.

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

로그인 bash 쉘은 다음을 순서대로 읽습니다.

  1. / etc / profile
  2. ~ / .bash_profile
  3. ~ / .bash_login
  4. ~ / .profile

이러한 파일이 있는지 확인하고 변수를 재설정했는지 확인하십시오. 또한 이러한 파일에 포함 된 모든 파일을 따라야합니다.

bash가 로그인 쉘로 호출되지 않은 경우, 대화식 쉘인 것으로 판별되면 여전히 아래 파일을 읽습니다.

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

호출되는 bash 쉘의 종류를 판별하는 간단한 방법은 .bash_profile 및 .bashrc를 정의하고 "로그인 쉘"및 "대화식 쉘"을 각각 에코하는 것입니다.

호출되는 쉘의 종류를 알면 홈 디렉토리의 .bashrc 또는 .bash_profile 파일에 스크립트를 추가 할 수 있습니다. 또는 LD_LIBRARY_PATH 재설정을 비활성화 할 수 있습니다.

.bashrc 또는 .bash_profile이 아래와 비슷한 가드로 보호되는 경우 외부에서 스크립트를 호출해야 할 수도 있습니다.

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

fi

이러한 보호는 일반적으로 세션에서 스크립트가 여러 번 소스되지 않도록하기 위해 배치됩니다.

편집 : 변수가 재설정되는 위치를 추적하는 tedius를 입증하고 예를 들어 / etc / profile 또는 /etc/bash.bashrc에 액세스 할 수있는 경우 일시적으로 상단에 "set -x"를 추가 할 수 있습니다 스크립트는 실행되는 모든 명령을 볼 수 있습니다. 결과는 매우 장황하므로 먼저 셸에서 "set -x"를 수행하고 몇 가지 명령을 실행하여 예상되는 것을 알 수 있습니다.


정보 감사합니다. 귀하의 답변에 따라 OP를 업데이트했습니다.
kjfletch

bash를 입력하여 동일한 터미널에서 새 bash 쉘을 입력하면 동일한 동작이 표시됩니까? Btw, /etc/bash.bashrc 및 / etc / profile 내에서 호출 된 파일도 확인해야합니다. 그 중 하나는 변수를 설정 해제 할 수 있습니다. 또는 set -x디버그 옵션을 사용 하여 셸이 생성 된 시점부터 수행되는 모든 항목을 덤프하십시오.

set -x덤프는 LD_LIBRARY_PATH에 대한 언급이 없다. 팬텀이 설정되지 않았습니다.
kjfletch

4

bash는 시작 방법에 따라 다른 시작 스크립트를 사용합니다. 시작하는 방법에는 7 가지가 있지만 가장 중요한 것은 로그인 쉘과 비 로그인 대화식 쉘입니다.

자세한 내용 은 bash 매뉴얼 을 확인하십시오. / etc / profile 또는 ~ / .bash_profile이 LD_LIBRARY_PATH 변수를 재설정하기 위해 무언가를하고 있다고 의심됩니다.


편집 : bash에 LD_LIBRARY_PATH를 설정 해제하는 시작 스크립트가 없음을 보여주기 위해 합리적으로 할 수있는 모든 것을했다고 생각합니다. 큰 총을 꺼낼 때입니다.

다음 명령은 bash에서 xterm에 이르기까지 각 프로세스가 시작될 때 전체 환경을 표시합니다. 여기에는 많은 양의 출력이 생길 수 있으므로 출력을 파일에 저장하는 것이 좋습니다 .

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

이제 strace_output.txt 파일 은 스크립트와 모든 하위 프로세스에서 수행 한 각 시스템 호출을 표시하며 LD_LIBRARY_PATH가 마지막으로 제거 된 프로세스를 확인할 수 있습니다.


2

(이 질문은 매우 오래되었지만 방금 동일한 문제가 발생하여 사후에 대한 해결책을 문서화하고 있습니다.)

GNU 화면 (터미널 멀티플렉서) 에서이 문제가 있었지만 일반 터미널에서도 발생할 수 있습니다. 내 경우에는 Teddy가 옳았 고 화면에 setguid가 설정되었습니다.

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

내 솔루션은 실행 전에 LD_LIBRARY_PATH를 저장하고 나중에 복원하는 것이 었습니다. 그래서 다음 내용으로 래퍼 ~ / bin / screen (PATH에 ~ / bin을 넣습니다)을 만들었습니다.

#!/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 "$@"

그런 다음로 실행 가능하게 만들었습니다 chmod +x ~/bin/screen. 랩퍼를 가져 오려면 새 쉘을 열어야 할 수도 있습니다.

그런 다음 ~ / .bashrc에 다음을 추가했습니다. ~ / .bashrc는 로그인 할 때만 (일반적으로 시작시 또는 ssh를 통해 로그인 할 때만) ~ / .bash_profile과 달리 bash를 시작할 때마다 공급됩니다.

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

이제 screen (또는 aterm, xterm, ... 그냥 위에 대체) $ LD_LIBRARY_PATH를 원하는대로 유지해야합니다.


또한 복원 할 수 LD_LIBRARY_PATH있는 .screenrc(대신 .bashrc) : setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"다음unsetenv PRESERVE_LD_LIBRARY_PATH
nandhp

0

이 변수를 정의하는 홈 디렉토리에 .bashrc (또는 동등한 파일) 파일이있는 것 같습니다. 그래도 자세한 내용은 모르겠습니다.

편집 확인은, bash는 일을 시작하기 때문에, 나는 추측하고있어 하지 의 .bashrc를. 그러나 xterm 또는 aterm을 시작할 때 동일한 방식으로 실행되는 다른 구성 파일 일 수 있습니다.


이것은 내 원래 생각이었습니다. 많은 검색 후에는 찾을 것이 없습니다. 나는 매우 깨끗한 (새로운) $ HOME을 갖는 이점이 있습니다.
kjfletch

0

대부분의 윈도우 시스템은 터미널 윈도우를 시작할 때 로그인 프로세스를 재생성합니다. 주로 터미널 윈도우는 시작 쉘이 아닌 윈도우 관리자의 자식이되기 때문입니다.

따라서 새 창에 표시하려면 .bash_profile 또는 .bashrc에 넣으십시오.

또 다른 대안은 시작 스크립트를 실행하기 위해 xterm (예를 들어) 인수를 전달하는 것입니다. 그 스크립트의 끝에서 종료하지 마십시오 ....


나는 내가 생각하는 이것에 의지해야 할 것이다. 내 환경 변수를 .xinitrc에서 소스 관리자로 지정하고 .bashrc에서 내 터미널 창에 변수를 제공 할 것입니다.
kjfletch
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.