The IFS variable is used in shells (Bourne, POSIX, ksh, bash) as the input field separator (or internal field separator). Essentially, it is a string of special characters which are to be treated as delimiters between words/fields when splitting a line of input.

The default value of IFS is space, tab, newline. (A three-character string.) If IFS is unset, it acts as though it were set to this default value. (This is presumably for simplicity in shells that do not support the $'...' syntax for special characters.) If IFS is set to an empty string (which is very different from unsetting it!) then no splitting will be performed.

This variable is used in a few different places. The semantics vary slightly:

There are special rules for handling whitespace characters in IFS, in any of the field-splitting situations above (the first two bullet points). Whitespace IFS characters at the beginning and end of a string are removed entirely, and consecutive whitespace IFS characters inside a string are treated as a single delimiter. For example, consider the following:

IFS=: read user pwhash uid gid gecos home shell \
   <<< 'statd:x:105:65534::/var/lib/nfs:/bin/false'

IFS=$' \t\n' read one two three \
   <<< '   1      2  3'

In the first example, the gecos variable is assigned the empty string, which is the contents of the field between the two adjacent colons. The colons are not consolidated together; they are treated as separate delimiters. In the second example, the one variable gets the value 1, and the two variable gets the value 2. The leading whitespace is trimmed, and the internal whitespace is consolidated.

More random examples:

$ IFS= read a b c <<< 'the plain gold ring'
$ echo "=$a="
=the plain gold ring=

$ IFS=$' \t\n' read a b c <<< 'the plain gold ring'
$ echo "=$c="
=gold ring=

$ IFS=$' \t\n' read a b c <<< 'the    plain gold      ring'
$ echo "=$a= =$b= =$c="
=the= =plain= =gold      ring=

The first example above shows the lack of splitting when IFS is empty. The second shows the last variable-name given to a read command absorbing all the remaining words of input. The third shows that splitting and delimiter-consolidation are not performed on the remaining part of a line when assigning excess fields to the last variable.

$ IFS=: read a b c <<< '1:2:::3::4'
$ echo "=$a= =$b= =$c="
=1= =2= =::3::4=

Here's another look at having more input fields than variables. Note that out of the three consecutive colons which follow field 2, precisely one colon was removed in order to terminate field 2. The remaining two colons, as well as two more colons later on, were all left untouched, and assigned to variable c verbatim.

IFS=:
set -f
for dir in $PATH; do
   ...
done
set +f
unset IFS

This example iterates through the colon-separated elements of the PATH variable, presumably to look for a command. It is an overly-simplified example, but should serve to demonstrate how IFS may be used to control WordSplitting. For a better approach to finding commands, see FAQ #81.


CategoryShell