Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.
$ IFS=";"

$ read first second 
i am;a_i b c
$ echo $first
i am
$ echo $second
a_i b c

$ echo $IFS
  1. Am I right that read first second is a subprocess of the current shell process? If yes, why don't we need export IFS=";"?
  2. why is IFS empty?
share|improve this question
    
What shell are you using? a=";"; echo $a produces ;. Tested using bash on Debian Gnu+Linux. –  richard Aug 30 at 21:30
    
Strangely it needs quotes for IFS but not a: IFS=";"; echo $IFS produces blank line, but IFS=";"; echo "$IFS" produces ;. –  richard Aug 30 at 21:33
    
And now it is broken for a as well. so it type IFS=" ", and now it is working for a without the quotes. Therefore the value of IFS is changing the behaviour. –  richard Aug 30 at 21:37
    
bash. @richard . –  Tim Aug 30 at 21:43

4 Answers 4

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

share|improve this answer
    
Thanks. (1) if 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 at 21:38
    
@Tim: (1) Yes. (2) Because you have changed value 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 at 21:51
    
The answers at that link are not very good. –  mikeserv Aug 31 at 2:49
    
Depending on the shell, 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 1 at 17:25

If we type type read we get read is a shell builtin. Therefore it is not run as a sub-process.

share|improve this answer

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).

share|improve this answer
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
<      ><><><><><><>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.