Why does my script only read two lines of a file and not the third

I'm learning about the read command and wrote this little script to read data from a file:

readfile()
{
 while read variable; do
echo $variable
done
}    
readfile < File.txt

I have three lines in File.txt; each a single word. The script only echoes the first two lines and drops the third one. Can anyone tell me why?

Also, what does the statment

if [ $variable ] mean? Does it mean 'if the value of variable exists....'?

can you post your File.txt?This code runs okay on my laptop.
I think [ $variable ] means to test if the value of variable is null or unset,if so,evaluated as false.use [ -n $variable ] or [ -z $variable ] will be better.

Sure can. Here is the file -- only three lines

Red
Blue
Green

It echoes Red and Blue but not green. Did it return all the lines in your file?

--Works fine for me too:

$ cat testit
readfile()
{
  while read variable; do
echo $variable
done
}
readfile < File.txt
$ cat File.txt
one
two
three
$ ./testit
one
two
three

if [$variable ] wont work as intended when $variable contains a space eg variable="one two" , best to stick with:

if [ -n "$variable" ]

Never mind -- figured it out, although I feel like an idiot. :o

I saved the file without hitting return after the last word. Out of curiosity, can anyone tell me why that is?
Runs fine now.

:),interesting~Even without hitting return,i get three lines and if i hit return,it will print a blank line as expected.

read returns a non-zero if it encounters a END-OF-FILE char and zero if it encounters a CR char. variables are populated with anything that is read to this point.

You should probably do something like:

readfile()
{
  while read variable; do
    echo "$variable"
  done
  echo -e "${variable}\c"
}

Thanks, Chubler. But as I'm still learning about these things, could you explain the last few lines of code to me -- I mean the \c part? Zero is the successful exit status or is it 1, I forget.

the -e option of echo is a bash/ksh thing and enables the interpreation of backslash escapes. \c is used to suppress the CR at the end of a string.

So by echoing the variable with \c we duplicate the contents of the file by showing any value without a CR as it was input. Now, if no line exists without a CR at the end of the file, the variable will be blank and so we echo blank without a CR (i.e. nothing).

read returns 0 if more data is available (ie no EOF is read) and non-zero (typically 1) if and EOF is found.

Instead of echo -e you could use printf which works in other shells too:

printf "%s" "$variable"

Or if you do not want to preserve the non-linefeed ending of the last line (which is not a proper unix text file format)

while read variable || [ -n "$variable" ]; do
  echo "$variable"
done