0

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)

Zombo
  • 1
  • 62
  • 391
  • 407
  • 1
    @fedorqui spooky, I'm on `GNU bash, version 4.2.45(2)-release (x86_64-slackware-linux-gnu)` and can reproduce the OP's behaviour – Tom Fenech Jul 24 '14 at 09:36
  • 1
    Reproduced with `GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)`. Output is `111 222 333` – user000001 Jul 24 '14 at 10:06
  • For those interested, this is the changelog of bash 4.2: https://github.com/sunny256/bash/blob/master/CWRU/changelog Somewhere there must be some explanations, as it is from 4.1 to 4.2 when this changes. – fedorqui Jul 24 '14 at 10:12
  • This may also be loosely related to http://stackoverflow.com/q/20144593/1126841 (in that proper support of here strings and IFS seems to be an ongoing process). – chepner Jul 24 '14 at 15:48

1 Answers1

7

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.

Zombo
  • 1
  • 62
  • 391
  • 407
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • 2
    +1 `cat` doesn't use `IFS`; things like `IFS=, read a b c` work because `read` is a `bash` builtin, not an external program. – chepner Jul 24 '14 at 15:45