The Theory
There are two concepts that are in play here :
IFSis the Input Field Separator, which means the string read will be split based on the characters inIFS. On a command line,IFSis normally any whitespace characters, that's why the command line splits at spaces.- Doing something like
VAR=value commandmeans "modify the environment of command so thatVARwill have the valuevalue". Basically, the commandcommandwill seeVARas having the valuevalue, but any command executed after that will still seeVARas having its previous value. In other words, that variable will be modified only for that statement.
In this case
So when doing IFS= read -r line, what you are doing is setting IFS to an empty string (no character will be used to split, therefore no splitting will occur) so that read will read the entire line and see it as one word that will be assigned to the line variable. The changes to IFS only affect that statement, so that any following commands won't be affected by the change.
As a side note
While the command is correct and will work as intended, setting `IFS` in this caseOne line is read from the standard input [...] and the first word is assigned to the first name, the second word to the second name, and so on, with leftover words and their intervening separators assigned to the last name. If there are fewer words read from the input stream than names, the remaining names are assigned empty values. The characters in
IFSare used to split the line into words. [...]
Since you only have the line variable, every words will be assigned to it anyway, so if you don't need any of the preceding and trailing whitespace characters1 you could just write read -r line and be done with it.
[1] As rightly noted by mikeservJust as an example of how an unset or default $IFS value will cause read to regard leading/trailing IFS whitespace, you might try:
echo ' where are my spaces? ' | {
unset IFS
read -r line
printf %s\\n "$line"
} | sed -n l
Run it and you will see that the preceding and trailing characters won't survive if IFS is not unset. Furthermore, some strange things could happen if IFS$IFS was to be modified somewhere earlier in the script.