Best explained with an example:
$ printf 'a\x00\x00bc' | { while IFS= read -d '' -n 1 var; do echo "read: $var, length: ${#var}"; done; } read: a, length: 1 read: , length: 0 read: , length: 0 read: b, length: 1 read: c, length: 1 This is as expected, and allows detecting a NUL in the input when the length of $var is 0 (let's not talk about EOF and non-newline terminated inputs here, this is not the issue). However, if trying to read 2 (or more) characters at a time, it's no longer true: $ printf 'a\x00\x00bc' | { while IFS= read -d '' -n 2 var; do echo "read: $var, length: ${#var}"; done; } read: a, length: 1 read: , length: 0 read: bc, length: 2 I would expect there to be another read of length 0 between the "a" and the "bc". Apologies if this has been already discussed and/or if I'm missing something. $ bash --version GNU bash, version 4.4.23(1)-release (x86_64-unknown-linux-gnu) -- D.