I have set the IFS to x, i.e IFS=x. Now if I check the value of IFS, then it appears to be empty if I do not use double-quotes:

~ $ echo $IFS | cat -e
$
~ $ echo "$IFS" | cat -e
x$
~ $ echo $HOME   
/home/mar
~ $ echo "$HOME"
/home/mar
~ $ 

As seen above, $HOME does not behave like that. What is the reason for such behavior?

After the variable is expanded, word-splitting occurs and it gets split into empty word(s). Splitting is done using each character of the IFS variable as delimiter and since $IFS only expands to characters in the IFS it gets split into empty word(s).

So, for example:

IFS=xxx;
printf %q $IFS
''''''[root@localhost ~]#

And if you double quote, you are telling bash to treat everything inside the quotes as one word:

printf %q "$IFS"
xxx[root@localhost ~]#
  • As I understand, if I use single- or double-quotes around the argument for echo, then there is no word-splitting and this single argument is passed to echo. So am I correct that if I don't use double-quotes around the variable name then word-splitting based on characters in IFS variable take place? – Martin Jun 16 '15 at 7:19
  • You are correct, but not single quotes, if you use single quotes: echo '$IFS' result will be $IFS. – taliezin Jun 16 '15 at 7:26
  • I see, thanks! However, how should one understand word-splitting? I mean if I execute examples like IFS="blah" echo $IFS or IFS=x VAR="abcxklm" echo $VAR or IFS=x VAR="abcx" echo $VAR | sed -n l then I would think that word-splitting is substituting characters in expanded variable with space if IFS character(s) is in the middle of the string and with nothing if no other characters follow? – Martin Jun 16 '15 at 8:36
  • you can test simple word-splitting with this: list="koko moko" and then for i in $list and for i in "$list" will produce different results. – taliezin Jun 16 '15 at 9:07

I guess it's related to what's stated in Advanced Bash-Scripting Guide

Use double quotes to prevent word splitting. [2] An argument enclosed in double quotes presents itself as a single word, even if it contains whitespace separators.

With the examples (5.1):

var="'(]\\{}\$\""
echo $var        # '(]\{}$"
echo "$var"      # '(]\{}$"     Doesn't make a difference.

IFS='\'
echo $var        # '(] {}$"     \ converted to space. Why?
echo "$var"      # '(]\{}$"
  • The reason why "\" becomes " " is explained in unix.stackexchange.com/a/209184/27616 (by @StéphaneChazelas ) ( "\" became an IFS, an Input Field Separator, so $var now contains 2 "parts", one before "\", the other after "\". And those 2 parts are written one after the other, separated by a space – Olivier Dulac Jun 15 '15 at 15:34

Another way to work around the word splitting issue here is:

set | grep -w IFS=

which outputs the default IFS as

IFS=$' \t\n'

See this related post on Stack Overflow:

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.