bash xargs: o mesmo comando fornece resultados diferentes

1

Quando eu corro

ls -1 *.a | xargs -I{} echo {} | sed 's/.a//'

A saída é

1
2
3

Quando eu corro

ls -1 *.a | xargs -I{} bash -c "echo {} $(echo {} | sed 's/.a//')"

e a saída é

1.a 1.a
2.a 2.a
3.a 3.a

Qual é o motivo dessa anomalia?

    
por stas 24.06.2016 / 19:22

1 resposta

1

Vamos supor que você esteja em seu diretório com a presença dos arquivos 1.a , 2.a , 3.a .

Com o comando

ls *.a | xargs -I{} echo {} | sed 's/.a//'

você não tem subshells, a saída de ls é canalizada em xargs que faz suas substituições. Em seguida, a saída é canalizada para sed . Daqui seu primeiro resultado.

Com o comando

ls *.a | xargs -I{} bash -c "echo {} $(echo {} | sed 's/.a//')"

você tem um novo elemento $(echo {} | sed 's/.a//') .

Ele é expandido e se torna

echo {}                # -- > {}
echo {} | sed 's/.a//' # -- > {}  again the same.

para que seu comando possa ser reescrito como

 ls *.a | xargs -I{} bash -c "echo {} {} "

que dá o seu segundo resultado.

Como acabamos de dizer também guest em seu comentário, depure seu script [ 1 ] (ou comando); com set -x , ative a depuração no shell ou script atual e, com set +x , desative-a:

set -x    
ls *.a | xargs -I{} bash -c "echo {} $(echo {} | sed 's/.a//')"
set +x    

e você verá cada etapa

+ ls --color=auto 1.a 2.a 3.a
++ echo '{}'
++ sed s/.a//
+ xargs '-I{}' bash -c 'echo {} {}'
1.a 1.a
2.a 2.a
3.a 3.a
    
por 24.06.2016 / 20:05