Versuche, eine Zeichenfolge in zwei Variablen aufzuteilen

Ich versuche eine Zeichenfolge in zwei Variablen aufzuteilen (ohne eine while-Schleife verwenden zu müssen):

var="hello:world" IFS=':' read var1 var2 <<< $var echo "var1: $var1" echo "var2: $var2" 

aber ich bekomme nicht das gewünschte Ergebnis:

 var1: 'hello world' var2: '' 

Könnte jemand bitte erklären, ob es möglich ist, es auf diese Weise (oder ähnlich) zu machen?

   

Dies ist ein Fehler in Bash 4.2. Siehe chepners Antwort für eine korrekte Erklärung.


Es geht um Zitate. Benutzen:

 IFS=':' read var1 var2 < << "$var" ^ ^ 

Anstatt von

 IFS=':' read var1 var2 < << $var 

Siehe Ergebnis:

 $ IFS=':' read var1 var2 < << "$var" $ echo "var1=$var1, var2=$var2" var1=hello, var2=world 

Aber

 $ IFS=':' read var1 var2 < << $var $ echo "var1=$var1, var2=$var2" var1=hello world, var2= 

FYI für zukünftige Leser:

Nachdem wir dies mit den Entwicklern besprochen haben, scheint dies ein Fehler in bash 4.2 zu sein und wurde in der kommenden Version 4.3 behoben. Aus dem Änderungsprotokoll für den Entwicklungspfad

rrrr. Mehrere Probleme mit IFS behoben, wenn es in der temporären Umgebung angezeigt wird und in Umleitungen verwendet wird.

Obwohl es immer eine gute Idee ist, Parametererweiterungen zu zitieren, sollte der OP-Code wie vorgesehen ohne Anführungszeichen funktionieren.


Hier ist eine Erklärung des Fehlers. Mit dem Code

 var="hello:world" IFS=':' read var1 var2 < << $var 

Das nicht aufgezählte $var sollte ein einzelnes Wort sein, da es kein Zeichen im globalen Wert von IFS ( IFS kein Leerzeichen). read sollte dann die string hello:world . Da es zwei Argumente erhalten hat, sollte es Wort-Splitting mit seinem lokalen Wert von IFS var1 und hello und world erzeugen, die var1 bzw. var2 zugewiesen sind.

Der Fehler besteht darin, dass die hier angegebene Zeichenfolge anscheinend teilweise geteilt wird, indem der "leaked" Wert von IFS zum read . Als Ergebnis wird die Zeichenfolge hello world , wird aber immer noch als ein einzelnes Wort read . Da dieses Wort kein a enthält, wird read nicht in zwei Wörter aufgeteilt, und die gesamte Zeichenfolge wird var1 zugewiesen.

In bash 4.3 wird, wie dokumentiert, die Erweiterung von $var als Argument für den Operator < << keiner Worttrennung unterzogen; der Code

 var="hello:1:2 world" IFS=: read var1 var2 < << $var 

setzt var1 auf hello und var2 auf 1:2 world .