変数に動的に値を割り当てたいですeval
。次のダミーの例が機能します。
var_name="fruit"
var_value="orange"
eval $(echo $var_name=$var_value)
echo $fruit
orange
ただし、変数の値にスペースが含まれている場合、二重eval
引用符の間にあってもエラーが返されます。$var_value
var_name="fruit"
var_value="blue orange"
eval $(echo $var_name="$var_value")
bash: orange : command not found
この問題を解決する方法はありますか?
答え1
体験版を使用しないでください。declare
$ declare "$var_name=$var_value"
$ echo "fruit: >$fruit<"
fruit: >blue orange<
答え2
eval
この目的には使用しないでくださいdeclare
。
var_name="fruit"
var_value="blue orange"
declare "$var_name=$var_value"
最初の単語だけでなく、それ以降のすべての項目が値と見なされる=
ため、単語の分割は問題になりません。declare
4.3では、bash
名前付き参照を使用すると、この操作がより簡単になります。
$ declare -n var_name=fruit
$ var_name="blue orange"
$ echo $fruit
blue orange
あなたできる作業してみましょうeval
。しかし、それでもやってはいけません:)eval
使用するのは悪い習慣です。
$ eval "$(printf "%q=%q" "$var_name" "$var_value")"
答え3
これを使用する良い方法はテストにeval
置き換えることです。そして同じように動作します(特定の実装によって作成された拡張を除いて(たとえば、特定の条件下で))。echo
echo
eval
\x
echo
bash
どちらのコマンドもスペースを使用して引数を連結します。違いは次のとおりです。echo
見せる同時に結果eval
評価する/説明するシェルコードの結果。
それでは、どのシェルコードがあるのか見てみましょう。
eval $(echo $var_name=$var_value)
評価して以下を実行できます。
$ echo $(echo $var_name=$var_value)
fruit=blue orange
これはあなたが望むものではありません。あなたが望むものは次のとおりです。
fruit=$var_value
また、$(echo ...)
ここで使用することは意味がありません。
上記を出力するには、以下を実行する必要があります。
$ echo "$var_name=\$var_value"
fruit=$var_value
だから簡単に説明すると、次のようになります。
eval "$var_name=\$var_value"
個々の配列要素の設定にも使用できます。
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
他の人が言ったように、コードが具体的であるかどうか気にしない場合は、bash
次のことを使用できますdeclare
。
declare "$var_name=$var_value"
しかし、副作用もあるので注意してください。
変数の範囲を変数を実行する関数に制限します。したがって、次の状況では使用できません。
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
foo
これはローカル変数を宣言するので役に立ちsetvar
ません。
bash-4.2
宣言する-g
オプションが追加されました。declare
グローバルsetvar
しかし、それは私たちが望むものではありません。グローバル呼び出し元が関数の場合、varは呼び出し元のvarとは反対です。
setvar() {
var_name=$1 var_value=$2
declare -g "$var_name=$var_value"
}
foo() {
local myvar
setvar myvar 'some value'
echo "1: $myvar"
}
foo
echo "2: $myvar"
すると、以下が出力されます。
1:
2: some value
またdeclare
、呼び出されている間declare
(実際にbash
Kornシェル組み込みの概念を借用するtypeset
)declare
、変数がすでに設定されている場合、新しい変数は宣言されず、割り当ての実行方法は変数の種類によって異なります。
たとえば、
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
varname
以前に次のように宣言された場合スカラー、大量にまたは連想配列。
また、コンテンツが厳密に管理されていないdeclare
よりも安全ではありません。eval
$varname
たとえば、eval "$varname=\$varvalue"
とが含まれている場合は、両方ともdeclare "$varname=$varvalue"
システムを再起動します。$varname
a[$(reboot)1]
答え4
死んだ参照を使用してください。アポストロフィ。
eval $(echo $var_name='$var_value')
それは私にとって効果的でした。