web-dev-qa-db-ja.com

シェルスクリプトで変数の内容の内容を印刷することは可能ですか? (間接参照)

次の変数を宣言したとします。

$ var='$test'
$ test="my string"

それらの内容を印刷すると、次のようになります。

$ echo $var
$test

$ echo $test
my string

$varのコンテンツ($testのコンテンツ)を印刷する方法を見つけたいのですが。だから私は次のことをやろうとしました:

$ echo $(echo $var)
$test

しかし、ここでは結果は$testであり、"my string"ではありません... bashを使用して変数の内容の内容を印刷することは可能ですか?

13
Rafael Muynarsk

これは、bashの間接変数展開を使用して実現できます(参照変数から$を省略してもかまいません)。

$ var=test
$ test="my string"
$ echo "$var"
test
$ echo "${!var}"
my string

.5.3シェルパラメータの拡張

21
jesse_b

varに含まれる変数名の前に$が付いている場合は、evalを使用できます。

$ var='$test'
$ test="my string"
$ eval echo $var
my string

そこで何が起こるの:

  • bashは$varを値$testに展開し、eval echo $testコマンドを生成します。
  • evalecho $test式を評価し、望ましい結果を生成します。

一般にevalを使用すると危険な場合があるため(varに何が格納されているかによって)、使用しないことをお勧めします。間接拡張機能の方が適しています(ただし、$サインイン$testを取り除く必要があります)。

10
Danila Kiver

Jesse_bの回答 に似ていますが、変数の間接参照の代わりに名前参照変数を使用します(bash 4.3+が必要):

$ declare -n var=test
$ test="my string"
$ echo "$var"
my string

名前参照変数varは、参照している変数の名前を保持します。変数が$varとして逆参照されると、他の変数の値が返されます。

bashは名前参照を再帰的に解決します:

$ declare -n var1=var2
$ declare -n var2=test
$ test="hello world"
$ echo "$var1"
hello world

完全を期すために、(bash 4.0+で)連想配列を使用することも、要件に応じてこれを解決する1つの方法です。

$ declare -A strings
$ strings[test]="my string"
$ var=test
$ echo "${strings[$var]}"
my string

これにより、動的に決定される可能性のあるキーまたは名前によって複数の値にアクセスするより柔軟な方法が提供されます。これは、特定のカテゴリのすべての値を単一の配列に収集したいが、汚染しないので、いくつかのキー(IDでアクセスできる名前、または目的でアクセスできるパス名など)で引き続きアクセスできる場合に適しています。スクリプトの変数の名前空間。

9
Kusalananda