A primeira executa find ./ $OPT1 $OPT2 $OPT3
word-splits e globs a saída (sem aspas em torno de $()
) e passa para echo
, que a imprime. O que é basicamente o mesmo que executar o comando find
, mas as novas linhas são transformadas em espaços e, se algum nome de arquivo impresso por find
contiver *
ou ?
, eles serão expandidos. Embora se seu IFS
contiver algo incomum, a divisão de palavras será similarmente incomum. (Além disso, $OPT1
e outros também não são citados, então eles são divididos e globbed antes de passar para find
.)
O segundo imprime find ./ $OPT1 $OPT2 $OPT3
, expandindo as variáveis (novamente dividindo e globbing, porque não há aspas) e passa o resultado para bash
, que o executa como um comando. Novamente praticamente o mesmo que apenas executar o find
, mas se as variáveis contiverem metacaracteres do shell, elas serão expandidas (novamente) pelo segundo shell.
O primeiro, observe que o nome do arquivo foo*
está expandido, globbing os três:
$ touch foo1 foo2 foo\*
$ echo $(find .)
. ./foo2 ./foo* ./foo1 ./foo2 ./foo1
O segundo, note que o pipe para bash faz com que a variável interna seja expandida, como se você usasse eval
:
$ OPT='echo $BASH_VERSION'
$ echo $OPT
echo $BASH_VERSION
$ echo $OPT | bash
4.3.30(1)-release
$ eval $OPT # about the same
4.3.30(1)-release
Expansão variável é provavelmente o exemplo mais simples disso, mas precisa de uma variável exportada ou uma que o outro shell tenha, em qualquer caso, como BASH_VERSION
aqui. (Eu não posso chegar a um exemplo são com find
por enquanto.)
Dependendo do que suas variáveis OPT
contenham, a rodada extra de avaliação poderá fazer a diferença se find
corresponder a alguma coisa.