Sie lesen (wahrscheinlich) zuerst aus zwei + Bytes. $keycode
In Ihrem Skript wäre ESC, wenn die Pfeiltaste gedrückt wird.
Pfeiltasten können sein:
\x1b + some value
Es wird immer als wahr ausgewertet, da Leerzeichen im bedingten Ausdruck fehlen.
Bearbeiten: eine Aktualisierung dieser Anweisung.
Sie if
bearbeiten den Exit-Status des [
Befehls. Der [
Befehl entspricht test
. Die Tatsache, dass es sich um einen Befehl handelt, ist eine sehr wichtige Tatsache. Als Befehl sind Leerzeichen zwischen Argumenten erforderlich. Der [
Befehl ist insofern etwas Besonderes, als er ]
als letztes Argument benötigt wird.
[ EXPRESSION ]
Der Befehl wird mit dem durch EXPRESSION festgelegten Status beendet. 1 oder 0, wahr oder falsch .
Es ist keine exotische Art, Klammern zu schreiben. Mit anderen Worten, es ist nicht Teil der if
Syntax wie zum Beispiel in C:
if (x == 39)
Durch:
if [ "$keycode"=39 ]; then
Sie geben aus:
[ "$keycode"=39 ]
das erweitert sich zu
[ \x1b=39 ]
Hier \x1b=39
wird als ein Argument gelesen . Wenn test
oder [
wenn ein Argument angegeben wird, wird es nur dann mit false beendet , wenn EXPRESSION null ist - was niemals der Fall sein wird. Selbst wenn $keycode
es leer wäre, würde es dazu führen =39
(was nicht null / leer ist).
Eine andere Sichtweise ist, dass Sie sagen:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
Lesen Sie diese Fragen und Antworten für weitere Details - sowie eine Diskussion über [
vs [[
:
In dieser Hinsicht könnten Sie auch Zecken `` vs. $( )
Multibyte-Escape-Sequenz mit Pfeiltasten:
Wie oben erwähnt: Sie lesen (wahrscheinlich) zuerst aus zwei + Bytes. $keycode
In Ihrem Skript wäre ESC, wenn die Pfeiltaste gedrückt wird.
Pfeil und andere Sonderschlüssel führen dazu, dass Escape-Sequenzen an das System gesendet werden. Das ESC- Byte signalisiert, dass "hier einige Bytes kommen, die anders interpretiert werden sollten" . Wie für den Pfeiltasten , die die ASCII sein würde , [
gefolgt von ASCII A
, B
, C
oder D
.
Mit anderen Worten, Sie müssen drei Bytes analysieren, wenn Sie mit Pfeiltasten arbeiten.
Sie könnten etwas in diese Richtung versuchen, um zu überprüfen:
{ 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
Ausbeute:
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
Ich bin mir nicht sicher, wie portabel dies ist, habe aber früher mit Code wie diesem herumgespielt, um Pfeiltasten zu fangen. Drücken Sie q
zum Beenden:
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
(Als kleine Anmerkung (beabsichtigen Sie auch), gegen Dezimal 39 zu testen - was wie eine Verwechslung zwischen Dezimal und Hexadezimal aussieht. Das erste Byte in einer Escape-Sequenz ist der ASCII-Wert ESC , der Dezimal 27 und Hexadezimal ist 0x1b
, während Dezimal 39 Hexadezimal ist 0x27
. )