Di versi lama bashAnda harus mengutip variabel setelahnya <<<. Itu diperbaiki di 4.4. Dalam versi yang lebih lama, variabel akan dipecah pada IFS dan kata-kata yang dihasilkan bergabung di ruang sebelum disimpan dalam file sementara yang membentuk <<<pengalihan itu.
Di 4.2 dan sebelumnya, ketika mengarahkan ulang builtin seperti readatau command, pemisahan itu bahkan akan mengambil IFS untuk builtin itu (4.3 memperbaiki itu):
$ 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
Yang diperbaiki di 4.3:
$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a.b.c.d
Namun $amasih ada pemisahan kata di sana:
$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a b c d
Dalam 4.4:
$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a.b.c.d
Untuk portabilitas ke versi yang lebih lama, kutip variabel Anda (atau gunakan dari zshmana <<<asalnya dan yang tidak memiliki masalah itu)
$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d
Perhatikan bahwa pendekatan untuk memecah string hanya berfungsi untuk string yang tidak mengandung karakter baris baru. Juga mencatat bahwa a..b.c.akan terpecah menjadi "a", "", "b", "c"(tidak ada mengosongkan elemen terakhir).
Untuk membagi string sewenang-wenang, Anda dapat menggunakan operator split + glob sebagai gantinya (yang akan menjadikannya standar dan menghindari menyimpan konten variabel dalam file temp seperti <<<halnya):
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
atau:
array=($var'') # in shells with array support
The ''adalah untuk melestarikan elemen kosong tertinggal jika ada. Itu juga akan membagi kosong $varmenjadi satu elemen kosong.
Atau gunakan shell dengan operator pemisahan yang tepat:
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