Вопрос или проблема
У меня есть следующий скрипт:
echo "Пользователь уже существует, удалить пользователя? [Y/n] "
read -r -n 1 yn
echo "$yn была нажата"
Когда я запускаю скрипт:
- Нажатие y или Y (без [Enter]) выводит символ на экран.
- Нажатие [Enter] перемещает курсор на новую строку, но следующая команда echo не выполняется
- Нажатие [Enter] второй раз вызывает выполнение команды echo
Я ожидаю, что не придется нажимать [Enter] дважды.
Я пробовал разные варианты, включая добавление подсказки в команду read, но это было еще хуже, так как подсказка даже не появлялась в этот момент.
Что я делаю не так?
Ответ или решение
Ваша проблема может быть связана с тем, как интерпретатор Bash обрабатывает ввод с помощью команды read
. Несмотря на то, что команда read
позволяет захватывать однобайтовый ввод с клавиатуры, в вашем случае, вводу требуются дополнительные нажатия клавиш для правильной обработки. Рассмотрим, как это можно исправить.
Проблема
Ваш исходный скрипт выглядит следующим образом:
echo "User already exists, delete user? [Y/n] "
read -r -n 1 yn
echo "$yn was pressed"
Поведение:
- Нажатие
y
илиY
отображает символ на экране. - Нажатие
Enter
вызывает перенос курсора, при этом командаecho
не выполняется. - Для выполнения
echo
требуется повторное нажатиеEnter
.
Причины
Команда read
с флагом -n 1
может вести себя неожиданно, если не обрабатывать ввод корректно. Ваша настройка фактически ожидает ввода одного символа, и только после нажатия Enter
интерпретирует команду. Это может приводить к тому, что выступление символа на экран выглядит как нечто ненадобное, и может вводить в заблуждение.
Решение
Для того чтобы упростить ввод пользователя и избежать необходимости нажимать Enter
сразу после нажатия ключа, вы можете использовать флаг -s
для скрытия вводимого символа, если это необходимо. Однако основное исправление заключается в том, чтобы не требовать Enter
после ввода. Вам стоит использовать подход, при котором команда может обрабатывать ввод и сразу же продолжать выполнение.
Попробуйте следующий обновленный код:
#!/bin/bash
echo -n "User already exists, delete user? [Y/n] "
read -r -n 1 yn
echo
case "$yn" in
[Yy]*) echo "You chose to delete the user." ;;
[Nn]*) echo "No action taken." ;;
*) echo "Invalid input." ;;
esac
Улучшения
-
Пользовательский ввод – Изменение
echo
наecho -n
предотвращает перенос строки, что улучшает восприятие запроса пользователем. -
Обработка ввода – Вы можете использовать конструкцию
case
для отлова различных вариантов ввода, это делает код более читаемым и понятным. -
Валидация ввода – Два условия
Yy
иNn
позволяют программе реагировать на оба варианта ввода, и добавление блока*)
предупреждает о неверном вводе.
Заключение
Используя коды выше, вы сможете избежать необходимости нажатия клавиши Enter
дважды, а также улучшить взаимодействие пользователя со скриптом. Если у вас возникнут дополнительные вопросы или проблемы с другими аспектами программирования на Bash, не стесняйтесь обратиться за помощью.