2014-04-03 10 views
8

Non sono sicuro se dovrei metterlo su stackoverflow o unix.stackexchange ma ho trovato un po 'di similarquestions qui, quindi eccolo qui.bash scripting - leggi una singola sequenza di tasti che include chiavi speciali e spazio

Sto cercando di creare uno script per essere chiamato da .bashrc che mi consente di selezionare una delle due opzioni in base a un singolo tasto. Questo non sarebbe difficile normalmente, ma voglio che i due tasti corrispondenti alle due opzioni siano spazio ed entri.

Ecco quello che ho ottenuto finora:

#!/bin/bash 

SELECT="" 
while [[ "$SELECT" != $'\x0a' && "$SELECT" != $'\x20' ]]; do 
    echo "Select session type:" 
    echo "Press <Enter> to do foo" 
    echo "Press <Space> to do bar" 
    read -s -N 1 SELECT 
    echo "Debug/$SELECT/${#SELECT}" 
    [[ "$SELECT" == $'\x0a' ]] && echo "enter" # do foo 
    [[ "$SELECT" == $'\x20' ]] && echo "space" # do bar 
done 

Il seguente output è quello che ricevo se premere Invio, lo spazio, backspace e x:

:~$ bin/sessionSelect.sh 
Select session type: 
Press <Enter> to start/resume a screen session 
Press <Space> for a regular ssh session 
Debug//0 
Select session type: 
Press <Enter> to start/resume a screen session 
Press <Space> for a regular ssh session 
Debug//0 
Select session type: 
Press <Enter> to start/resume a screen session 
Press <Space> for a regular ssh session 
Debug//1 
Select session type: 
Press <Enter> to start/resume a screen session 
Press <Space> for a regular ssh session 
Debug/x/1 

Così sia entrare e risultato spazio una SELEZIONE vuota. Non c'è modo di distinguere i due. Ho provato ad aggiungere -d 'D' alle opzioni di lettura, ma questo non ha aiutato. Forse qualcuno può indicarmi la giusta direzione.

La versione di bash sarebbe 4.2 btw.

+0

relative https://unix.stackexchange.com/questions/179191/bashscript-to-detect-right-arrow-key-being-pressed –

risposta

3

impostare il delimitatore di lettura su una stringa vuota Prova quindi controllare che la funzione interna variabile $ REPLY:

read -d'' -s -n1 

Per qualche motivo non ho potuto farlo funzionare specificando una variabile.

+0

Funziona bene, anche senza cambiare il delimitatore con -d. Entrambe le entrate e lo spazio sono correttamente rilevati. –

+1

Probabilmente abbiamo avuto diverse versioni di 'read'. Se esco da -d '', non ottengo la chiave di invio. –

+0

Ho appena notato che usiamo -n e -N rispettivamente. Questo deve essere il motivo per cui, quando si specifica la lunghezza con -N i ritorni a capo non vengono trattati in modo speciale. –

3
#!/bin/bash 
SELECT="" 
# prevent parsing of the input line 
IFS='' 
while [[ "$SELECT" != $'\x0a' && "$SELECT" != $'\x20' ]]; do 
    echo "Select session type:" 
    echo "Press <Enter> to do foo" 
    echo "Press <Space> to do bar" 
    read -s -N 1 SELECT 
    echo "Debug/$SELECT/${#SELECT}" 
    [[ "$SELECT" == $'\x0a' ]] && echo "enter" # do foo 
    [[ "$SELECT" == $'\x20' ]] && echo "space" # do bar 
done 
2

ci sono un paio di cose su read che sono rilevanti qui:

  • Si legge una singola linea
  • La linea è divisa in campi come con la suddivisione delle parole

Poiché stai leggendo un carattere, ciò implica che l'immissione di Inserisci risulterebbe in una variabile vuota.

Inoltre, per impostazione predefinita le regole per la divisione delle parole, immettendo , lo spazio risulterebbe anche in una variabile vuota. La buona notizia è che puoi gestire questa parte impostando IFS.

Modificare l'istruzione read a:

IFS= read -s -n 1 SELECT 

e si aspettano una stringa nulla, invece di $'\x0a' quando si entra Inserisci.

+0

Questo funziona come bene e con la regolazione IFS solo per il comando di lettura è fondamentalmente come pulire una soluzione. Ho ancora segnato putnamhill come quello corretto perché non può produrre effetti collaterali accidentali attraverso un IFS modificato. Votato però! Btw, con -N invece di -n SELECT non è vuoto quando si invia l'immissione ma in realtà contiene il valore previsto. –

Problemi correlati