While trying the cat "$@"
trick to read from either standard input or given files, it turned out that pipe and process substitution handle a missing trailing newline differently:
printf %s foo > test.txt
unset REPLY
while read
do
:
done < <(cat test.txt)
echo "$REPLY" # Prints foo
unset REPLY
cat test.txt | while read
do
:
done
echo "$REPLY" # Prints nothing!
Is this by design? Is this "feature" documented anywhere?
D'oh! @fered had the right idea - It's just another example of how variable values are lost because piped commands are run in a subshell.