GAH! Eu acabei de descobrir ... Parece que o redirecionamento é redefinido quando você invoca outra função. Mas não é isso. O problema real é muito mais idiota:
IFS='' read -r n1 CHAR
Há um traço faltando!
IFS='' read -r -n1 CHAR
[facepalm]