A diferença mais importante entre
bash -c "$1"
E
eval "$1"
É que o primeiro roda em um subshell e o segundo não. Tão:
set -- 'var=something'
bash -c "$1"
echo "$var"
SAÍDA:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
SAÍDA:
something
Não tenho idéia do porquê alguém usaria o executável bash
dessa maneira. Se você precisar chamá-lo, use o built-in garantido POSIX sh
. Ou (subshell eval)
se você deseja proteger seu ambiente.
Pessoalmente, prefiro o shell .dot
acima de tudo.
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
SAÍDA
something1
something2
something3
something4
something5
MAS VOCÊ PRECISA?
A única causa a ser usada é o fato de sua variável realmente atribuir ou avaliar outra, ou a divisão de palavras é importante para a saída.
Por exemplo:
var='echo this is var' ; $var
SAÍDA:
this is var
Isso funciona, mas apenas porque echo
não se importa com a contagem de argumentos.
var='echo "this is var"' ; $var
SAÍDA:
"this is var"
Vejo? As aspas duplas aparecem porque o resultado da expansão de shell $var
não é avaliado quote-removal
.
var='printf %s\\n "this is var"' ; $var
SAÍDA:
"this
is
var"
Mas com eval
ou sh
:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
SAÍDA:
this is var
this is var
Quando usamos eval
ou sh
o shell faz uma segunda passagem nos resultados das expansões e as avalia como um comando potencial também, e assim as aspas fazem a diferença. Você também pode fazer:
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
SAÍDA
this is var
e='echo foo'; $e
funciona muito bem.