Shell – Understanding IFS

shell

The following few threads on this site and StackOverflow were helpful for understanding how IFS works:

But I still have some short questions. I decided to ask them in the same post since I think it may help better future readers:

Q1. IFS is typically discussed in the context of "field splitting". Is field splitting the same as word splitting ?

Q2: The POSIX specification says:

If the value of IFS is null, no field splitting shall be performed.

Is setting IFS= the same as setting IFS to null? Is this what is meant by setting it to an empty string too?

Q3: In the POSIX specification, I read the following:

If IFS is not set, the shell shall behave as if the value of IFS is
<space>, <tab> and <newline>

Say I want to restore the default value of IFS. How do I do that? (more specifically, how do I refer to <tab> and <newline>?)

Q4: Finally, how would this code:

while IFS= read -r line
do    
    echo $line
done < /path_to_text_file

behave if we we change the first line to

while read -r line # Use the default IFS value

or to:

while IFS=' ' read -r line

Best Answer

  1. Yes, they are the same.
  2. Yes.
  3. In bash, and similar shells, you could do something like IFS=$' \t\n'. Otherwise, you could insert the literal control codes by using [space] CTRL+V [tab] CTRL+V [enter]. If you are planning to do this, however, it's better to use another variable to temporarily store the old IFS value, and then restore it afterwards (or temporarily override it for one command by using the var=foo command syntax).
    • The first code snippet will put the entire line read, verbatim, into $line, as there are no field separators to perform word splitting for. Bear in mind however that since many shells use cstrings to store strings, the first instance of a NUL may still cause the appearance of it being prematurely terminated.
    • The second code snippet may not put an exact copy of the input into $line. For example, if there are multiple consecutive field separators, they will be made into a single instance of the first element. This is often recognised as loss of surrounding whitespace.
    • The third code snippet will do the same as the second, except it will only split on a space (not the usual space, tab, or newline).