Porque são duas coisas diferentes. O {1,2,3}
é um exemplo de expansão de contraventores . A construção {1,2,3}
é expandida pelo shell , antes que echo
a veja. Você pode ver o que acontece se você usar set -x
:
$ set -x
$ echo {1,2,3}
+ echo 1 2 3
1 2 3
Como você pode ver, o comando echo {1,2,3}
é expandido para:
echo 1 2 3
No entanto, [[:digit:]]
é uma classe de caracteres POSIX . Quando você dá a echo
, o shell também o processa primeiro, mas desta vez ele está sendo processado como um shell glob . funciona da mesma forma como se você executasse echo *
, o que imprimiria todos os arquivos no diretório atual. Mas [[:digit:]]
é uma globalização que corresponderá a qualquer dígito. Agora, no bash, se um shell glob não corresponder a nada, ele será expandido para si mesmo:
$ echo /this*matches*no*files
+ echo '/this*matches*no*files'
/this*matches*no*files
Se o glob corresponder a algo, isso será impresso:
$ echo /e*c
+ echo /etc
/etc
Em ambos os casos, echo
apenas imprime o que o shell lhe diz para imprimir, mas no segundo caso, como o glob corresponde a algo ( /etc
), é dito para imprimir esse item.
Portanto, como você não possui arquivos ou diretórios cujo nome consista exatamente em um dígito (que é o que [[:digit:]]
corresponderia), o glob é expandido para si mesmo e você obtém:
$ echo [[:digit:]]
[[:digit:]]
Agora, tente criar um arquivo chamado 5
e executando o mesmo comando:
$ echo [[:digit:]]
5
E se houver mais de um arquivo correspondente:
$ touch 1 5
$ echo [[:digit:]]
1 5
Isso é (mais ou menos) documentado em man bash
na explicação das opções nullglob
, o que desativa esse comportamento:
nullglob
If set, bash allows patterns which match no files (see
Pathname Expansion above) to expand to a null string,
rather than themselves.
Se você definir esta opção:
$ rm 1 5
$ shopt -s nullglob
$ echo [[:digit:]] ## prints nothing
$