使用する良い方法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="';:(){ :|:&};:'"
)