Vous (probablement) lisez d'abord deux octets +. $keycode
dans votre script serait ESC lorsque vous appuyez sur la touche fléchée.
Les touches fléchées peuvent être:
\x1b + some value
Il prend toujours la valeur true en raison des espaces manquants dans l'expression conditionnelle.
Edit: une mise à jour sur cette déclaration.
Votre if
fonctionne sur l'état de sortie de la [
commande. La [
commande est équivalente à test
. Le fait qu'il s'agisse d'une commande est un fait très important. En tant que commande, elle nécessite des espaces entre les arguments. La [
commande est en outre spéciale en ce qu'elle requiert ]
comme dernier argument.
[ EXPRESSION ]
La commande se termine avec le statut déterminé par EXPRESSION. 1 ou 0, vrai ou faux .
Ce n'est pas une façon exotique d'écrire des parenthèses. En d'autres termes, il ne fait pas partie de la if
syntaxe comme par exemple en C:
if (x == 39)
Par:
if [ "$keycode"=39 ]; then
vous émettez:
[ "$keycode"=39 ]
qui s'étend à
[ \x1b=39 ]
ici \x1b=39
est lu comme un argument. Lorsque test
ou [
reçoit un argument, il ne se termine avec false que si EXPRESSION est null - ce qui ne le sera jamais. Même s'il $keycode
était vide, il en résulterait =39
(qui n'est pas nul / vide).
Une autre façon de voir les choses est de dire:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
Lisez ces questions et réponses pour plus de détails - ainsi que la discussion sur [
vs [[
:
À cet égard, vous pouvez également rechercher des tiques arrière `` vs $( )
Séquence d'échappement multi-octets avec touches fléchées:
Comme mentionné en haut: vous lisez (probablement) le premier sur deux octets +. $keycode
dans votre script serait ESC lorsque vous appuyez sur la touche fléchée.
Les flèches et autres touches spéciales entraînent l' envoi de séquences d'échappement au système. L' octet ESC signale que "voici quelques octets qui doivent être interprétés différemment" . En ce qui concerne les touches fléchées qui seraient ASCII [
suivie par ASCII A
, B
, C
ou D
.
En d'autres termes, vous devez analyser trois octets lorsque vous utilisez les touches fléchées.
Vous pouvez essayer quelque chose dans ce sens pour vérifier:
{ stty_state=$(stty -g)
stty raw isig -echo
keycode=$(dd bs=8 conv=sync count=1)
stty "$stty_state"
} </dev/tty 2>/dev/null
printf %s "$keycode" | xxd
Rendement:
HEX ASCII
1b 5b 41 .[A # Up arrow
1b 5b 42 .[B # Down arrow
1b 5b 43 .[C # Right arrow
1b 5b 44 .[D # Left arrow
| | |
| | +------ ASCII A, B, C and D
| +--------- ASCII [
+------------ ASCII ESC
Je ne sais pas à quel point c'est portable, mais j'ai déjà joué avec du code comme celui-ci pour attraper les touches fléchées. Appuyez q
pour quitter:
while read -rsn1 ui; do
case "$ui" in
$'\x1b') # Handle ESC sequence.
# Flush read. We account for sequences for Fx keys as
# well. 6 should suffice far more then enough.
read -rsn1 -t 0.1 tmp
if [[ "$tmp" == "[" ]]; then
read -rsn1 -t 0.1 tmp
case "$tmp" in
"A") printf "Up\n";;
"B") printf "Down\n";;
"C") printf "Right\n";;
"D") printf "Left\n";;
esac
fi
# Flush "stdin" with 0.1 sec timeout.
read -rsn5 -t 0.1
;;
# Other one byte (char) cases. Here only quit.
q) break;;
esac
done
(En tant que note mineure, vous avez également (l'intention de) tester la décimale 39 - qui ressemble à un mélange entre décimal et hexadécimal. Le premier octet d'une séquence d'échappement est la valeur ASCII ESC , qui est décimal 27 et hexadécimal 0x1b
, tandis que la décimale 39 est hexadécimal 0x27
. )