Running these commands gives expected results
$ bash --version
GNU bash, version 4.1.11(2)-release
$ foo=(111 222 333)
$ IFS=, cat <<< "${foo[*]}"
111,222,333
However it appears with Bash 4.2 the IFS value is being ignored
$ bash --version
GNU bash, version 4.2.0(1)-release
$ foo=(111 222 333)
$ IFS=, cat <<< "${foo[*]}"
111 222 333
What is causing this difference?
I found the answer here
http://lists.gnu.org/archive/html/bug-bash/2014-03/msg00065.html
It looks as though this has been an error all along. According to Chet,
redirections should never have had access to the temp environment
(IFS
in this case)
I find the behaviour of 4.2 correct as word splitting should happen first before evaluation of assignments:
IFS=, cat <<< "${foo[*]}"
I believe the new value of IFS should only affect cat
and not <<< "${foo[*]}"
.
The proper way to do that is
IFS=, eval 'cat <<< "${foo[*]}"'
And for a conservative approach we can use a function:
function t { cat <<< "${foo[*]}"; }
IFS=, t
I also have a guess that it's related to this:
m. Fixed a bug that caused here documents to not be displayed correctly
when attached to commands inside compound commands.
Update
Another confusing behavior can be found in 4.2 which is already fixed in 4.3. By doing IFS=, cat <<< "${foo[*]}"
, "${foo[*]}"
expands well as "111 222 333"
(not affected by IFS) as shown by cat
which is 111 222 333
. However when we do IFS=, read bar <<< "${foo[*]}"; echo "$bar"
, the output would be 111,222,333
and would appear as if "${foo[*]}"
expanded as "111,222,333"
. This inconsistent behavior is no longer happening in Bash 4.3 and Bash 4.3's behavior is probably a fix.