Qual é a diferença entre substituição e tubulação para bash

0

Estou executando esses dois comandos:

echo $(find ./ $OPT1 $OPT2 $OPT3)
echo find ./ $OPT1 $OPT2 $OPT3 | bash

e o mais estranho é que o comando top não produz resultados enquanto o inferior faz. Por que isso?

    
por user2167582 18.09.2016 / 14:21

1 resposta

4

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.

    
por 18.09.2016 / 14:33