In alten Versionen mussten bash
Sie danach Variablen zitieren <<<
. Das wurde in 4.4 behoben. In älteren Versionen wurde die Variable in IFS aufgeteilt und die resultierenden Wörter im Leerzeichen verbunden, bevor sie in der temporären Datei gespeichert wurden, aus der diese <<<
Umleitung besteht.
In Version 4.2 und früher, wenn Buildins wie read
oder umgeleitet werden command
, würde diese Aufteilung sogar das IFS für dieses Builtin erfordern (4.3 hat das behoben):
$ 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
Das in 4.3 festgelegte:
$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a.b.c.d
Aber $a
unterliegt dort immer noch der Wortspaltung:
$ 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
Geben Sie für die Portabilität auf ältere Versionen Ihre Variable an (oder verwenden Sie, zsh
woher das <<<
kommt und wo dieses Problem nicht auftritt).
$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d
Beachten Sie, dass dieser Ansatz zum Teilen einer Zeichenfolge nur für Zeichenfolgen funktioniert, die keine Zeilenumbrüche enthalten. Beachten Sie auch , dass a..b.c.
wäre aufgeteilt in "a"
, ""
, "b"
, "c"
(kein letztes Element leer).
Um beliebige Zeichenfolgen zu teilen, können Sie stattdessen den Operator split + glob verwenden (was ihn zum Standard macht und das Speichern des Inhalts einer Variablen in einer temporären Datei wie <<<
folgt vermeidet ):
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
oder:
array=($var'') # in shells with array support
Das ''
soll ein nachfolgendes leeres Element beibehalten, falls vorhanden. Das würde auch ein leeres $var
in ein leeres Element aufteilen .
Oder verwenden Sie eine Shell mit einem geeigneten Aufteilungsoperator:
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