read reads a record (line by default, but ksh93/bash/zsh allow other delimiters with
-d, even NUL with zsh/bash) and returns success as long as a full record has been read.
read returns non-zero when it finds EOF while the record delimiter has still not been encountered.
That allows you do do things like
while IFS= read -r line; do
done < text-file
Or with zsh/bash
while IFS= read -rd '' nul_delimited_record; do
done < null-delimited-list
And that loop to exit after the last record has been read.
You can still check if there was more data after the last full record with
[ -n "$nul_delimited_record" ].
In your case,
read's input doesn't contain any record as it doesn't contain any NUL character. In
bash, it's not possible to embed a NUL inside a here document. So
read fails because it hasn't managed to read a full record. It stills stores what it has read until EOF (after IFS processing) in the
In any case, using
read without setting
$IFS rarely makes sense.
For more details, see Understanding "IFS= read -r line".