IFS change with Bash 4.2

2019-04-16 22:24发布

问题:

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)

回答1:

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.



标签: bash ifs