Nelle vecchie versioni bashhai dovuto citare le variabili dopo <<<. Ciò è stato risolto in 4.4. Nelle versioni precedenti, la variabile veniva suddivisa su IFS e le parole risultanti venivano unite nello spazio prima di essere archiviate nel file temporaneo che costituisce il <<<reindirizzamento.
In 4.2 e prima, quando si reindirizzava builtin come reado command, tale suddivisione avrebbe persino preso l'IFS per quel builtin (4.3 risolto che):
$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a b c d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. cat <<< $a'
a.b.c.d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. command cat <<< $a'
a b c d
Quello risolto in 4.3:
$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a.b.c.d
Ma $aè ancora soggetto alla suddivisione delle parole lì:
$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a b c d
In 4.4:
$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a.b.c.d
Per la portabilità alle versioni precedenti, cita la tua variabile (o usa da zshdove <<<proviene in primo luogo e che non ha quel problema)
$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d
Si noti che tale approccio alla divisione di una stringa funziona solo per le stringhe che non contengono caratteri di nuova riga. Si noti inoltre che a..b.c.sarebbe diviso in "a", "", "b", "c"(senza svuotare ultimo elemento).
Per dividere stringhe arbitrarie puoi usare invece l'operatore split + glob (che lo renderebbe standard ed eviterebbe di archiviare il contenuto di una variabile in un file temporaneo <<<):
var='a.new
line..b.c.'
set -o noglob # disable glob
IFS=.
set -- $var'' # split+glob
for i do
printf 'item: <%s>\n' "$i"
done
o:
array=($var'') # in shells with array support
È ''preservare un elemento vuoto finale se presente. Ciò dividerebbe anche un vuoto $varin un elemento vuoto.
O utilizzare una shell con un operatore di divisione appropriato:
zsh:
array=(${(s:.:)var} # removes empty elements
array=("${(@s:.:)var}") # preserves empty elements
rc:
array = ``(.){printf %s $var} # removes empty elements
fish
set array (string split . -- $var) # not for multiline $var