La diferencia más importante entre
bash -c "$1"
Y
eval "$1"
Es que el primero se ejecuta en una subshell y el segundo no. Asi que:
set -- 'var=something'
bash -c "$1"
echo "$var"
SALIDA:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
SALIDA:
something
Sin embargo, no tengo idea de por qué alguien usaría el ejecutable bash
de esa manera. Si debe invocarlo, utilice el POSIX garantizado incorporado sh
. O (subshell eval)
si desea proteger su medio ambiente.
Personalmente, prefiero el caparazón .dot
sobre todo.
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
SALIDA
something1
something2
something3
something4
something5
¿PERO LO NECESITA?
La única causa para usar, en realidad, es en el caso de que su variable realmente asigne o evalúe a otra, o la división de palabras sea importante para la salida.
Por ejemplo:
var='echo this is var' ; $var
SALIDA:
this is var
Eso funciona, pero solo porque echo
no le importa su conteo de argumentos.
var='echo "this is var"' ; $var
SALIDA:
"this is var"
¿Ver? Las comillas dobles aparecen porque $var
no se evalúa el resultado de la expansión de la shell quote-removal
.
var='printf %s\\n "this is var"' ; $var
SALIDA:
"this
is
var"
Pero con eval
o sh
:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
SALIDA:
this is var
this is var
Cuando usamos eval
o sh
el shell da un segundo paso a los resultados de las expansiones y también los evalúa como un comando potencial, por lo que las citas marcan la diferencia. También puedes hacer:
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
SALIDA
this is var
e='echo foo'; $e
funciona bien