I was going to leave this as a comment to your own 'answer' but decided I needed more room.
cbreak is equivalent to raw mode except in that cbreak doesn't intercept control sequences like ctrl-c, ctrl-z etc. They both collect characters one at a time. The difference in behavior between the two modes isn't the source of your problem. If Chas's solution does something like what you intended, then the problem more likely has to do with whatever you redacted in your #process input
line. I've commented already that your original script works fine if I fill it with something rudimentary so I can see that it's working. For example, a minor touch-up:
use strict;
use warnings;
use Term::ReadKey;
my ($char, $input, $pause_time);
ReadMode("cbreak");
# Collect all characters typed into $input
# and quit when '#' is typed.
$input = '';
while ($char = ReadKey($pause_time)) {
last if $char eq '#';
$input .= $char;
}
print "$input\n";
There's no need for me to hit 'enter' at the end of this, and doing so won't do anything (apart from throwing a carriage return into $input
and weirding up the string).