シェルスクリプトを使用して変数のコンテンツを印刷することはできますか?(間接参照)


13

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

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

コンテンツを印刷すると、次のように表示されます。

$ echo $var
$test

$ echo $test
my string

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

$ echo $(echo $var)
$test

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


あなたは可能性が編集し、使用しているシェルいる、またはあなたが持っているものポータビリティ要件を言うためにあなたのポストを?
マイケルホーマー

@MichaelHomerもちろんですが、この情報をどのように確認できますか?
ラファエルムイナルスク

確認するものよりも、選択するものの方が多いです。たとえば、、ashまたはbash、またはcsh、またはdash、...、またはzsh、またはPOSIX shを使用してスクリプトを実行していますか、または異なるシステム間で作業する必要がありますか?
マイケルホーマー

@MichaelHomerあ、なるほど...私はbashを使っています。最後の質問を変更して、新しいタグを挿入します。
ラファエルムイナルスク

回答:



10

に含まれる変数名にvar接頭辞が付いている$場合は、次を使用できますeval

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

そこで何が起こるの:

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

eval一般的に使用することは危険である可能性があることに注意してください(保存されている内容によって異なりますvar)。間接的な拡張機能は、あなたの場合に適しています(ただし、$サインインを取り除く必要があります$test)。


確かに、それはタイプミスです。元の投稿には一重引用符が付いています。修繕。
ダニラ・キーヴァー

4
変数参照を二重引用符で囲むことを常にお勧めします(予期しない単語の分割やワイルドカードの展開によるトラブルを避けるため)。ではeval、二重引用符の2つの層が必要ですeval echo "\"$var\""。気を付けてください、これはevalあなたが言及した他の使用の危険については何もしません。
ゴードンデイヴィ

9

Jesse_bの答えに似ていますが、変数間接指定の代わりに名前参照変数を使用します(bash4.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でアクセスできる名前、目的でアクセスできるパス名など)で汚染しないため、それらにアクセスできる場合に望ましいスクリプトの変数名前空間。


3

zsh

$ var='$test'
$ test='*'
$ printf '%s\n' ${(e)var}
*

Bourneのようなシェルで

$ eval 'printf "%s\n" "'"$var"'"'
*

これらのシェルでは、split + glob(zsh例外)を防ぐために変数展開を引用する必要がありecho、任意のデータには使用できないことに注意してください。

両方で以来(e)evalシェルコードの評価があり、それはの内容が重要です$var任意のコマンドインジェクションの脆弱性(と同じにすることができそうでない場合は、あなたのコントロール内の滞在${!var}アプローチが)。

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