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

私は、端末を呼び出すためにそれを使用する場合(xtermaterm、...)私はLD_LIBRARY_PATH未設定の取得します。

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

なぜこれが起こるのですか?どうすればこれを止められますか?(私はDebian 5.0を実行しています)

更新

私の端末はログインとしてbashを呼び出していません:

kjfletch@flatbed:~$ echo $0
bash

LD_LIBRARY_PATHはどのbashスタートアップファイルにも表示されません(.bash_historyと〜/ .profileは別として存在します)。

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

「ソース」コマンドまたは「。」を呼び出すスタートアップファイルのいずれか 他の起動スクリプトを取り込むコマンド?もしそうなら、それらの1つが原因である可能性があります。
ケビンパンコ

あなたの質問には答えませんが、本当に良いことは、LD_LIBRARY_PATH の必要性を取り除くことです(理由:1 2 3)。たとえば、/ etc / ld.so.confを編集したり、〜/ localにあるユーザー定義のライブラリをコンパイルして、ライブラリの場所を知っている方法でコンパイルすることができます(提供したリンクを参照)。
DevSolar 2012

回答:


9

端末バイナリはsetgidグループ化する可能性が最も高いutmpです。LD_LIBRARY_PATHセキュリティ上の理由から、setuidおよびsetgidバイナリは設定解除されています。参照してくださいld.so(8)

プログラムが必要とする必要な共有ライブラリは、次の順序で検索されます

  • 環境変数の使用LD_LIBRARY_PATHLD_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

このようなガードは通常、セッション内でスクリプトが複数回ソースされるのを防ぐために配置されます。

編集:変数がリセットされている場所を追跡するのが面倒であることがわかっていて、たとえば/ etc / profileまたは/etc/bash.bashrcにアクセスできる場合、一時的に「set -x」を上部に追加できます実行されるすべてのコマンドを確認するスクリプト。出力はかなり冗長になるので、最初にシェルで「set -x」を実行し、いくつかのコマンドを実行して、何が期待できるかを理解します。


+1情報をありがとう。回答に応じてOPを更新しました。
kjfletch 2009

同じ端末でbashと入力して新しいbashシェルを入力しても、同じ動作が見られますか?ところで、/ etc / bash.bashrcおよび/ etc / profile内から呼び出されたファイルも確認する必要があります。これらの1つは変数の設定を解除する可能性があります。または、set -xデバッグオプションを使用して、シェルの作成時から行われたすべてのダンプを取得します。

set -xダンプは、LD_LIBRARY_PATHへの参照を行いません。ファントムが未設定です。
kjfletch 2009

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画面(ターミナルマルチプレクサ)でこの問題が発生しましたが、通常のターミナルでも発生する可能性があります。テディは私の場合は正しかった、画面は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

これで、画面(または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(または同等の)ファイルがホームディレクトリにあるようです。詳細はわかりません。

OKを編集してください。bashが動作するので、.bashrcではないと思います。ただし、xtermまたはatermを起動したときに、たまたま同じ方法で実行される他の構成ファイルがある可能性があります。


これは私の最初の考えでした。多くの検索の後、発見するものは何もありません。私は非常にクリーンな(新しい)$ HOMEを持っているという利点があります。
kjfletch 2009

0

ほとんどのウィンドウシステムは、ターミナルウィンドウを起動するときにログインプロセスを再作成します。これは、主にターミナルウィンドウが、起動シェルではなくウィンドウマネージャの子になるためです。

したがって、新しいウィンドウに表示したい場合は、.bash_profileまたは.bashrcに入れてください。

もう1つの方法は、起動スクリプトを実行するための引数を(たとえば)xtermに渡すことです。スクリプトの最後で終了しないでください...


私はこれに頼らなければならないと思います。私はおそらく、環境変数を両方の.xinitrcにソースして、ウィンドウマネージャーにそれらを提供し、.bashrcに提供して、ターミナルウィンドウにそれらを提供します。
kjfletch 2009
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.