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