bashscript per rilevare il tasto freccia destra premuto


Risposte:


16

(Probabilmente) leggi prima su due + byte. $keycodenel tuo script sarebbe ESC quando si preme il tasto freccia.

I tasti freccia possono essere:

\x1b + some value

Viene sempre valutato come vero a causa di spazi mancanti nell'espressione condizionale.

Modifica: un aggiornamento su tale affermazione.

Il tuo ifopera sullo stato di uscita del [comando. Il [comando è equivalente a test. Il fatto che si tratti di un comando è un fatto molto importante. Come comando richiede spazi tra gli argomenti. Il [comando è ulteriormente speciale in quanto richiede ]come ultimo argomento.

[ EXPRESSION ]

Il comando termina con lo stato determinato da ESPRESSIONE. 1 o 0, vero o falso .

E ' non è un modo esotico per la parentesi di scrittura. In altre parole è non parte della ifsintassi come per esempio in C:

if (x == 39)

Di:

if [ "$keycode"=39 ]; then

si emette:

[ "$keycode"=39 ]

che si espande a

[ \x1b=39 ]

qui \x1b=39viene letto come un argomento. Quando testo [viene dato un argomento, esce con false solo se EXPRESSION è null - che non lo sarà mai. Anche se $keycodefosse vuoto, si tradurrebbe in =39(che non è nullo / vuoto).

Un altro modo di vederlo è che dici:

if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.

Leggi queste domande e risposte per maggiori dettagli, oltre a discussioni su [vs [[:

A tale proposito, è possibile ricercare anche le zecche `` vs $( )


Sequenza di escape multibyte con i tasti freccia:

Come menzionato all'inizio: (probabilmente) leggi prima su due + byte. $keycodenel tuo script sarebbe ESC quando si preme il tasto freccia.

La freccia e altri tasti speciali comportano l' invio di sequenze di escape al sistema. Il byte ESC segnala che "ecco che arrivano alcuni byte che dovrebbero essere interpretati in modo diverso" . Per quanto riguarda i tasti freccia che sarebbe l'ASCII [seguito da ASCII A, B, Co D.

In altre parole, devi analizzare tre byte quando gestisci i tasti freccia.

Puoi provare qualcosa in questa direzione per verificare:

{   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

Dare la precedenza:

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

Non sono sicuro di quanto sia portatile, ma in precedenza hanno giocato con questo codice per catturare i tasti freccia. Premere qper uscire:

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

(Come nota minore anche tu (intendi) testare con il decimale 39 - che sembra un miscuglio tra decimale ed esadecimale. Il primo byte in una sequenza di escape è il valore ASCII ESC , che è decimale 27 ed esadecimale 0x1b, mentre il decimale 39 è esadecimale 0x27. )


2
Il primo problema nella domanda è che non ci sono spazi che circondano il =segno nel test, quindi viene analizzato semplicemente come una stringa non vuota e quindi è vero. Il fatto che i tasti freccia siano più byte è un problema separato.
Wurtel,

2
Hmm, quella frase non ha molto contesto così com'è, l'ho letto mentre pensavo che fosse parte della spiegazione delle sequenze multi-byte che conoscevo già.
Wurtel,

2
@wurtel: Sì. A dire il vero, credo. Scopri che una volta spiegato [è un comando incorporato, le persone comprendono perché gli spazi sono importanti molto più rapidamente. (Non è semplicemente un modo strano di bash usare parentesi anziché parentesi.) Ora devono finire. Aggiorna una volta tornato.
user367890,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.