Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting IFS for a single statement

Tags:

bash

ifs

On my GNU bash, version 4.3.42(1)-release I am doing some tests to answer a question. The idea is to split a :-separated string and and each of its elements into an array.

For this, I try to set the IFS to : in the scope of the command, so that the split is automatic and IFS remains untouched:

$ myvar="a:b:c"
$ IFS=: d=($myvar)
$ printf "%s\n" ${d[@]}
a
b
c

And apparently IFS remains the same:

$ echo $IFS
                      # empty

The BASH reference says that:

If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are joined without intervening separators.

However, then I notice that the IFS is kind of broken, so that echo $myvar returns a b c instead of a:b:c.

Unsetting the value solves it:

$ unset IFS
$ echo $myvar
a:b:c

But I wonder: what is causing this? Isn't IFS=: command changing IFS just in the scope of the command being executed?

I see in Setting IFS for a single statement that this indeed works:

$ IFS=: eval 'd=($myvar)'
$ echo $myvar
a:b:c

But I don't understand why it does and IFS=: d=($myvar) does not.

like image 302
fedorqui 'SO stop harming' Avatar asked Oct 29 '15 14:10

fedorqui 'SO stop harming'


1 Answers

I was going to comment on this when I saw you use it, but it didn't occur to me until just now what the problem was. The line

IFS=: d=($myvar)

doesn't temporarily set IFS; it simply sets two variables in the current shell. (Simple commands can be prefixed with local environment settings, but an assignment statement itself is not a simple command.)

When you write

echo $IFS

IFS expands to :, but because : is the first character of IFS, it is removed during word splitting. Using

echo "$IFS"

would show that IFS is still set to :.

like image 166
chepner Avatar answered Sep 22 '22 04:09

chepner