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.