tar
呼び出すことができるプログラムを実行するために必要なすべてを含むファイルをダウンロードしましたsome_binary
。内容を抽出してみると次のようになります。
- バイナリファイル(と呼びましょう
some_binary
) - さまざまな動的ライブラリ(.soファイル)を含むフォルダ
lib
。/lib/ld-linux-x86-64.so
- そして、次のシェルスクリプトがあります。
some_binary.sh
スクリプトの内容は次のとおりです。
#!/bin/bash
`dirname "$0"`/lib/ld-linux-x86-64.so.2 `dirname "$0"`/some_binary "$@"
./some_binary.sh some arguments
実行すると正しく実行されるようです./some_binary
。奇妙なことに、次のスクリプトを実行します。
#!/bin/bash
LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
./some_binary "$@"
./my_script.sh some arguments
うまくいかないからです。以下のライブラリを誤ってロードしたため、再配置エラー(未定義のシンボル)が発生します。./lib
また、コマンドラインで次の2つのステートメントを実行すると、次の結果が表示されますsegmentation fault
。
> LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
> ./some_binary some arguments
これに関する私の質問は次のとおりです。
- 最初のスクリプトは何をしますか?
- 3回の試みでなぜ他の結果が出るのですか?なぜ追加し
$pwd/lib
てLD_LIBRARY_PATH
実行できないのですかsome_binary
?
答え1
このプログラムは独自に提供されます。動的ローダー。プログラムには独自の動的ローダがほとんど必要ありません。通常、システムの動的ローダも機能します。これは、プログラムがGNU libc以外の標準ライブラリ、または奇妙な設定でコンパイルされたGNU libcにリンクされている場合に必要になる場合があります。
プログラムが好むライブラリを見つける場所をローダーに知らせるだけで十分です。あなたの試みはほとんどそうですが、必ずしもそうではありません。LD_LIBRARY_PATH
環境にまだ存在しない場合、割り当てはLD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
環境変数ではなくシェル変数のみを定義するため、プログラムには何も表示されません。また、通常$CWD
参照できる空の文字列(スクリプトを含むディレクトリなど)にも拡張されます。また、あなたの質問に一貫性のないコンテンツを使用していることに注意してください。努力する$PWD
$(dirname "$0")
lib
LIB
#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
exec "$(dirname "$0")/some_binary" "$@"
あるいは、より良い方法は、以前に定義されていない場合は最後に空のエントリを置かないことですLD_LIBRARY_PATH
(空のエントリは現在のディレクトリを表すので悪いかもしれませんが、パスの終わりにライブラリが定義されていない場合にのみ有害です)。存在しません)、それが必要な場所が見つかりません):
#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
case "$LD_LIBRARY_PATH" in *:) LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:};; esac
exec "$(dirname "$0")/some_binary" "$@"