使用する良い方法evalはecho、テスト用に置き換えることです。echoそしてeval同じように動作します(ある条件下でのような\xいくつかのecho実装によって行われる拡張を脇に置いたbash場合)。
両方のコマンドは、間にスペースを1つ入れて引数を結合します。違いは、結果をシェルコードとして評価 / 解釈する間、結果を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を:
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以前にスカラー、配列、または連想配列として宣言されていた場合、異なる結果を生成します(そして潜在的に厄介な副作用があります)。
evalその方法を使用するのは間違っています。$var_value渡す前に展開しているためeval、シェルコードとして解釈されます。(たとえば、試してみてくださいvar_value="';:(){ :|:&};:'")