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


13

ダッシュでは、関数と変数は別々の名前空間にあるように見えます:

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の保証ですか?


2
実際のコードは、fn関数が別の名前空間にあることを証明しません。一度実行すると定義が一掃された場合、まったく同じ動作が見られます。関数がまだ定義されていることを、たとえばtype fn後で示す必要があります。
アレクシス

回答:


13

保証

2.9.5関数定義コマンド

関数は、新しい定位置パラメーターを使用して複合コマンドを呼び出すための単純なコマンドとして使用されるユーザー定義の名前です。関数は「関数定義コマンド」で定義されます。[...]

この関数はfnameという名前です。アプリケーションは、それが名前(XBD名を参照)であり、特別な組み込みユーティリティの名前ではないことを保証する必要があります。実装では、関数名に他の文字を拡張として使用できます。実装は、関数と変数のために別々の名前空間を維持しなければなりません。


また、それは注意しunsetている-vと、-f指定した名前の変数や関数を設定解除のどちらかを選択します。bash(他のほとんどのシェルではなく)設定が解除されますfoo 機能unset fooまったくありません場合はfoo、変数を(!)、POSIXで許可された行動を。そのため、POSIXスクリプトでは、常に-vまたはのいずれかを使用することをお勧めします-f(もちろん、bashスクリプトでも同様unsetですがbashbash変数の設定を常に解除するとは限らないことに注意してください、変数のスコープにはかなりの問題があります)。
ステファンシャゼラス

シェルショック前のbashでは、bashが両方に同じ環境変数名を使用するようになるため、変数と関数の両方を特定の名前でエクスポートすると問題が発生することに注意してください(環境で2回置くと、いくつかのコマンドが削除できますそれらの1つ)
ステファンシャゼル

8

変数と関数はダッシュの異なる名前空間に存在し、これもPOSIXで指定されています:

実装は、関数と変数の個別の名前空間を維持するものとします。

それに加えて、変数にはデフォルトでグローバルスコープがあります。一部のシェル(bash、ksh、zshなど)は、localローカルスコープのみで関数内の変数を宣言するためのキーワードを提供します。

したがって、はい、あなたが見ている動作はPOSIXによって保証されています。

POSIXはしていない標準化され localまだ

初期の提案での関数の説明は、関数がミニチュアシェルスクリプトのように動作するという概念に基づいていました。つまり、変数の共有を除き、実行環境のほとんどの要素は、新しい実行環境であるかのように動作する必要があります[..]

[..]関数内のローカル変数は考慮され、別の初期提案(特別なビルトインによって制御される)に含まれましlocal、関数用に開発された単純なモデルに適合せず、追加することに反対するため削除されました歴史的慣習の一部ではない別の新しい特別なビルトイン。実装では、このローカル変数メカニズムがこの標準の将来のバージョンで採用される場合に備えて、識別子local(およびtypesetKornShellで使用される)を予約する必要があります。

(エンファシス鉱山)


ダッシュも有する基づいている(80年代後半からの)灰local、(例えばbashでひどく破壊1と比較して)そこに最も一貫したインターフェースの一つのみつい最近のbash(4.4)は、借用local -(のローカルスコープのオプション)from ash(その1つの$-変数のみに対してashスタイルのスコープを実装します)。kshとyashにはないlocal(pdkshバリアントのみにあるlocal)が、typeset代わりにあります(ksh93 typesetでは、ksh構文を使用して宣言された関数でのみローカル(静的)スコープを提供します)。
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.