POSIXシェルの関数と変数の別々の名前空間

POSIXシェルの関数と変数の別々の名前空間

ダッシュでは、関数と変数が異なる名前空間にあるように見えます。

fn(){
    fn="hello world"
}
fn; echo "The value is $fn!" #prints: The value is hello world!
fn; echo "The value is $fn!" #prints: The value is hello world!
#the fn variable doesn't conflict with the fn function

これはダッシュ固有の機能ですか、それともPOSIX保証ですか?

答え1

保証:

2.9.5 機能定義コマンド

関数は、新しい位置引数を使用して複合コマンドを呼び出すための単純なコマンドとして使用されるカスタム名です。機能は「機能定義コマンド」によって定義されます。[...]

関数名は fname です。アプリケーションでは、この名前が特別な組み込みユーティリティの名前ではなく名前(XBD名を参照)であることを確認する必要があります。実装では、関数名に拡張子として追加の文字を許可できます(MAY)。実装では、関数と変数に対して別々の名前空間を維持する必要があります。

答え2

変数と関数はダッシュの異なる名前空間にあり、これは次のように表示されます。POSIX:

実装では、関数と変数に対して別々の名前空間を維持する必要があります。

また、変数にはデフォルトでグローバルスコープがあります。一部のシェル(例:bash、ksh、zsh)は、localローカルスコープのみを持つ関数で変数を宣言するキーワードを提供します。

はい。現在見ている動作はPOSIXによって保証されます。

まだPOSIXではありません標準化 localしかし、:

以前の提案の関数の説明は、関数を小さなシェルスクリプトのように実行する必要があるという概念に基づいていました。共有変数を除く、実行環境のほとんどの要素は、新しい実行環境のように動作する必要があります。 [..]

[..]関数内のローカル変数が考慮され、別の初期提案に含まれていました(特殊な組み込み関数によって制御されますlocal)。削除されましたなぜなら、機能のために開発された単純なモデルに収まらず、歴史的慣行の一部ではない別の新しい特殊な組み込み機能を追加することに反対があるからです。標準の将来のバージョンがこのローカル変数メカニズムを採用する場合、実装は識別子local(KornShellで使用されているように)を保存する必要があります。typeset

(強調は私のもの)

関連情報