È 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?.txt
poiché 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?.txt
corrisponde almeno a un nome file, l'elemento list test?.txt
viene sostituito dall'elenco dei nomi file che corrispondono ai pattern, producendo l'elenco a due elementi contenentetest1.txt
e test2.txt
. Alla fine ls
viene chiamato con due argomenti test1
e 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ì ls
viene 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 test1
e test2
. Quindi, poiché nessuna delle stringhe contiene un carattere jolly, vengono lasciate sole, quindi ls
viene chiamata con due argomenti test1
e test2
.