1. ホーム
  2. bash

[解決済み] $0とBASH_SOURCEの選択

2022-04-21 05:16:08

質問

のどちらかを選択します。 "$0""${BASH_SOURCE[0]}"

のこの記述は GNU はあまり役に立ちませんでした。

    BASH_SOURCE

 An array variable whose members are the source filenames where the
 corresponding shell function names in the FUNCNAME array variable are
 defined. The shell function ${FUNCNAME[$i]} is defined in the file
 ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}

解決方法は?

POSIX準拠の を参照してください。 この回答 .

${BASH_SOURCE[0]} (あるいは、もっと簡単に $BASH_SOURCE [1] ) に、そのスクリプトの (相対的な) パスが含まれています。 すべて を呼び出す場合、特にスクリプトが ソース には当てはまりません。 $0 .

さらに チャールズ・ダフィー が指摘する。 $0 を設定することができます。 任意の の値を呼び出し元が設定します。

裏を返せば $BASH_SOURCE は、名前の付いたファイルがない場合は、空になります; 例:

echo 'echo "[$BASH_SOURCE]"' | bash

次の例では、これを説明しています。

スクリプト foo :

#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"


$ bash ./foo
[./foo] vs. [./foo]

$ ./foo
[./foo] vs. [./foo]

$ . ./foo
[bash] vs. [./foo]

$0 は POSIX シェル仕様の一部であるのに対し BASH_SOURCE は、その名の通り、Bashに特化したものです。


[1] 任意で読みます。 ${BASH_SOURCE[0]} vs. $BASH_SOURCE :

Bashでは、要素 0 配列 変数を使用しています。 スカラー と書く代わりに ${arr[0]} と書くことができます。 $arr 言い換えれば、もし変数 スカラーであるかのように にある要素を取得します。 0 .

この機能を使用すると $arr は配列であるため、人気のあるシェルコードリンターである シェルチェック・ネット は以下のような警告を発します(この記事を書いている時点)。

SC2128: インデックスを指定せずに配列を展開すると、最初の要素しか得られません。

余談ですが、この警告は有用ですが、より正確であるべきです。 まず 要素で構成されています。具体的には、インデックス 0 を返すので、もし最初の要素のインデックスがもっと高ければ (Bashではあり得ます)、空文字列が返されます。 'a[1]='hi'; echo "$a"' .

(これに対して zsh さすがは反逆者 する は、インデックスに関係なく最初の要素を返します)。

この機能はわかりにくいので敬遠されるかもしれませんが、予測通りに動作しますし、実際問題、インデックスにアクセスする必要はほとんどないでしょう。 他の よりも 0 配列変数の ${BASH_SOURCE[@]} .


オプションの読み方その2:どのような条件下で BASH_SOURCE 配列変数には、実際に 複数 要素を使用しますか? :

BASH_SOURCE は、複数のエントリを持ちます。 関数呼び出しが含まれる場合 この場合、その要素は FUNCNAME すべての関数名を含む配列 現在コールスタックにある .

つまり、関数の内部です。 ${FUNCNAME[0]} には実行中の関数の名前が入り ${BASH_SOURCE[0]} には、その関数が定義されているスクリプトファイルのパスが含まれる。 ${FUNCNAME[1]} には、現在実行中の関数が呼び出された元となる関数の名前 (該当する場合) などが入ります。

ある関数が、その関数を定義したスクリプトファイル内のトップレベルスコープから直接呼び出された場合、レベル $i コールスタックの ${FUNCNAME[$i+1]} が含まれています。

  • main (疑似関数名)、スクリプトファイルが起動された場合 直接 (例) ./script )

  • source (擬似関数名)であった場合、スクリプトファイルが サード (例) source ./script または . ./script ).