En versiones anteriores de bash
usted tenía que citar variables después <<<
. Eso fue arreglado en 4.4. En versiones anteriores, la variable se dividiría en IFS y las palabras resultantes se unirían en el espacio antes de almacenarse en el archivo temporal que constituye esa <<<
redirección.
En 4.2 y anteriores, al redirigir las construcciones como read
o command
, esa división incluso tomaría el IFS para esa construcción (4.3 solucionó eso):
$ 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
Ese arreglado en 4.3:
$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a.b.c.d
Pero $a
todavía está sujeto a la división de palabras allí:
$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a b c d
En 4.4:
$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a.b.c.d
Para la portabilidad a versiones anteriores, indique su variable (o use de zsh
dónde <<<
proviene en primer lugar y eso no tiene ese problema)
$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d
Tenga en cuenta que ese enfoque para dividir una cadena solo funciona para cadenas que no contienen caracteres de nueva línea. También tenga en cuenta que a..b.c.
se dividiría en "a"
, ""
, "b"
, "c"
(sin vaciar último elemento).
Para dividir cadenas arbitrarias, puede usar el operador split + glob en su lugar (lo que lo haría estándar y evitaría almacenar el contenido de una variable en un archivo temporal como lo <<<
hace):
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
El ''
es preservar un elemento vacío final si lo hay. Eso también dividiría un elemento vacío $var
en un elemento vacío.
O use un shell con un operador de división adecuado:
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