文字列置換でbash間接参照を使用する必要がないのはなぜですか?

文字列置換でbash間接参照を使用する必要がないのはなぜですか?

Bashスクリプトで私が経験した難しいことの1つは、変数拡張を再帰的に使用することです。

しかし、私は[ChatGPTを介して]位置パラメータ値を参照するために間接置換を使用できることを発見しました。

linkerArgs+=("${!i}")

ただし、文字列置換を使用すると、論理的に拡張を再帰的に使用できます。

"${x// /$newChar}"

bashインタプリタが配列に項目を割り当てるコンテキストで使用されている場合、後者の型の拡張(括弧内のドル記号のみ)を「無効な置換」として扱いますが、文字列置換では使用時に処理しないのはなぜですか?

答え1

代わりに、構文の他の場所に含まれる変数を使用してください。計算名ではなく、計算パラメーターです。

これは古典的なPOSIX置換と連携します(例:${var#replacement}Inside)replacement。置換を実行できます。

$ A=B
$ B=42
$ echo ${$A}
bash: ${$A}: bad substitution
$ echo ${!A}
42

しかし:

$ echo ${B}
42
$ echo ${B%2}
4
$ C=2
$ echo ${B%$C}
4

文法の$Cテキストと同様に動作することがわかります。2${B%<tail-pattern-to-chop>}

構文は${!A}Bash 拡張です。なぜ明確ではないのです${$A}か?

推測するのは難しいです。これは非常に古い Bash 機能です。bash-2.0現在、Bash gitリポジトリの最初にインポートされた1996年のtarballにすでに存在しています。

対照的に、Make言語は計算された変数を使用して明白に実行します$(OBJS_$(this_file))

これは純粋な推測ですが、問題になる可能性があります。 Makeで計算された変数を見ると、.NETの$($(...内部に限定されず、$(...)どこにでも変数を持つことができます。

で置き換えられた${$A}シェルでこれが機能することがわかった場合は、変数を計算して拡張して同様の機能が機能することを期待してください。AB${abc_$A}abc_B

したがって、おそらく実装者/発明者は${!A}それまで行く意向がないでしょう。

もう1つの可能性は、この関数の前に他の${!関数が${!name[@]}すでに存在することです。したがって、その構文に基づいており、後ろに、または来ない${!word}ときに意味が与えられます。既存の拡張の構文に新しい拡張を統合することは、既存の拡張を使用するプログラムにのみ影響を与える可能性がある問題の推論の量を減らすため、簡単です。word@*[*][@]

残念ながら、GNUのFTPリポジトリはタールボールとタールボールのみをbash-1.14.7.tar.gz提供bash-2.0.tar.gzします。その間には何もありません。バージョン1.14.7には正式な拡張はありません${!...}。その問題については、まだ配列を実装していません。バージョン2.0はすべての${!...}構文を${!word}実装しています${name[@]}。何が起こったのかを知るための詳細な記録はありません。

最後の手段として、Chet Raimiをインタビューすることができます。私は答えが次のようになると思います。複数の拡張が変数拡張に追加され、間接参照は独自の構文を取得するのではなく、同じ構文で固定されます。つまり、Bashが見ると、${!「これから様々なBash拡張を処理する」という意味です。

関連情報