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
$