Why does this always detect as true, even if the keycode is not right-arrow-key?
stty_state=`stty -g`
stty raw; stty -echo
keycode=`dd bs=1 count=1 2>/dev/null`
stty "$stty_state"
echo $keycode
if [ "$keycode"=39 ]; then
echo "Right Arrow Key Pressed!"
fi
Best Answer
You (likely) read first out of two+ bytes.
$keycode
in your script would be ESC when arrow key is pressed.Arrow keys can be:
It always evaluates to true because of missing spaces in conditional expression.
Edit: an update on that statement.
Your
if
operates on the exit status of the[
command. The[
command is equivalent totest
. The fact that it is a command is a very important fact. As a command it require spaces between arguments. The[
command is further special in that it require]
as last argument.The command exits with the status determined by EXPRESSION. 1 or 0, true or false.
It is not an exotic way to write parenthesis. In other words it is not part of the
if
syntax as for example in C:By:
you issue:
which expands to
here
\x1b=39
is read as one argument. Whentest
or[
is given one argument it exits with false only if EXPRESSION is null – which is is never going to be. Even if$keycode
was empty, it would result in=39
(which is not null / empty).Another way to look at it is that you say:
Read these questions and answers for more details – as well as discussion on
[
vs[[
:In that regard you could also research back ticks `` vs
$( )
Multibyte escape sequence with arrow keys:
As mentioned at the top: You (likely) read first out of two+ bytes.
$keycode
in your script would be ESC when arrow key is pressed.Arrow and other special keys result in escape sequences to be sent to the system. The ESC byte signals that "here comes some bytes that should be interpreted differently". As for arrow keys that would be the ASCII
[
followed by ASCIIA
,B
,C
orD
.In other words you have to parse three bytes when dealing with arrow keys.
You could try something in the direction of this to check:
Yield:
Not sure how portable this is, but have earlier played around with code like this for catching arrow keys. Press
q
to quit:(As a minor note you also (intend to) test against decimal 39 – which looks like a mixup between decimal and hexadecimal. First byte in an escape sequence is ASCII value ESC, which is decimal 27 and hexadecimal
0x1b
, while decimal 39 is hexadecimal0x27
.)