2014-04-03 22 views
8

Nicht sicher, ob ich dies auf stackoverflow oder unix.stackexchange setzen sollte, aber ich fand einige similarquestions hier, also hier geht es.bash scripting - lesen single keystroke einschließlich spezielle Schlüssel eingeben und Leerzeichen

Ich versuche, ein Skript zu erstellen, das von .bashrc aufgerufen wird, das es mir ermöglicht, eine von zwei Optionen auszuwählen, die auf einem einzelnen Tastendruck basieren. Das wäre normalerweise nicht schwer, aber ich möchte, dass die zwei Schlüssel, die den beiden Optionen entsprechen, Leerzeichen sind und eingeben.

Hier ist, was ich bisher habe:

#!/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 

Die folgende Ausgabe ist, was ich, wenn ich die Eingabetaste drücken, Raum, Backspace und 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 

beide So geben und Raum Ergebnis in ein leeres SELECT. Keine Möglichkeit, die beiden zu unterscheiden. Ich habe versucht, -d 'D' zu den Leseoptionen hinzuzufügen, aber das hat nicht geholfen. Vielleicht kann mich jemand in die richtige Richtung weisen.

Die Bash-Version wäre 4.2 btw.

+0

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

Antwort

3

Versuchen Sie, überprüfen Sie die Lesetrennzeichen auf eine leere Zeichenfolge dann die eingebaute $ REPLY Variable:

read -d'' -s -n1 

Aus irgendeinem Grund habe ich es nicht eine Variable spezifiziert arbeiten konnte.

+0

Dies funktioniert gut, auch ohne das Trennzeichen mit -d zu ändern. Sowohl Eingabe als auch Leerzeichen werden korrekt erkannt. –

+1

Wir haben wahrscheinlich verschiedene Varianten von 'lesen'. Wenn ich -d 'weglasse, bekomme ich die Enter-Taste nicht. –

+0

Ich habe gerade erst gemerkt, dass wir -n bzw. -N verwenden. Das muss der Grund dafür sein, wenn die Länge mit -N newlines nicht speziell behandelt wird. –

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

Es gibt ein paar Dinge, über read, die relevant sind hier:

  • Es liest eine Zeile
  • Die Zeile in Felder wie mit Wort Spaltung gespalten wird

Da Sie ein Zeichen lesen, bedeutet dies, dass die Eingabe Enter zu einer leeren Variablen führen würde.

Darüber hinaus würde nach Vorgabe von Regeln für die Wortaufteilung Space auch in eine leere Variable führen. Die gute Nachricht ist, dass Sie mit diesem Teil umgehen können, indem Sie IFS setzen.

ändern read Anweisung:

IFS= read -s -n 1 SELECT 

und erwarten, statt $'\x0a' eine leere Zeichenfolge, wenn eingeben eingeben.

+0

Dies funktioniert auch und mit der Einstellung IFS nur für den Lesebefehl ist grundsätzlich so eine Lösung reinigen. Ich habe putnamhill immer noch als den richtigen markiert, weil es keine versehentlichen Nebenwirkungen durch ein verändertes IFS erzeugen kann. Upvoted obwohl! Btw, mit -N anstelle von -n SELECT ist nicht leer, wenn Enter gesendet wird, enthält aber tatsächlich den erwarteten Wert. –