Bash replacement to getchar

There's a replacement in bash for getchar or get functions of C and C++?Those functions read the next char avaliable in the input stream.
I've tried something like:

OLD_STTY=`stty -g`
  stty cbreak -echo
  look=`dd if=/dev/tty bs=1 count=1 2>/dev/null`
  stty $OLD_STTY

But it is not working very well.

Generic for all shells

read -n1 kbd

If you not echo then use stty -echo before read and stty echo after.

Also this "old standard" works:

echo -n "Press key:"
stty -echo raw
c=$(dd bs=1 count=1 2>/dev/null )
stty echo -raw
echo " key:$c"

Ofcourse you can save current stty and return it, but usually echo is on and raw is off.

Ksh include KEYBD interrupt = you can trap KEYBD.

keybd()
{
    key="${.sh.edchar}"
}

trap 'keybd' KEYBD
while :
do
        read a
done
echo -n "Press key:"
stty -echo raw
c=$(dd bs=1 count=1 2>/dev/null )
stty echo -raw
echo " key:$c"

It interpreters ctrl-c and ctrl-d literally... Is there a way to make it to be aborted by a signal?

With this you can debug:

trap 'echo "int shell"' HUP INT QUIT
echo -n "Press key:"
stty -echo raw
c=$(dd bs=1 count=1 2>/dev/null )
stty echo -raw
echo "<$c>"
echo $c | od -c

echo "press ctrl-c"
sleep 20

result: dd read one char from stdin. Also ctrl-c and ctrl-d are only chars. So you can test those chars.

trap ':'  HUP INT QUIT
c=""
while [ "$c" = "" ]
do
  # do c read, look previous dd or
  echo -n "key:"
  read -n 1 c 
  # test it
  case "$c" in
    \001) ;; # ctrl-A
    \003) ;; # ctrl-C
  esac
  # remove char ascii 01-04
  c=$(echo "$c" | tr -d "[\001-\004]" )
done