Reputation: 3
I'm attempting to make a script that handles arrow keys on a very limited system with busybox ash and very little else. No stty for example. I have something that mostly works but occasionally some ANSI escape sequences show up on the screen. This seems to happen most often when auto-key-repeat kicks in but also when more complex processing must be done before reading the next key. This is mostly good on on my laptop which is faster than my target system, but if I hold down the arrow keys occasionally one like ^[[B shows up on screen. How does it get past the silent reads?
I didn't explicitly handle HOME and END so ^[OH and ^[OF get through more often. This makes me think maybe they're leaking out during the timeout period, but I really don't know.
Anyhow, is there some trick with a pipe or subshell that might contain the escapees?
E=$(printf "\033")
NL='
'
# Works in bash, ash without stty but takes a sec for ESC key (not ESC sequence)
# But even with nothing but q key checks in the loop it still occasionally
# spams the screen with ^[[B etc if I hold arrow keys down for auto-repeat.
while true; do
IFSBAK=$IFS ; IFS=
read -rsn1 _KEY
case "${_KEY}" in
"${E}") _K=""; read -sn2 -t1 _K; _KEY="${E}${_K}";
case "${_K}" in
"[A"|"[B"|"[C"|"[D"|"") ;;
"OP"|"OQ"|"OR"|"OS") ;;
*) _K=""; read -n1 -t1 _K; _KEY="${_KEY}${_K}" ;;
esac
;; "") _KEY="NL"
;;
esac
IFS=$IFSBAK ; IFSBAK=
case "$_KEY" in
"${E}" | q )
break;;
esac
done
Upvotes: 0
Views: 343
Reputation: 54583
The question is
How does it get past the silent reads?
That's because the script is switching the terminal in/out of the modes used for the silent (no-echo) reads, and your keys are echoed by the shell when it is not expecting input. You can improve this by using stty to disable echo while the script is running (and restore echoing on exit).
Upvotes: 0