
tar
呼び出すことができるプログラムを実行するために必要なものがすべて含まれているはずのファイルをダウンロードしましたsome_binary
。その内容を解凍すると、次のようになります。
- バイナリ(と呼びましょう
some_binary
) lib
さまざまな動的ライブラリ(.soファイル)を含むフォルダ。/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" "$@"