Trying to split a string into two variables
Solution 1:
This is a bug in Bash 4.2. See chepner's answer for a proper explanation.
It is about quotes. Use:
IFS=':' read var1 var2 <<< "$var"
^ ^
instead of
IFS=':' read var1 var2 <<< $var
See result:
$ IFS=':' read var1 var2 <<< "$var"
$ echo "var1=$var1, var2=$var2"
var1=hello, var2=world
But
$ IFS=':' read var1 var2 <<< $var
$ echo "var1=$var1, var2=$var2"
var1=hello world, var2=
Solution 2:
FYI for future readers:
After discussing this with the developers, it appears this is indeed a bug in bash
4.2, and has been fixed in the upcoming 4.3 release. From the devel branch change log
rrrr. Fixed several problems with IFS when it appears in the temporary environment and is used in redirections.
Although it's always a good idea to quote parameter expansions anyway, the OP's code should work as intended without quotes.
Here's an explanation of the bug. With the code
var="hello:world"
IFS=':' read var1 var2 <<< $var
the unquoted $var
should be a single word, since it contains no character in the global value of IFS
(that is, no white-space). read
should then see the string hello:world
. Because it received two arguments, it should apply word-splitting using its local value of IFS
, producing hello
and world
which are assigned to var1
and var2
, respectively.
The bug is that the here string appears to undergo partial splitting using the "leaked" value of IFS
being passed to read
. As a result, the string becomes hello world
, but is still seen by read
as a single word. Since that word does not contain a :
, read
does not split it into two words, and the entire string is assigned to var1
.
In bash
4.3, as documented, the expansion of $var
does not undergo word-splitting as the argument to the <<<
operator; the code
var="hello:1:2 world"
IFS=: read var1 var2 <<< $var
sets var1
to hello
and var2
to 1:2 world
.