$ 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
read is not a builtin, will I have to export IFS=";"? (2) why do I need double quote for $IFS? Why can i echo $a, if replacing IFS with a?
– Tim
Aug 30 '14 at 21:38
IFS to ;, so when you echo $IFS, after $IFS is expanded to ;, the shell performs spliting fields and globbing, with ; as separator. So nothing is printed.
– cuonglm
Aug 30 '14 at 21:51
echo $IFS will output NL (where $IFS is a field delimiter (bash, some implementations/versions of ksh or dash) or non-whitespace are not considered different from whitespace (Bourne)) as it's like echo ''. And with others (where $IFS is a field separator (zsh, yash, some versions/implementations of dash or ksh), it will output SPC NL as it's like echo '' ''
– Stéphane Chazelas
Sep 01 '14 at 17:25
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
< ><><><><><><>
a=";"; echo $aproduces;. Tested using bash on Debian Gnu+Linux. – ctrl-alt-delor Aug 30 '14 at 21:30IFSbut nota:IFS=";"; echo $IFSproduces blank line, butIFS=";"; echo "$IFS"produces;. – ctrl-alt-delor Aug 30 '14 at 21:33aas well. so it typeIFS=" ", and now it is working forawithout the quotes. Therefore the value ofIFSis changing the behaviour. – ctrl-alt-delor Aug 30 '14 at 21:37