間接拡張とは何ですか?$ {!var *}はどういう意味ですか?


85

初心者のためのBashガイド」を読んでいます。それは言う:

の最初の文字がPARAMETER感嘆符である場合、Bashは残りの部分から形成された変数の値を変数PARAMETERの名前として使用します。次に、この変数が展開され、その値は、PARAMETERそれ自体の値ではなく、残りの置換で使用されます。これは、間接拡張として知られています。

与えられた例は次のとおりです。

franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH

私はここで完全に理解していません:

残りの部分から形成された変数の値 PARAMETER

PARAMETERだけで!N*、その後、

残りの PARAMETER

だけN*です。これはどのように変数を形成することができますか?Bashはそこで可能なすべてのコマンドを検索しましたか?

回答:


110

bashマニュアルページを読むと、基本的にあなたが述べたことを確認します。

パラメータの最初の文字が感嘆符(!)の場合、可変間接参照のレベルが導入されます。Bashは、残りのパラメーターから形成された変数の値を変数の名前として使用します。次に、この変数が展開され、パラメーター自体の値ではなく、その値が残りの置換で使用されます。これは、間接拡張として知られています。

しかし、そこから読んでください:

これに対する例外は、以下の拡張${!prefix*}${!name[@]}説明です。

${!prefix*}プレフィックスに一致する名前。名前が接頭辞で始まり、IFS特殊変数の最初の文字で区切られた変数の名前に展開されます。

言い換えれば、あなたの特定の例${!N*}はあなたが引用した規則の例外です。それはない、しかし、仕事のような予想例、で広告として:

$ export xyzzy=plugh ; export plugh=cave

$ echo ${xyzzy}  # normal, xyzzy to plugh
plugh

$ echo ${!xyzzy} # indirection, xyzzy to plugh to cave
cave

答えてくれてありがとう。「初心者のためのBashガイド」を読めば読むほど、著者が自分の書いたものを理解しているかどうかを自問します。
LRDPRDX

23

ここでのように、指定された「間接参照」がで終わる場合は例外のよう*です。この場合、指定した部分(Nここ)で始まるすべての変数名が付けられます。Bashは変数を追跡し、どの変数が存在するかを知っているので、それを行うことができます。

真の間接はこれです:
セイ私は変数持つ$VARIABLEにセットし42て、私は別の変数持つ$NAMEにセットをVARIABLE${!NAME}私に与えます42。ある変数の値を使用して、別の変数の名前を通知します。

$ NAME="VARIABLE"
$ VARIABLE=42
$ echo ${!NAME}
42

4
うわー、人生の意味、宇宙、そしてすべての答えを得るのはとても簡単だと誰が知っていましたか?
KomodoDave 2014年

3

はい、!の後に変数の可能なすべての展開を検索します。行った場合:

echo ${!NP*}

あなただけを得るでしょうNPX_PLUGIN_PATH

次の例を考えてみましょう。

:~> export myVar="hi"
:~> echo ${!my*}
    myVar
:~> export ${!my*}="bye"
:~> echo $myVar
    bye

my *に一致する他の変数も「bye」に設定されますか?
アンソニー

1
@Anthony試してみましたが、${!my*}myA、myBに展開すると、myAは現在の値でエクスポートされ、myBは「bye」に設定されてエクスポートされます。あまり役に立ちません。
GKFX 2016年

3

間接処理で例外が発生しました。最後の文字が*、の場合、前にプレフィックスが指定されているすべての変数が返されます。


それで、*ケースを除いて、これはと同じ${${VAR}}ですか?
クロノスプーン2014年

1
@chronospoon、は${${VAR}}、より短く書き込み可能ですが、記号に続くことができない文字列を返すため、${$VAR}合法ではありません。文字列を変数名として使用するには、(元の質問自体で引用されているように)1レベルの間接参照を導入する必要があります。つまり、を使用できます。これは、期待どおりに(誤って、しかし理解できるように)実行します。$VAR$${!VAR}${$VAR}
エンリコ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.