Не удается заставить “read” работать правильно в bash-скрипте.

Вопрос или проблема

У меня есть следующий скрипт:

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"

Поведение:

  1. Нажатие y или Y отображает символ на экране.
  2. Нажатие Enter вызывает перенос курсора, при этом команда echo не выполняется.
  3. Для выполнения 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

Улучшения

  1. Пользовательский ввод – Изменение echo на echo -n предотвращает перенос строки, что улучшает восприятие запроса пользователем.

  2. Обработка ввода – Вы можете использовать конструкцию case для отлова различных вариантов ввода, это делает код более читаемым и понятным.

  3. Валидация ввода – Два условия Yy и Nn позволяют программе реагировать на оба варианта ввода, и добавление блока *) предупреждает о неверном вводе.

Заключение

Используя коды выше, вы сможете избежать необходимости нажатия клавиши Enter дважды, а также улучшить взаимодействие пользователя со скриптом. Если у вас возникнут дополнительные вопросы или проблемы с другими аспектами программирования на Bash, не стесняйтесь обратиться за помощью.

Оцените материал
Добавить комментарий

Капча загружается...