В этой статье мы рассмотрим основы конструкции select в Bash.
Конструкция select позволяет генерировать меню.
Конструкции select в Bash
Конструкция select создает меню из списка элементов. Она имеет почти такой же синтаксис, что и цикл for:
select ITEM in [LIST] do [COMMANDS] done
[LIST] – может быть последовательность строк, разделенных пробелами, диапазоном чисел, выводом команды, массивом и т. д. Настраиваемое приглашение для конструкции select может быть задано с помощью переменной среды PS3.
Когда вызывается конструкция select, каждый элемент из списка печатается на экране (стандартная ошибка), которому предшествует номер.
Если пользователь вводит число, соответствующее номеру одного из отображаемых элементов, то [ITEM] для этого элемента устанавливается значение. Значение выбранного элемента сохраняется в переменной REPLY. В противном случае, если пользовательский ввод пуст, подсказка и список меню отображаются снова.
Цикл select будет продолжать работать и запрос на ввод пользователя , пока команда break не будет выполнена.
Чтобы продемонстрировать, как работает конструкция select, давайте рассмотрим следующий простой пример:
PS3="Введите число: " select character in AndreyEx Max Alex Terminator do echo "Выбранный символ: $character" echo "Выбранный номер: $REPLY" done
Скрипт отобразит меню, состоящее из пунктов списка с сопровождающим номером и подсказкой PS3. Когда пользователь вводит число, скрипт напечатает выбранный символ и номер:
1) AndreyEx 2) Max 3) Alex 4) Terminator Введите число: 3 Выбранный символ: Alex Выбранный номер: 3 Введите число:
Пример select в Bash
Как правило, select используется в сочетании с case и заявлением if.
Давайте посмотрим на более практичный пример. Это простой калькулятор, который запрашивает у пользователя ввод и выполняет основные арифметические операции, такие как сложение, вычитание, умножение и деление.
PS3="Выберите операцию: " select opt in add subtract multiply divide quit; do case $opt in add) read -p "Введите первое число: " n1 read -p "Введите второе число: " n2 echo "$n1 + $n2 = $(($n1+$n2))" ;; subtract) read -p "Введите первое число: " n1 read -p "Введите второе число: " n2 echo "$n1 - $n2 = $(($n1-$n2))" ;; multiply) read -p "Введите первое число: " n1 read -p "Введите второе число: " n2 echo "$n1 * $n2 = $(($n1*$n2))" ;; divide) read -p "Введите первое число: " n1 read -p "Введите второе число: " n2 echo "$n1 / $n2 = $(($n1/$n2))" ;; quit) break ;; *) echo "Недопустимая опция $REPLY" ;; esac done
Когда скрипт выполняется, он отображает меню и подсказку PS3. Пользователю предлагается выбрать операцию, а затем ввести два числа. В зависимости от ввода пользователя скрипт напечатает результат. Пользователю будет предложено выполнить новую операцию после каждого выбора, пока команда break не будет выполнена.
1) add 2) subtract 3) multiply 4) divide 5) quit Выберите операцию: 1 Введите первое число: 4 Введите второе число: 5 4 + 5 = 9 Выберите операцию: 2 Введите первое число: 4 Введите второе число: 5 4 - 5 = -1 Выберите операцию: 9 Недопустимая опция 9 Выберите операцию: 5
Недостатком этого скрипта является то, что он может работать только с целыми числами.
Вот немного более продвинутая версия. Мы используем инструмент bc, который поддерживает плавающие числа для выполнения математических вычислений. Кроме того, повторяющийся код сгруппирован внутри функции.
calculate () { read -p "Введите первое число: " n1 read -p "Введите второе число: " n2 echo "$n1 $1 $n2 = " $(bc -l <<< "$n1$1$n2") } PS3="Выберите операцию: " select opt in add subtract multiply divide quit; do case $opt in add) calculate "+";; subtract) calculate "-";; multiply) calculate "*";; divide) calculate "/";; quit) break;; *) echo "Недопустимая опция $REPLY";; esac done
1) add 2) subtract 3) multiply 4) divide 5) quit Выберите операцию: 4 Введите первое число: 8 Введите второе число: 9 8 / 9 = .88888888888888888888 Выберите операцию: 5
Вывод
Конструкция select позволяет легко создавать меню. Это особенно полезно при написании сценариев оболочки, которые требуют ввода данных пользователем.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.