ソースbashスクリプトに無効な$BASH_SOURCE値が含まれていますか?

ソースbashスクリプトに無効な$BASH_SOURCE値が含まれていますか?

Linux文書化プロジェクト説明する:

ファイルをインポートすると(コマンドラインにソースファイル名または.filenameと入力して)、ファイルのコード行がコマンドラインに印刷されているかのように実行されます。これは、ファイルに保存してファイルをインポートしてインポートできる複雑なプロンプトに特に役立ちます。

test.shtest2.shとの3つのスクリプトがありますcommon.sh。現在のスクリプトのデフォルト名を含む変数をcommon.sh設定します(使用)。呼び出されて表示されます。呼び出され、表示される内容。$me${BASH_SOURCE[0]}test.shsourcecommon.sh$metest2.shevalcommon.sh$me

==> common.sh <==
#!/bin/bash

realpath=$(realpath "${BASH_SOURCE[0]}")
me=$(basename "${realpath}")

==> test.sh <==
#!/bin/bash

source common.sh

echo "me: $me"

==> test2.sh <==
#!/bin/bash

common=$(cat common.sh)
eval "$common"

echo "me: $me"

実行すると、./test2.sh出力はですme: test2.sh

実行すると、./test.sh出力はですme: common.shなぜですか?

編集する

sourcingJeff Schallerの答えは、他のスクリプトがスクリプト名を配列に「取り消す」という点で正確です$BASH_SOURCE。眺めるだけで私が欲しいものを成し遂げることができた最後値については$BASH_SOURCE下記をご覧ください。

#!/bin/bash

declare -p BASH_SOURCE
bash_source_size="${#BASH_SOURCE[*]}"
realpath=$(realpath "${BASH_SOURCE[$bash_source_size-1]}")
me=$(basename "${realpath}")

答え1

test.sh呼び出されると、sourcebashはcommon.sh現在のスクリプトを明示的に取得してBASH_SOURCE変数を更新します。test2.shコマンドの置き換え(何でも可能)および後続のコマンドを実行するとeval明示的なことはsourcing発生しないため、BASH_SOURCEは影響を受けません。

シェルスクリプトの検出

declare -p BASH_SOURCE違いを確認する行:

$ ./test.sh
declare -a BASH_SOURCE='([0]="common.sh" [1]="./test.sh")'
declare -a BASH_SOURCE='([0]="./test.sh")'
me: common.sh

比較:

$ ./test2.sh
declare -a BASH_SOURCE='([0]="./test2.sh")'
declare -a BASH_SOURCE='([0]="./test2.sh")'
me: test2.sh

bashが知る限りでは、test2.sh任意のコマンド、つまり$(echo ls)

関連情報