Você pode ver exatamente qual comando está sendo executado usando set -x
. Um exemplo bastante bobo:
$ echo $(echo "foo 'bar baz' taz\ jaz")
foo 'bar baz' taz\ jaz
vai dar:
++ echo 'foo '\''bar baz'\'' taz\ jaz'
+ echo foo ''\''bar' 'baz'\''' 'taz\' jaz
foo 'bar baz' taz\ jaz
Isto é um pouco difícil de ler, por causa de todo o escape. Por exemplo, essa segunda palavra:
-
''
não é nada. -
\'
se torna uma cotação única ('
) -
'bar'
se tornabar
para que o parâmetro seja passado como 'bar
. Você pode confirmar com algo assim (supondo que você tenha Data :: Dump instalado, que não é o padrão, infelizmente) Observe que o $(echo…
foi copiado na linha perl:
$ perl -MData::Dump=pp -E 'pp @ARGV' $(echo "foo 'bar baz' taz\ jaz")
("foo", "'bar", "baz'", "taz\", "jaz")
O que está acontecendo aqui é que o bash está fazendo a divisão de palavras (com base em $IFS
) e não a análise de argumentos. Então, infelizmente, você provavelmente terá que usar eval
e lidar com todo o risco que isso implica.
$ eval "echo $(echo "foo 'bar baz' taz\ jaz")"
foo bar baz taz jaz
(Além disso, observarei, se você conseguir que seu comando gere sua saída como uma lista de nomes, separados por NUL, isso seria fácil para lidar com xargs -0
e mais, totalmente seguro).