Why is this shell script printing inputs twice?I expected the script to ignore the inputs after 5.Script:#! /bin/bashecho Enter 5 words : read  a b c d e printf > %s %s %s %s %s < $a $b $c $d $eOutput:user@linux:~$ pico ifs2.shuser@linux:~$ ./ifs2.shEnter 5 words : 1 2 3 4 5 > 1 2 3 4 5 <user@linux:~$ ./ifs2.shEnter 5 words : 1 2 3 4 5 6> 1 2 3 4 5 <> 6     <user@linux:~$ ./ifs2.shEnter 5 words : 1 2 3 4 5 6 7 8 9 0> 1 2 3 4 5 <> 6 7 8 9 0 <user@linux:~$ And, the following script works no matter what is set to $IFS. Why?#! /bin/bash    old=$IFSIFS=:echo IFS = $IFSecho Enter 5 words : read  a b c d e printf > %s %s %s %s %s < $a $b $c $d $e    IFS=$oldOutput:user@linux:~$ ./ifs2.shIFS = :Enter 5 words : 1 2 3 4 5  > 1 2 3 4 5      <user@linux:~$ ./ifs2.shIFS = :Enter 5 words : 1 2 3 4 5> 1 2 3 4 5     <user@linux:~$ ./ifs2.shIFS = :Enter 5 words : 1:2:3:4:5> 1 2 3 4 5 <user@linux:~$ 
Why does printf print more arguments than expected?
shell script
You have three problems:With read, if there are fewer variable names than fields in the input, the last var will be bound to all the remaining fields on the line, with delimiters. That means that $e gets 5 6 in your first unexpected example.Because all of $a..$e are unquoted, their values undergo field splitting. If $e holds 5 6 then it expands into two arguments to the command.printf consumes all its arguments, using as many arguments at once as there are % substitutions, repeatedly. This is buried in the documentation as:The format operand shall be reused as often as necessary to satisfy the argument operands. Any extra c or s conversion specifiers shall be evaluated as if a null string argument were supplied; other extra conversion specifications shall be evaluated as if a zero argument were supplied.In other words, if there are unused arguments it starts over again and processes them from the beginning too, including the whole format string. This is useful when you want to format an entire array, say:printf '%b ' ${array[@]}Your printf command gets one argument from each of $a..$d, and then however many are left over from $e. When $e is 5 6, printf has two goes around, the second just getting 6 to format. When it's 5 6 7 8 9 10 it has the full range of substitutions for the second printing.You can avoid all of these by adding an extra dummy field to read, and quoting your parameter substitutions (which is always a good idea):read  a b c d e dummyprintf > %s %s %s %s %s < $a $b $c $d $eThis will give:Enter 5 words : 1 2 3 4 5 6 7 8 9 10> 1 2 3 4 5 <dummy gets all the extra fields, and printf only gets the five arguments you expected.Your second edited-in question has a similar answer: only a gets a value when IFS doesn't have a space. That means $b..$e expand to nothing, so printf only gets a single argument. Your spaces from the format string are printed, with nothing substituted in between them (as if a null string argument were supplied).