Un bon moyen de travailler avec evalest de le remplacer par echopour les tests. echoet evaltravailler de la même manière (si nous mettons de côté l' \xexpansion effectuée par certaines echoimplémentations comme celle bashde certaines dans certaines conditions).
Les deux commandes joignent leurs arguments avec un espace entre les deux. La différence est que le résultat est echo affiché pendant qu'il eval évalue / interprète le code shell comme résultat.
Donc, pour voir quel code shell
eval $(echo $var_name=$var_value)
évaluerait, vous pouvez exécuter:
$ echo $(echo $var_name=$var_value)
fruit=blue orange
Ce n'est pas ce que vous voulez, ce que vous voulez c'est:
fruit=$var_value
De plus, l'utilisation $(echo ...)ici n'a pas de sens.
Pour afficher ce qui précède, vous devez exécuter:
$ echo "$var_name=\$var_value"
fruit=$var_value
Donc, pour l'interpréter, c'est simplement:
eval "$var_name=\$var_value"
Notez qu'il peut également être utilisé pour définir des éléments de tableau individuels:
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
Comme d'autres l'ont dit, si vous ne vous souciez pas que votre code soit bashspécifique, vous pouvez l'utiliser declarecomme:
declare "$var_name=$var_value"
Notez cependant qu'il a des effets secondaires.
Il limite la portée de la variable à la fonction dans laquelle elle est exécutée. Vous ne pouvez donc pas l'utiliser par exemple dans des choses comme:
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
Parce que cela déclarerait une foovariable locale à setvarso serait inutile.
bash-4.2ajouté une -goption pour declaredéclarer une variable globale , mais ce n'est pas ce que nous voulons non plus car notre setvardéfinirait une variable globale par opposition à celle de l'appelant si l'appelant était une fonction, comme dans:
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"
qui produirait:
1:
2: some value
Notez également que while declareest appelé declare(en fait bashemprunté au concept du shell Korn typeset), si la variable est déjà définie, declarene déclare pas de nouvelle variable et la façon dont l'affectation est effectuée dépend du type de la variable.
Par exemple:
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
produira un résultat différent (et aura potentiellement des effets secondaires désagréables) s'il a varnameété précédemment déclaré comme un scalaire , un tableau ou un tableau associatif .
evalcette façon est faux. Vous développez$var_valueavant de le transmettre, ceevalqui signifie qu'il va être interprété comme du code shell! (essayez par exemple avecvar_value="';:(){ :|:&};:'")