Esse problema é muito específico bash
e é porque eles decidiram bash
separar a expansão da chave da expansão do nome do arquivo (globbing) e executá-la primeiro, antes de todas as outras expansões.
Na página de bash
manual:
A ordem das expansões é: expansão de chaves; expansão de til, expansão de parâmetro e variável, expansão aritmética e substituição de comando (feita da esquerda para a direita); divisão de palavras; e expansão do nome do caminho.
No seu exemplo, bash
você só verá seus aparelhos depois de executar a substituição de comando (the $(echo ...)
), quando for tarde demais.
Isso é diferente de todos os outros invólucros, que executam a expansão da cinta logo antes (e alguns até como parte da) expansão do nome do caminho (globbing). Isso inclui, mas não se limita a, csh
onde as expansões de braquetes foram inventadas pela primeira vez.
$ csh -c 'ls `echo "test{1,2}.txt"`'
test1.txt test2.txt
$ ksh -c 'ls $(echo "test{1,2}.txt")'
test1.txt test2.txt
$ var=nope var1=one var2=two bash -c 'echo $var{1,2}'
one two
$ var=nope var1=one var2=two csh -c 'echo $var{1,2}'
nope1 nope2
O último exemplo, é a mesma em csh
, zsh
, ksh93
, mksh
ou fish
.
Além disso, observe que a expansão do suporte como parte do globbing também está disponível através da glob(3)
função de biblioteca (pelo menos no Linux e em todos os BSDs) e em outras implementações independentes (por exemplo, em perl:) perl -le 'print join " ", <test{1,2}.txt>'
.
Por que isso foi feito de maneira diferente bash
provavelmente tem uma história por trás disso, mas FWIW eu não consegui encontrar nenhuma explicação lógica e acho todas as racionalizações post-hoc não convincentes.