È una combinazione di due cose. Innanzitutto, l'espansione delle parentesi graffe non è un modello che corrisponde ai nomi dei file: è una sostituzione puramente testuale - vedi Qual è la differenza tra `a [bc] d` (parentesi) e` a {b, c} d` (parentesi graffe)? . In secondo luogo, quando si utilizza il risultato di una sostituzione di comando al di fuori delle doppie virgolette ( ls $(…)), ciò che accade è solo la corrispondenza dei modelli (e la suddivisione delle parole: l'operatore "split + glob"), non un riepilogo completo.
Con ls $(echo 'test?.txt'), il comando echo 'test?.txt'genera la stringa test?.txt(con una nuova riga finale). La sostituzione del comando genera la stringa test?.txt(senza una nuova riga finale, poiché la sostituzione del comando rimuove le righe successive). Questa sostituzione non quotata viene suddivisa in parole, producendo un elenco costituito da una singola stringa test?.txtpoiché non contiene caratteri di spazi bianchi (più precisamente, nessun carattere $IFS). Ogni elemento di questo elenco di un elemento subisce quindi l'espansione jolly condizionale e poiché ?nella stringa è presente un carattere jolly, si verifica l'espansione jolly. Poiché il modello test?.txtcorrisponde almeno a un nome file, l'elemento list test?.txtviene sostituito dall'elenco dei nomi file che corrispondono ai pattern, producendo l'elenco a due elementi contenentetest1.txte test2.txt. Alla fine lsviene chiamato con due argomenti test1e test2.
Con ls $(echo 'test{1,2}'), il comando echo 'test{1,2}'genera la stringa test{1,2}(con una nuova riga finale). La sostituzione del comando risulta nella stringa test{1,2}. Questa sostituzione non quotata viene suddivisa in parole, producendo un elenco costituito dalla singola stringa test{1,2}. Ogni elemento di questo elenco di un elemento viene quindi sottoposto a espansione jolly condizionale, che non fa nulla (l'elemento viene lasciato così com'è) poiché nella stringa non sono presenti caratteri jolly. Così lsviene chiamato con il singolo argomento test{1,2}.
Per confronto, ecco cosa succede ls $(echo test{1,2}). Il comando echo test{1,2}genera la stringa test1 test2(con una nuova riga finale). La sostituzione del comando genera la stringa test1 test2(senza una nuova riga finale). Questa sostituzione non quotata viene suddivisa in parole, producendo due stringhe test1e test2. Quindi, poiché nessuna delle stringhe contiene un carattere jolly, vengono lasciate sole, quindi lsviene chiamata con due argomenti test1e test2.