misc/159642: bash shell fails to convert string to array when IFS is a space

Peter Maloney peter.maloney at brockmann-consult.de
Wed Aug 10 13:00:29 UTC 2011


>Number:         159642
>Category:       misc
>Synopsis:       bash shell fails to convert string to array when IFS is a space
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 10 13:00:28 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Peter Maloney
>Release:        8.2-RELEASE
>Organization:
Brockmann Consult
>Environment:
FreeBSD bcnastest3.bc.local 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Thu Feb 17 02:41:51 UTC 2011     root at mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64

>Description:
The bash shell fails to convert a string to an array when IFS is a space.

Works as expected with the latest Ubuntu, and some old installations I tried:
bash: 4.2.8(1)-release, linux: Ubuntu 11.04 64 bit 
bash: 3.2.39(1)-release, linux: Ubuntu 8.04.4 LTS 64 bit
bash: 3.00.15(1)-release, linux: Red Hat Enterprise Linux ES release 4 32 bit

$ IFS=' '
$ x="1 2 3 4"
$ y=($x)
$ echo ${y[0]}
1

$ IFS=','
$ x="1,2,3,4"
$ y=($x)
$ echo ${y[0]}
1


First line sets the "internal field separator" to a space (which should have no effect since default includes space).
Second line creates a string with spaces in it.
Third line sets y to an array given the input string from x (and conversion here uses the IFS variable set on line 1)
Fourth line prints the first element of the array.
Fifth line is the output.

However, on FreeBSD, it doesn't work as expected.

bash was built from /usr/ports/shells/bash/

$ bash -version
GNU bash, version 4.1.9(0)-release (amd64-portbld-freebsd8.2)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ ps | grep $$
 1201   0  S      0:01.00 bash

$ which bash
/usr/local/bin/bash

$ IFS=$' '
$ x="1 2 3 4"
$ y=($x)
$ echo ${y[0]}
1 2 3 4

workaround (replace line 3):
$ eval y=($x)

result with workaround:
$ echo ${y[0]}
1

Works when IFS is "," for some reason. I didn't test other special characters.
$ IFS=$','
$ x="1,2,3,4"
$ echo ${y[0]}

$ y=($x)
$ echo ${y[0]}
1
$ echo ${y[1]}
2



>How-To-Repeat:
Run script (default IFS):

x="1 2 3 4"
y=($x)
echo ${y[0]}

or

IFS=$' '
x="1 2 3 4"
y=($x)
echo ${y[0]}
>Fix:
workaround:
replace:
    $ y=$(x)
with
    $ eval y=($x)

However, this is likely not a good "fix" since then the array is created with the default IFS, so there are possible side effects.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list