I've been trying to figure out why I get a literal end-of-transmission character (EOT, ASCII code 4) in my variable if I read Ctrl+D with read -N 1 in bash and ksh93.
I'm aware of the distinction between the end-of-transmission character and the end-of-file condition, and I know what Ctrl+D does when using read without -N (it sends EOT, and if the input was empty, the underlying read() returns zero, signalling EOF).
But I'm not sure why trying to read a specific number of characters changes this behaviour so radically. I would have expected an EOF condition and that the following loop would exit:
while read -N 1 ch; do
printf '%s' "$ch" | od
done
Output when pressing Ctrl+D:
0000000 000004 0000001
The bash manual says about read -N (ksh93 has a similar wording):
-N nchars; read returns after reading exactlyncharscharacters rather than waiting for a complete line of input, unless EOF is encountered or read times out.
... but it says nothing about switching the TTY to raw/unbuffered mode (which is what I assume is happening).
The -n option to read seems to work in the same way with regards to Ctrl+D, and the number of characters to read doesn't seem to matter either.
How may I signal an end-of-input to read -N and exit the loop (other than testing the value that was read), and why is this different from a "bare" read?
read -e -N 1 chworks fine.-eoptions involves bash readline for interactive shells... Maybe this means thatread -Nworks in a non interactive way while simplereadworks interactivelly. – George Vasiliou Jan 24 '17 at 09:28-eit's more complicated, but it's still not a true EOF (you can see that withread -e -N 2 ch). I suppose that's a bug, i.e. the EOF should be emulated in both cases. – Satō Katsura Jan 24 '17 at 09:40