2

I am using Bash 5.0.17 on Ubuntu 20.04

This is a followup to this question. Before asking the question I thought I understand how IFS works but now I am TOTALLY confused and I have a chain of questions:

  1. What is meant by static strings?
  2. What is the difference between word splitting and expansion?
  3. I've read somewhere on this website that quoting variables is recommended (*) but sometimes I am getting different results, e.g:
IFS=":"; for i in 1:2:3; do echo $i; done # output: 1 2 3
IFS=":"; for i in 1:2:3; do echo "$i"; done # output: 1:2:3

Why do the quotes make a difference between the two commands?

Please, if you think these are stupid questions just ignore it. If someone is interesting to help me clear this confusion I will be really grateful to his/her help

Thank you

EDIT: added links below


(*): I am refering to these two answers:

  • 5
    Just to say you would get the same output without the loop: i=1:2:3; echo "$i" would output 1:2:3 regardless of IFS, while i=1:2:3; echo $i would output 1 2 3 if IFS=:. Your loop does nothing apart from assigning 1:2:3 to i. – Kusalananda Dec 19 '21 at 22:13
  • This is very closely related: https://unix.stackexchange.com/questions/523187/use-of-ifs-in-for-loop – pLumo Dec 20 '21 at 07:16

2 Answers2

3

Your for-loop does not behave like you think it does:

IFS=":"; for i in 1:2:3; do ...

$i will be literally 1:2:3, so your loop only runs once.

Words are split using the special variable IFS only with variable expansion or using read command.

And this also the answer for your question.

When you run IFS=:; i=1:2:3; echo $i;, the expansion (and the word splitting) happens only with the last command and the "words" (1, 2 and 3) are echoed separately --> 1 2 3. (Like @ikkachu already said in his answer, this is just how echo behaves).
Putting quotes around $i will prevent word splitting, and echo will output the variable literally (1:2:3).


You can also use this knowledge to fix your for loop by using variable expansion:

IFS=:; var=1:2:3; for i in $var; do echo $i; done

will output:

1
2
3
pLumo
  • 22,565
  • Could you please read my post and answer it in the order I asked the questions? you didn't answer any of those questions. – Amazigh_05 Dec 20 '21 at 10:18
-2

I think I have found answers to my questions (for the last two questions, thanks to this webpage ).

1. What is a static string?

This is not accurate wording. But I think it means a "literal" string.

2. What is the difference between expansion and word splitting?

Exapansion refers to: Brace expansion, Tilde expansion, Shell parameter and variable expansion (this involves using $ symbol), command substitution, arithmetric expansion, process substitution, Word splitting, and File name expansion.

So the word splitting is a special case of expansion and to quote the webpage above:

The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting.

The shell treats each character of $IFS as a delimiter, and splits the results of the other expansions into words on these characters. If IFS is unset, or its value is exactly "''", the default, then any sequence of IFS characters serves to delimit words. If IFS has a value other than the default, then sequences of the whitespace characters "space" and "Tab" are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character). Any character in IFS that is not IFS whitespace, along with any adjacent IF whitespace characters, delimits a field. A sequence of IFS whitespace characters is also treated as a delimiter. If the value of IFS is null, no word splitting occurs.

Explicit null arguments ("""" or "''") are retained. Unquoted implicit null arguments, resulting from the expansion of parameters that have no values, are removed. If a parameter with no value is expanded within double quotes, a null argument results and is retained.

But the important thing to remember is:

If no expansion occurs, no splitting is performed.

3. The third question is answered by question 2.