$ IFS=";"
$ read first second
i am;a_i b c
$ echo $first
i am
$ echo $second
a_i b c
$ echo $IFS
- Am I right that
read first secondis a subprocess of the current shell process? If yes, why don't we needexport IFS=";"? - why is
IFSempty?
$ IFS=";"
$ read first second
i am;a_i b c
$ echo $first
i am
$ echo $second
a_i b c
$ echo $IFS
read first second is a subprocess of the current
shell process? If yes, why don't we need export IFS=";"?IFS empty?Am I right that read first second is a subprocess of the current shell process? If yes, why don't we need export IFS=";"?
No, read is a bash bultin function. No subshell or subprocess is created here, so we don't need to export IFS.
why is IFS empty?
Because you don't use double quote. You have changed value IFS to ;, so when you echo $IFS, after $IFS is expanded to ;, the shell performs word spliting and globbing, with ; as separator. So nothing is printed.
Try:
$ IFS=";"
$ printf "%s\n" $IFS
$ printf "%s\n" "$IFS"
;
Note
If we type type read we get read is a shell builtin. Therefore it is not run as a sub-process.
In answer to why IFS is empty. It is not. But the value in IFS is changing the behaviour of the shell. Below is not an explanation but just the result of my experiments using bash on Debian Gnu+Linux.
a=";"; echo $a produces ;.
IFS=";"; echo $IFS produces blank line.
IFS=";"; echo "$IFS" produces ;.
Now a=";"; echo $a produces blank line, but IFS=" "; a=";"; echo $a produces ; again.
So
Now IFS=";"; a=";"; echo $a produces blank line, but IFS=" "; a=";"; echo $a produces ;.
Therefore the value of IFS changes the behaviour (then quotes not used in echo).
IFS=\;; set -- $IFS; echo $#; echo "$*"
1
;
IFS=; set -- $IFS; echo $#; echo "$*"
0
#there doesn't seem to be anything here
As you can see - $IFS is not empty in the first case - it contains exactly one field separator.
When the shell expands an unquoted variable it splits its value on the delimiters defined in $IFS. In this way each variable is, potentially, an $IFS separated array. By default $IFS is set to a <space>, a \tab, and a \newline. Each of these has special qualities in $IFS as they are $IFS whitespace. $IFS whitespace delimiters are not retained and each sequence of either is instead truncated to a single field when the shell performs the wordsplitting, whereas all others will delimit a single field per separator. $IFS whitespace will also be removed entirely from either the beginning or end of a field. For instance:
IFS=/; slashes=///////; printf '<%s>' $slashes
<><><><><><><>
IFS=' '; spaces=' '; printf '<%s>' $spaces
<>
printf '<%s>' $spaces$slashes
<///////>
But $IFS whitespace is obviously not removed when it is not in $IFS:
IFS=/; printf '<%s>' $spaces$slashes
< ><><><><><><>