1

Whenever I read about IFS it was always in the context of read (or at least thus I understood).

Is IFS used for anything else than read shell-builtin?

Kusalananda
  • 333,661
  • 3
    Yes, it's used for everything that does word splitting which is a lot of things. – jesse_b Mar 17 '21 at 12:19
  • Word splitting / field splitting (parsing?) is something that as far as I know any shell does without calling a certain program but read (which for the record is a shell-builtin) has a special call for IFS, if I am not wrong about this. – variableexpander Mar 17 '21 at 12:26
  • 1
    read doesn't call any program either. By that logic, eval and exec also do the same thing. – muru Mar 17 '21 at 12:32

1 Answers1

7

The POSIX shell manual has the following to say about field splitting:

2.6.5 Field Splitting

After parameter expansion (Parameter Expansion), command substitution (Command Substitution), and arithmetic expansion (Arithmetic Expansion), the shell shall scan the results of expansions and substitutions that did not occur in double-quotes for field splitting and multiple fields can result.

The shell shall treat each character of the IFS as a delimiter and use the delimiters as field terminators to split the results of parameter expansion, command substitution, and arithmetic expansion into fields.

If the value of IFS is a <space>, <tab>, and <newline>, or if it is unset, any sequence of <space>, <tab>, or <newline> characters at the beginning or end of the input shall be ignored and any sequence of those characters within the input shall delimit a field. For example, the input:

<newline><space><tab>foo<tab><tab>bar<space>

yields two fields, foo and bar.

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

Otherwise, the following rules shall be applied in sequence. The term " IFS white space" is used to mean any sequence (zero or more instances) of white-space characters that are in the IFS value (for example, if IFS contains <space>/ <comma>/ <tab>, any sequence of <space> and <tab> characters is considered IFS white space).

IFS white space shall be ignored at the beginning and end of the input.

Each occurrence in the input of an IFS character that is not IFS white space, along with any adjacent IFS white space, shall delimit a field, as described previously.

Non-zero-length IFS white space shall delimit a field.

So any time the shell expands an unquoted parameter, command substitution, or arithmetic expansion it will split the result into fields based on how IFS is set.

You can see this in the context of parameter expansion with the following:

$ IFS=$' \t\n'
$ var='foo:bar'
$ printf '<%s>\n' $var
<foo:bar>
$ IFS=:
$ printf '<%s>\n' $var
<foo>
<bar>
$ printf '<%s>\n' "$var"
<foo:bar>
$ set -- foo bar baz
$ echo "$*"
foo:bar:baz
$ IFS=$' \t\n'
$ echo "$*"
foo bar baz
$
jesse_b
  • 37,005
  • 1
    To see the effect of word splitting, it would make more sense to use something like printf '<%s>\n' $var. Using echo (which joins its arguments with spaces) combined with awk (which splits on blanks or whitespace) confuses things IMO. – Stéphane Chazelas Mar 17 '21 at 17:07