Isso é intencional, para evitar quebrar a conformidade com POSIX (embora inicialmente tenha sido para evitar a quebra da compatibilidade com o Bourne).
echo file_{2}([0-9])
seria um código inválido em Bourne / POSIX sh , portanto, ksh está livre para interpretá-lo como quiser. Mas:
pattern='file_{2}([0-9])'
echo $pattern
é válido como código Bourne / POSIX sh e, conforme POSIX, deve corresponder aos arquivos nomeados como file_{2}(0) , file_{2}(1) ...
Os operadores estendidos não estão disponíveis quando eles são o resultado de uma expansão, mesmo se você usar:
echo @($pattern)
Você precisaria usar eval ou também poderia usar FIGNORE :
FIGNORE="!($pattern)"; echo *
(cuidado, porém, isso afeta a expansão de arquivos ocultos, torne-o FIGNORE="@(.*|!($pattern))" se você não espera que o glob expanda arquivos ocultos).
Observe que bash e zsh adotaram alguns desses ksh de operadores estendidos (embora não o {x,y}(...) one), mas eles abordaram a compatibilidade do POSIX / Bourne de maneira diferente: eles disponibilizam esses globs estendidos em todos contextos, mas somente quando uma opção específica é ativada ( kshglob in zsh , extglob in bash ). Isso significa, no entanto, que é difícil para eles adicionar mais operadores sem quebrar sua própria compatibilidade com versões anteriores. Por exemplo, se bash adicionasse o operador {x,y}(...) agora, ele poderia quebrar os scripts que esperam que a='{1}(2){3}'; [[ $a = $a ]] retorne verdadeiro.