2014-04-03 4 views
8

Не уверен, что я должен поместить это в stackoverflow или unix.stackexchange, но я нашел здесь similarquestions, так что вот оно.bash scripting - читать одно нажатие клавиши, включая ввод специальных клавиш и пробел

Я пытаюсь создать сценарий, который будет вызываться .bashrc, что позволяет мне выбрать один из двух вариантов, основанный на одном нажатии клавиши. Это было бы не сложно, но я хочу, чтобы два ключа, соответствующие двум параметрам, были свободными и вводились.

Вот что я получил до сих пор:

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

Следующий вывод, что я получу, если я нажимаю войти, пространство, забой и х:

:~$ 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 

Так как ввести и результат пространство пустой SELECT. Невозможно отличить их. Я попытался добавить -d 'D' в параметры чтения, но это не помогло. Может быть, кто-то может указать мне в правильном направлении.

Баш версия будет 4.2 кстати.

+0

связанный https://unix.stackexchange.com/questions/179191/bashscript-to-detect-right-arrow-key-being-pressed –

ответ

3

установка чтения разделителя в пустую строку Try затем проверить внутреннюю переменные $ РЕПЛИКИ:

read -d'' -s -n1 

По какой-то причине я не мог заставить его работать с указанием переменного.

+0

Это прекрасно работает, даже не меняя разделителя на -d. И ввод и пробел правильно определены. –

+1

У нас, вероятно, были разные вкусы 'read'. Если я уйду из -d '', я не получу ключ ввода. –

+0

Я только заметил, что мы используем -n и -N соответственно. Это и должно быть причиной этого, когда спецификация длины с -N символами новой строки не обрабатывается специально. –

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

Есть несколько вещей, о read, которые имеют отношение здесь:

  • Она читает одну строку
  • линия разделяется на поля, как со словом расщеплению

Поскольку вы читаете один символ, это означает, что ввод Ввод приведет к пустой переменной.

Кроме того, по умолчанию правила разделения слов, ввод Пространство также приведет к пустой переменной. Хорошей новостью является то, что вы можете справиться с этой частью, установив IFS.

read Изменить заявление:

IFS= read -s -n 1 SELECT 

и ожидать пустую строку вместо $'\x0a' при вводе Enter.

+0

Это работает также и с установкой IFS только для команды чтения в основном как очистите раствор. Я по-прежнему отмечен как putnamhill как правильный, потому что он не может создавать случайные побочные эффекты через измененный IFS. Приобретено! Btw, с -N вместо -n SELECT не пуст при отправке ввода, но фактически содержит ожидаемое значение. –