Najprawdopodobniej przeczytałeś pierwszy z dwóch + bajtów. $keycode
w twoim skrypcie będzie ESC po naciśnięciu klawisza strzałki.
Klawisze strzałek mogą być:
\x1b + some value
Zawsze zwraca wartość true, ponieważ brakuje spacji w wyrażeniu warunkowym.
Edycja: aktualizacja tego oświadczenia.
Twój if
działa na statusie wyjścia [
polecenia. [
Komenda jest równoważna test
. Fakt, że jest to polecenie, jest bardzo ważnym faktem. Jako polecenie wymaga spacji między argumentami. [
Komenda jest dodatkowo specjalny w to, że wymagają ]
jako ostatni argument.
[ EXPRESSION ]
Polecenie kończy pracę ze statusem określonym przez WYRAŻENIE. 1 lub 0, prawda lub fałsz .
To nie jest egzotyczny sposób pisania nawiasów. Innymi słowy, nie jest to część if
składni, jak na przykład w C:
if (x == 39)
Przez:
if [ "$keycode"=39 ]; then
wydajesz:
[ "$keycode"=39 ]
który rozwija się do
[ \x1b=39 ]
tutaj \x1b=39
jest czytany jako jeden argument. Kiedy podano test
lub [
podano jeden argument, kończy się ono na fałsz tylko wtedy, gdy EXPRESSION ma wartość null - co nigdy nie będzie. Nawet jeśli $keycode
byłby pusty, spowodowałoby to =39
(co nie jest zerowe / puste).
Innym sposobem spojrzenia na to jest powiedzenie:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
Przeczytaj te pytania i odpowiedzi, aby uzyskać więcej informacji - a także dyskusję na temat [
vs [[
:
W tym względzie można również zbadać tyknięcia `` vs $( )
Wielobajtowa sekwencja ucieczki za pomocą klawiszy strzałek:
Jak wspomniano u góry: Najprawdopodobniej przeczytałeś pierwszy z dwóch + bajtów. $keycode
w twoim skrypcie będzie ESC po naciśnięciu klawisza strzałki.
Strzałki i inne specjalne klawisze powodują wysłanie sekwencji ucieczki do systemu. W ESC bajt sygnały, że „tutaj jest kilka bajtów, które powinny być interpretowane w różny sposób” . Co do klawiszy strzałek, które byłyby ASCII [
następnie ASCII A
, B
, C
lub D
.
Innymi słowy, musisz parsować trzy bajty podczas obsługi klawiszy strzałek.
Możesz spróbować czegoś w tym kierunku, aby sprawdzić:
{ 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
Wydajność:
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
Nie jestem pewien, jak przenośny, ale wcześniej bawiłem się takim kodem do łapania klawiszy strzałek. Naciśnij, q
aby wyjść:
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
(Jako drobna uwaga, również (zamierzasz) przetestować dziesiętnie 39 - co wygląda jak połączenie dziesiętnego i szesnastkowego. Pierwszy bajt w sekwencji specjalnej to wartość ASCII ESC , która jest dziesiętna 27 i szesnastkowa 0x1b
, podczas gdy dziesiętna 39 jest szesnastkowa 0x27
. )