$ 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 second
is a subprocess of the current shell process? If yes, why don't we needexport IFS=";"
? - why is
IFS
empty?
$ 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 \t
ab, and a \n
ewline. 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 $a
produces;
. Tested using bash on Debian Gnu+Linux. – ctrl-alt-delor Aug 30 '14 at 21:30IFS
but nota
:IFS=";"; echo $IFS
produces blank line, butIFS=";"; echo "$IFS"
produces;
. – ctrl-alt-delor Aug 30 '14 at 21:33a
as well. so it typeIFS=" "
, and now it is working fora
without the quotes. Therefore the value ofIFS
is changing the behaviour. – ctrl-alt-delor Aug 30 '14 at 21:37