次の変数を宣言するとします。
$ var='$test'
$ test="my string"
内容を印刷すると、以下が表示されます。
$ echo $var
$test
$ echo $test
my string
$var
コンテンツの内容(たとえば、コンテンツ)を印刷する方法を見つけたいです$test
。だから私は次を試してみます。
$ echo $(echo $var)
$test
しかし、結果は$test
そうではありません"my string"
。 bashを使用して変数の内容を印刷できますか?
答え1
$
bashの間接変数拡張を使用してこれを行うことができます(変数から参照を省略できる限り):
$ var=test
$ test="my string"
$ echo "$var"
test
$ echo "${!var}"
my string
答え2
var
含まれる変数名がプレフィックスで始まる場合は、次のものを$
使用できますeval
。
$ var='$test'
$ test="my string"
$ eval echo $var
my string
ここで何が起こっていますか?
- bashは
$var
値に拡張され、コマンドを$test
生成しますeval echo $test
。 eval
echo $test
式を評価し、目的の結果を生成します。
一般的な使用はeval
危険な場合があります(保存されている内容に応じてvar
)、避けるのが最善です。あなたの場合は、間接拡張機能がより適切です(ただし、$
ログインを削除する必要があります$test
)。
答え3
〜のように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以降)を使用することも、要件に応じてこの問題を解決する方法です。
$ declare -A strings
$ strings[test]="my string"
$ var=test
$ echo "${strings[$var]}"
my string
これは、動的に決定できるキーまたは名前を介して複数の値にアクセスするためのより柔軟な方法を提供します。特定のカテゴリのすべての値を単一の配列として収集したいが、まだいくつかのキー(ID固有の名前、宛先固有のパス名など)でその値にアクセスできる場合は、これはより良いオプションです。スクリプトの変数名前空間を汚染しません。
答え4
そしてzsh
:
$ var='$test'
$ test='*'
$ printf '%s\n' ${(e)var}
*
Bourneのようなシェルを使用してください。
$ eval 'printf "%s\n" "'"$var"'"'
*
zsh
これらのシェルでは、分割+glob(例外)を防ぐために変数拡張を引用する必要があり、echo
任意のデータと一緒に使用することはできません。
両方にシェルコード評価機能が(e)
あるため、コンテンツを制御できるeval
ことが重要です。それ以外の場合は、任意のコマンド注入の脆弱性になる可能性があります(方法と同じ)。$var
${!var}