Bash Shell Scripting — обнаружение клавиши Enter

Мне нужно сравнить мой ввод с клавишей Enter/Return...

read -n1 key
if [ $key == "\n" ]
   echo "@@@"
fi

Но это не работает. Что не так с этим кодом


person veda    schedule 10.04.2010    source источник
comment
Тогда вам не хватает линии между if и echo. Не единственная проблема, но одна   -  person Phil    schedule 10.04.2010


Ответы (5)


Несколько проблем с опубликованным кодом. В комментариях подробно описано, что нужно исправить:

#!/bin/bash 
# ^^ Bash, not sh, must be used for read options

read -s -n 1 key  # -s: do not echo input character. -n 1: read only 1 character (separate with space)

# double brackets to test, single equals sign, empty string for just 'enter' in this case...
# if [[ ... ]] is followed by semicolon and 'then' keyword
if [[ $key = "" ]]; then 
    echo 'You pressed enter!'
else
    echo "You pressed '$key'"
fi
person Mark Rushakoff    schedule 10.04.2010
comment
Это не работает. Если вы нажмете ESC, вы перейдете к вводу! - person Bruno Medina; 11.05.2018
comment
@Jiu, кажется, вы используете sh file для его выполнения, а не bash file или просто ./file, если у него есть chmod +x file. Отмечу, что гуглить гораздо быстрее, чем писать такой комментарий. - person m3nda; 19.03.2019
comment
@Бруно Медина. Что ж, если вы используете необработанную опцию -r, вы будете читать "" для клавиши возврата и "\e" для клавиши перехода, делая разницу между ними. Использование текущего read -s -n удалит символы с обратной косой чертой, превратив их в "". Итак, просто read -r -s -n 1 key решит. - person m3nda; 19.03.2019

Также рекомендуется определить пустой $IFS (внутренний разделитель полей) перед сравнением, потому что в противном случае вы можете получить " " и "\n" равными.

Итак, код должен выглядеть так:

# for distinguishing " ", "\t" from "\n"
IFS=

read -n 1 key
if [ "$key" = "" ]; then
   echo "This was really Enter, not space, tab or something else"
fi
person tsds    schedule 17.02.2016
comment
# это не работает для меня, если я использую циклическую печать coutdown IFS= echo -e Нажмите [ENTER] для настройки клавиатуры. for (( i=10; i›0; i--)); do printf \rНачиная через $i секунд... read -n 1 -t 1 key if [ $key = $'\e' ]; then echo Это ESC break elif [ $key == ] ;then echo -e \n пробел нажат break fi done - person Asaf Magen; 25.04.2016
comment
возможно, дело в том, что для встроенного синтаксиса вы должны использовать IFS=; эхо... (с точкой с запятой) - person tsds; 25.04.2016
comment
Довольно хорошее исправление, просто используя IFS= - person m3nda; 19.03.2019

Я добавляю ниже код только для справки, если кто-то захочет использовать такое решение, содержащее цикл обратного отсчета.

IFS=''
echo -e "Press [ENTER] to start Configuration..."
for (( i=10; i>0; i--)); do

printf "\rStarting in $i seconds..."
read -s -N 1 -t 1 key

if [ "$key" = $'\e' ]; then
        echo -e "\n [ESC] Pressed"
        break
elif [ "$key" == $'\x0a' ] ;then
        echo -e "\n [Enter] Pressed"
        break
fi

done
person Asaf Magen    schedule 26.04.2016
comment
Это идеально вписывается в цикл while, чтобы я мог выполнять что-то, пока жду. :D - person Swivel; 01.06.2019

read читает строку из стандартного ввода, вплоть до новой строки в конце строки, но не включая ее. -n указывает максимальное количество символов, заставляя read возвращаться раньше, если вы достигаете этого количества символов. Однако он все равно закончится раньше, когда будет нажата клавиша Return. В этом случае возвращается пустая строка — все, кроме клавиши Return.

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

read -n1 KEY
if [[ "$KEY" == "" ]]
then
  echo "@@@";
fi
person meagar    schedule 10.04.2010

Ни одно из этих условий не сработало для меня, поэтому я придумал это:

${key} = $'\0A'

Протестировано на CentOS с Bash 4.2.46.

person Martin Zeitler    schedule 06.10.2020
comment
Оно работает! После попытки с [[ $key == $'\x0A' ]], но не работает, изменил его на $'\0a', теперь работает. Протестировано на Arch с Bash 5.1 - person Dzulfikar Adib; 14.06.2021
comment
00 0A — это ASCII для LF. Юникод \x000A тоже может работать. - person Martin Zeitler; 14.06.2021
comment
да, тоже работает - person Dzulfikar Adib; 15.06.2021