Да или нет bash

Устал от долгих раздумий? Пусть bash решит всё за тебя! Узнай, как да или нет bash работает в консоли — быстро, дерзко и без компромиссов.

В интерактивных скриптах Bash часто возникает необходимость задать пользователю простой вопрос «Да» или «Нет» и выполнить разные действия в зависимости от ответа. В этой статье мы разберём:

  • Как правильно выводить запрос пользователю.
  • Какие существуют способы чтения ответа (read, select, case).
  • Как использовать условные операторы if, elif и else с несколькими условиями.
  • Как обрабатывать ввод без учёта регистра и с тайм‑аутом.
  • Полезные приёмы для надёжного скрипта.

Базовый шаблон с read и if

Самый простой способ – вывести вопрос, считать ввод и сравнить его с ожидаемыми вариантами.

#!/bin/bash

echo -n "Продолжить работу? (да/нет): "

read reply

reply=${reply,,} # Bash 4+, меняет регистр на нижний

if  "$reply" == "да" ; then
 echo "Продолжаем..."
 # Здесь размещаем код, который должен выполниться при «да»
elif  "$reply" == "нет" ; then
 echo "Останавливаемся."
 exit 0
else
 echo "Ответ не распознан. Пожалуйста, введите «да» или «нет»."
 # Можно повторить запрос рекурсивно или выйти с ошибкой
 exit 1
fi

В этом примере использованы:

  • Оператор [[ … ]] – более надёжный, чем [ … ], позволяет использовать логическое ИЛИ (||) и И (&&).
  • Синтаксис ${var,,} – преобразует строку к нижнему регистру, избавляя от необходимости писать несколько вариантов с разным регистром.
  • Блок else – отлавливает любые неожиданные ответы.

Оператор elif для нескольких вариантов

Если требуется поддержать несколько вариантов «да» и «нет», удобно воспользоваться elif. Пример:

#!/bin/bash

read -p "Удалить все временные файлы? (y/n): " ans
ans=${ans,,}

if  "$ans" == "y" ; then
 echo "Файлы удаляются..."
 rm -rf /tmp/*
elif  "$ans" == "n" ; then
 echo "Удаление отменено."
else
 echo "Некорректный ввод."
 exit 1
fi

Использование case вместо if

Для более читаемого кода при большом количестве вариантов можно применить case. Это особенно удобно, когда список возможных ответов длинный.

#!/bin/bash

read -p "Перезапустить сервис? (да/д/yes/y/нет/н/no/n): " answer
answer=${answer,,}

case "$answer" in
 da|д|yes|y)
 echo "Сервис перезапускается..."
 systemctl restart myservice
 ;;
 net|н|no|n)
 echo "Перезапуск отменён."
 ;;
 *)
 echo "Неизвестный ответ: $answer"
 exit 1
 ;;
esac

Логические операторы в условных выражениях

Иногда необходимо проверить несколько условий одновременно, например, существует ли файл config.cfg или default.cfg. Для этого используют логический оператор ИЛИ (||) внутри [[ … ]]:

if  -f config.cfg ; then
 echo "Конфигурационный файл найден."
else
 echo "Нет ни одного из ожидаемых файлов."
fi

Аналогично, логическое И (&&) проверяет, что оба условия истинны:

if [[ -d /var/log && -w /var/log ]]; then
 echo "Каталог /var/log существует и доступен для записи."
fi

Тайм‑аут для ввода пользователя

Иногда скрипт не должен ждать ввода бесконечно. Можно задать тайм‑аут с помощью ключа -t команды read:

#!/bin/bash

if read -t 10 -p "Продолжить? (да/нет): " reply; then
 reply=${reply,,}
 if [[ "$reply" == "да" ]]; then
 echo "Продолжаем без задержек."
 else
 echo "Отмена."
 exit 0
 fi
else
 echo -e "
Время ожидания истекло. Выходим."
 exit 1
fi

Здесь -t 10 означает «ждать не более 10 секунд». Если пользователь не ввёл ничего, read завершается с ненулевым кодом возврата, и мы обрабатываем это в ветке else.

Полезные рекомендации

  1. Всегда проверяйте код возврата read. Если пользователь нажал Ctrl+C или ввод прерван, скрипт может продолжить работу с неверными данными.
  2. Нормализуйте ввод – перевод в нижний регистр (${var,,}) и удаление пробелов (${var// /}) делают сравнение более надёжным.
  3. Не забывайте про локаль. Если скрипт будет использовать русские ответы, убедитесь, что в системе установлена LANG=ru_RU.UTF-8, иначе сравнение может работать некорректно.
  4. Для сложных диалогов используйте select – он автоматически формирует меню с нумерацией.

Пример с select

#!/bin/bash

PS3="Выберите действие (1‑Да, 2‑Нет): "
options=("Да" "Нет")
select opt in "${options[@]}"; do
 case $REPLY in
 1) echo "Вы выбрали Да"; break ;;
 2) echo "Вы выбрали Нет"; break ;;
 *) echo "Неправильный выбор." ;;
 esac
done

Команда select выводит нумерованный список и ждёт ввода числа. Это удобно, когда вариантов несколько и нужно избежать опечаток.

Полный «шаблон» скрипта с вопросом «Да или нет»

Ниже представлена готовая заготовка, которую можно копировать в любой Bash‑скрипт и адаптировать под свои нужды.

#!/bin/bash

ask_yes_no {
 local prompt="$1"
 local default="$2" # "yes", "no" или "" (без значения по умолчанию)
 local reply

 # Формируем строку подсказки
 if [[ "$default" == "yes" ]]; then
 prompt="${prompt} [Y/n] "
 elif [[ "$default" == "no" ]]; then
 prompt="${prompt} [y/N] "
 else
 prompt="${prompt} [y/n] "
 fi

 while true; do
 read -r -p "$prompt" reply
 # Если пользователь просто нажал Enter, берём значение по умолчанию
 if [[ -z "$reply" && -n "$default" ]]; then
 reply="$default"
 fi
 reply=${reply,,} # нижний регистр
 case "$reply" in
 y|yes) return 0 ;; # Да
 n|no) return 1 ;; # Нет
 ) echo "Пожалуйста, введите y/yes или n/no." ;;
 esac
 done
}

if ask_yes_no "Удалить все файлы в /tmp?" "no"; then
 echo "Удаляем..."
 rm -rf /tmp/
else
 echo "Операция отменена."
fi

Эта функция:

  • Поддерживает варианты ввода y/yes и n/no (регистронезависимо).
  • Позволяет задать значение по умолчанию, которое будет использовано при пустом вводе.
  • Возвращает статус 0 для «да» и 1 для «нет», что удобно использовать в условных конструкциях.

В Bash запрос «Да или нет» выглядит простым, но без правильного подхода скрипт может вести себя непредсказуемо:

  • Не учитывайте регистр – пользователи могут написать ДА, да или Y.
  • Обрабатывайте все возможные варианты, включая пустой ввод.
  • Для более сложных проверок используйте логические операторы || и && внутри [[ … ]].
  • Не забывайте о тайм‑ауте и о том, как правильно завершать скрипт с кодом возврата.

Следуя рекомендациям из этой статьи, вы сможете писать надёжные интерактивные скрипты, которые корректно реагируют на ответы пользователя «да» или «нет». Удачной разработки!