Una buena forma de trabajar evales reemplazarlo por echopara probar. echoy evalfunciona igual (si dejamos de lado la \xexpansión realizada por algunas echoimplementaciones como bashen algunas condiciones).
Ambos comandos unen sus argumentos con un espacio en el medio. La diferencia es que echo muestra el resultado mientras eval evalúa / interpreta como código shell el resultado.
Entonces, para ver qué código de shell
eval $(echo $var_name=$var_value)
evaluaría, puede ejecutar:
$ echo $(echo $var_name=$var_value)
fruit=blue orange
Eso no es lo que quieres, lo que quieres es:
fruit=$var_value
Además, usar $(echo ...)aquí no tiene sentido.
Para generar lo anterior, ejecutarías:
$ echo "$var_name=\$var_value"
fruit=$var_value
Entonces, para interpretarlo, eso es simplemente:
eval "$var_name=\$var_value"
Tenga en cuenta que también se puede usar para establecer elementos de matriz individuales:
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
Como otros han dicho, si no te importa que tu código sea bashespecífico, puedes usarlo declarecomo:
declare "$var_name=$var_value"
Sin embargo, tenga en cuenta que tiene algunos efectos secundarios.
Limita el alcance de la variable a la función donde se ejecuta. Por lo tanto, no puede usarla, por ejemplo, en cosas como:
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
Porque eso declararía que una foovariable local setvarsería inútil.
bash-4.2agregó una -gopción para declaredeclarar una variable global , pero eso tampoco es lo que queremos, ya setvarque estableceríamos una var global en lugar de la de la persona que llama si la persona que llama fue una función, como en:
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"
que daría salida:
1:
2: some value
Además, tenga en cuenta que mientras declarese llama declare(en realidad bashtomó prestado el concepto de la construcción del shell Korn typeset), si la variable ya está establecida, declareno declara una nueva variable y la forma en que se realiza la asignación depende del tipo de la variable.
Por ejemplo:
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
producirá un resultado diferente (y potencialmente tendrá efectos secundarios desagradables) si varnamese declaró previamente como un escalar , matriz o matriz asociativa .
evalese camino está mal. ¡Se está expandiendo$var_valueantes de pasarlo, loevalque significa que se interpretará como código shell! (prueba por ejemplo convar_value="';:(){ :|:&};:'")