次のsourceable bar
Bashスクリプトがあるとします...
echo :$#:"$@":
...および次の実行可能ファイルfoo
Bashスクリプト:
echo -n source bar:
source bar
echo -n source bar foo:
source bar foo
function _import {
source "$@"
}
echo -n _import bar:
_import bar
echo -n _import bar foo:
_import bar foo
foo
Bashスクリプト、つまり./foo
を実行すると、次の出力が表示されます。
source bar::0::
source bar foo::1:foo:
_import bar::1:bar:
_import bar foo::1:foo:
ここに私の質問があります:
_import
関数からBashのsource
コマンドを呼び出すと、なぜ違いが生じるのですか?source
コマンドの動作を正規化するにはどうすればよいですか?Fedoraバージョン20でBashバージョン4.2.47(1)-releaseを使用しています。
Gnoucの答えは私の最初の質問を説明します:「直接ではなく、_import関数からBashのソースコマンドを呼び出すとき、なぜ違いがあるのですか?」
2つ目の質問について:「Bashのソースコマンドの動作を正規化するにはどうすればよいですか?」
私は次の答えを見つけたと思います:
_import
関数:
function _import {
local -r file="$1"
shift
source "$file" "$@"
}
foo
Bashスクリプトを実行すると、次の出力が得られます。つまり、./foo
:
source bar::0::
source bar foo::1:foo:
_import bar::0::
_import bar foo::1:foo:
私の質問とこの答えの背後にある根拠:「インポートされた」Bashスクリプトは、インポート中に何も指定されていない場合でも、Bashの位置パラメータと特殊パラメータを介して独自の引数セットを評価できるはずです。インポートするBashスクリプトに渡される可能性のある引数は、インポートされるBashスクリプトに暗黙的に渡されてはなりません。
現在の環境でsource
実行ファイルが原因の問題。また、bash
では、位置パラメータが指定されていない場合、変更されません。 bash
から Bourne Shell Builtins のマニュアルページ:
。 (期間)
。ファイル名[引数]
現在のシェルコンテキストのファイル名引数からコマンドを読み取り、実行します。ファイル名にスラッシュが含まれていない場合、PATH変数を使用してファイル名が検索されます。 BashがPOSIXモードでない場合、ファイル名が$ PATHで見つからない場合、現在のディレクトリが検索されます。 引数が指定されている場合、それらはfilenameが実行されるときの位置パラメータになります。それ以外の場合、位置パラメータは変更されません。戻りステータスは、最後に実行されたコマンドの終了ステータス、またはコマンドが実行されていない場合はゼロです。ファイル名が見つからないか、読み取ることができない場合、戻りステータスはゼロ以外です。この組み込みはソースと同等です。
POSIXは dot を定義します(source
はdot
のbash
と同義です):
シェルは、現在の環境でファイルからコマンドを実行します。
また、ドットのKornShellバージョンは、位置パラメーターに設定されたオプションの引数を取ることができることも説明しました。
KornShellバージョンのドットは、定位置パラメーターに設定されるオプションの引数を取ります。これは、ドットスクリプトが関数と同じように動作できるようにする有効な拡張機能です。
そのため、source bar
関数内で_import
を呼び出す場合、位置パラメータは指定しないため、変更されません。これらは_import
関数スコープと同じで、$@
にはbar
が含まれ、$#
は1
です(_import bar
を実行するため)。
source bar
関数スコープの外で_import
を呼び出すと、グローバルスコープ(またはfoo
スクリプト)と同じになります。この場合、./foo
を実行するので、引数なしでfoo
を実行します。$@
はnullで、$#
はゼロです。