ld-linux.so を使用してスクリプトを呼び出しますか?

ld-linux.so を使用してスクリプトを呼び出しますか?

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

これに関して、私の質問は次のとおりです。

  1. 最初のスクリプトは何をするのでしょうか?
  2. なぜ 3 回の試行で異なる結果が得られるのでしょうか。また、追加し$pwd/libLD_LIBRARY_PATH直接実行some_binaryできないのはなぜでしょうか。

答え1

プログラムには独自のダイナミックローダープログラムが独自のダイナミック ローダーを必要とすることは非常にまれです。通常は、システム上のダイナミック ローダーでも動作します。プログラムが GNU libc 以外の標準ライブラリにリンクされている場合、または奇妙な設定でコンパイルされた GNU libc にリンクされている場合は、これが必要になることがあります。

ローダーにプログラムの優先ライブラリがどこにあるかを伝えるだけで十分かもしれません。あなたの試みはほぼそれを実現しますが、完全には実現していません。LD_LIBRARY_PATHが環境にない場合、割り当てはLD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATHシェル変数のみを定義し、環境変数は定義しないため、プログラムは何も認識しません。 さらに、 は$CWD通常、空の文字列に展開されますが、おそらく$PWDまたは(つまり、スクリプトを含むディレクトリ)を意味していたのでしょう。 また、質問ではと を一貫して$(dirname "$0")使用していないことに注意してください。 を試してください。libLIB

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

関連情報