間接参照を使用して変数を設定できますか?

間接参照を使用して変数を設定できますか?

たとえば、次のスクリプトは規則Helloに従って印刷されます。${!

A=B
B=Hello
echo ${!A}

しかし、私はどうすればいいですか?置く間接名を持つ変数の値?シンボルを直接使用すると!機能しません。

A=B
!A=Hello # here is tricky line
echo $B

一時ファイルを使用するためのトリックがあることを知っていますが、次のようなものではなく間接的な使用に興味があります。

A=B
echo "$A=Hello" > 1.tmp
. 1.tmp
echo $B

答え1

typeset組み込み関数を使用してこれを実行できます。

$ A=B
$ typeset $A=42
$ echo $B
42

または以下を使用してくださいdeclare

$ declare $A=1
$ echo $B
1

答え2

フォローする変数値を取得する間接的な方法

移植可能な方法はを使用することですeval。値の特殊文字が評価されない場合に評価されないように、引用符を処理する必要があります。最も簡単な方法は、新しい値を中間変数に保存し、その変数の値を割り当てることです。

A=B
tmp='stuff with special characters or whatever…'
eval $A=\$tmp

パラメータは単純な割り当てevalです。B=$tmpスペースやワイルドカード文字が含まれていても、$tmpこれらの文字は割り当てで拡張されないため、二重引用符は必要ありません。

環境変数を生成するには使用できますexport。 bash、ksh、またはzshでは、typesetこれを使用してローカル変数(declarebashの同義語)を生成できます。今回も特殊文字が破損しないように中間変数を使用する必要があります。 zshを除いて、変数拡張の周りに二重引用符が必要です。これは、代入ではなく、代入のように見える引数を取る組み込み関数だからです。

export $A="$tmp"

答え3

試してみるもう1つの方法は次のとおりです。

$ A=B
$ read $A <<< 81
$ echo "$B"
81

ただし、これらすべての方法にはセキュリティリスク(!)があります。この場合、declare左(の値)を制御する必要があります。つまり、少なくともでは、変数に入力ファイルなどのユーザーが制御する入力を含めてはいけません。typeseteval$Abash$A


シェルがこの文字列(<<<)をサポートしていない場合は、ここでドキュメントを使用することもできます。

A=B
read $A << EOF
82
EOF
echo "$B"

答え4

printf別の方法は、名前を引数として渡すことができる変数に出力を割り当てるwithを使用することです-v

A=B
printf -v "$A" '%s' "Hello"
echo ${!A}

関連情報