Создание диалоговых окон графического пользовательского интерфейса в сценариях Bash с помощью Whiptail
Некоторое время назад мы кратко обсуждали Zenity, простую программу, которая позволяет создавать графические (GTK+) диалоговые окна в командной строке и сценариях оболочки. В этой статье мы обсудим еще одну утилиту с графическим интерфейсом под названием Whiptail, которую можно использовать для создания диалоговых окон с графическим интерфейсом в сценариях Bash в Linux.
Не каждому написанному вами сценарию требуется графический интерфейс внешнего интерфейса. Но иногда было бы лучше, если бы вы создали графический интерфейс, а не полагались на взаимодействие с командной строкой. В моем случае, если в сценарии требуется длинный список ответов, я бы выбрал графический интерфейс.
Whiptail — это дружественная утилита с графическим пользовательским интерфейсом, использующая < span style="text-decoration: underline;">newt библиотека программирования. Whiptail предлагает разные диалоговые окна для разных целей. В зависимости от вашего варианта использования вы можете использовать эти диалоговые окна, чтобы сделать ваш скрипт более интерактивным.
Установите Whiptail в Linux
Whiptail предустановлен во многих дистрибутивах, но если в вашем дистрибутиве Whiptail не установлен, следуйте инструкциям ниже, чтобы установить его.
Чтобы проверить, установлен ли уже Whiptail, выполните следующую команду.
which whiptail
Чтобы установить Whiptail в Debian/Ubuntu и его производных дистрибутивах, выполните следующую команду:
sudo apt install whiptail -y
Fedora/RHEL/CnetOS/AlmaLinux/Rocky Linux:
sudo dnf install newt
Arch Linux, EndeavourOS, Manjaro Linux:
sudo pacman -S whiptail
Альпийский Линукс:
apk add newt
Вариант помощи
Вы можете использовать флаг --help
, который отобразит список поддерживаемых диалоговых окон и другие параметры, которые вы можете использовать. Всего поддерживается 10 диалоговых окон с различными функциями, и мы рассмотрим их все в следующих разделах.
whiptail -help
Box options:
--msgbox <text> <height> <width>
--yesno <text> <height> <width>
--infobox <text> <height> <width>
--inputbox <text> <height> <width> [init]
--passwordbox <text> <height> <width> [init]
--textbox <file> <height> <width>
--menu <text> <height> <width> <listheight> [tag item] ...
--checklist <text> <height> <width> <listheight> [tag item status]...
--radiolist <text> <height> <width> <listheight> [tag item status]...
--gauge <text> <height> <width> <percent>
1. Окно сообщений
В окне сообщений будут отображаться сообщения пользователю, и он будет ждать, пока пользователь не нажмет клавишу
whiptail --title "Welcome Message" --msgbox "Howdy, Welcome to OSTechnix.." 8 78
Окно сообщения
Давайте расшифруем приведенную выше команду.
- --title
Это добавит заголовок в окно
- --msgbox
-
Это напечатает сообщение, которое вы указали в кавычках.
- 8 78
Это устанавливает высоту (8) и ширину (78) окна.
Вы можете открыть новый терминал и проверить процесс «whiptail». Он будет в состоянии сна. То есть ждет нажатия
ps -ef | grep -i whiptail
karthick 20023 9251 0 22:41 pts/0 00:00:00 whiptail --title Welcome Message --msgbox Howdy, Welcome to OSTechnix.. 8 78
karthick 20071 19379 0 22:41 pts/1 00:00:00 grep --color=auto -i whiptail
ps -q 20023 -o state --no-headers
S
ПРИМЕЧАНИЕ: Состояние (S) -> прерываемый сон (ожидание завершения события).
2. Информационное окно
Информация похожа на окно сообщения, но разница в том, что информационное окно окна сообщения не будет ждать ввода пользователя. Используйте флаг --infobox
и передайте строку в качестве аргумента, которая будет отображаться в информационном окне.
В некоторых оболочках информационное окно запускается, но не отображает никаких результатов. Вам нужно изменить эмуляцию терминала и запустить ее, как я это сделал в приведенном ниже фрагменте.
TERM=ansi whiptail --title "Welcome Message" --infobox "Howdy, Welcome to OSTechnix.." 8 78
Информационное окно
3. Коробка «Да/Нет»
В поле «Да/Нет» отобразится диалоговое окно с параметром ДА или НЕТ, где, если вы выберете <Да>, будет выдано return< код 0, и когда вы нажмете
Используйте флаг --yesno
, чтобы запросить выбор. Запустите следующий фрагмент, который объединяет поле «да/нет» и окно сообщения. Сначала он отобразит опцию «Да/Нет», и в зависимости от вашего выбора выдаст код возврата.
Создайте сценарий оболочки, скопируйте приведенный ниже фрагмент и запустите его.
#!/usr/bin/env bash
whiptail --title "CONFIRMATION" --yesno "Should I proceed" 8 78
if [[ $? -eq 0 ]]; then
whiptail --title "MESSAGE" --msgbox "Process completed successfully." 8 78
elif [[ $? -eq 1 ]]; then
whiptail --title "MESSAGE" --msgbox "Cancelling Process since user pressed <NO>." 8 78
elif [[ $? -eq 255 ]]; then
whiptail --title "MESSAGE" --msgbox "User pressed ESC. Exiting the script" 8 78
fi
Диалоговое окно «Да/Нет»
Если вы не имеете ни малейшего представления об условных операторах bash, прочтите нашу краткую статью об этом, перейдя по ссылке ниже.
- Сценарии Bash - условные операторы
4. Текстовое поле
Текстовое поле прочитает и распечатает файл. В приведенном ниже фрагменте я читаю файл ostechnix.txt
. Флаг -scrolltext позволяет вам использовать колесо мыши для вертикальной прокрутки, если у вас есть длинные страницы текста, которые не помещаются в текущее окно.
whiptail --textbox --scrolltext ostechnix.txt 10 80
Текстовое окно
5. Перенаправления
Диалоговые окна, которые вы увидите в следующем разделе, требуют сохранения вывода в переменной и последующего использования для обработки. Возвращаемое значение виджета отправляется на stderr вместо stdout. Поэтому вам нужно поменять местами stdout и stderr, чтобы результат сохранялся в переменной.
Вам нужно использовать следующее выражение для замены stdout и stderr.
3>&1 1>&2 2>&3
Попробуем понять приведенное выше выражение. Вы знаете, что FD1 — это стандартный вывод, а FD2 — стандартная ошибка.
- 3>&1 — все, что перенаправляется на файловый дескриптор 3, перенаправляется на файловый дескриптор 1.
- 1>&2 — все, что отправляется в файловый дескриптор 1 (Stdout), перенаправляется в файловый дескриптор 2.
- 2>&3 — все, что отправляется в файловый дескриптор 2 (stderr), перенаправляется в файловый дескриптор 3.
Таким образом, мы меняем местами stdout и stderr, чтобы переменная могла хранить возвращаемое значение из диалоговых окон.
6. Поле пароля
Используя диалоговое окно пароля, вы можете вводить пароли, которые не будут отображаться в виде обычного текста при вводе. Используйте --passwordbox
, чтобы запросить ввод пароля.
whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password"
Диалоговое окно «Пароль»
Когда вы нажимаете
Выход в терминале
Вам необходимо записать пароль в переменную, а затем использовать его в скрипте. Как обсуждалось в разделе «Перенаправление», вам необходимо перенаправить результат.
PASSWORD=$(whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password" 8 78 3>&1 1>&2 2>&3)
echo "The password entered by the user is $PASSWORD"
Сохранение вывода в переменной
7. Поле ввода
Диалоговое окно ввода предложит пользователю ввести данные. Как и в случае с диалоговым окном пароля, введенные вами данные будут выведены на терминал, если вы запустите его с терминала. Вам необходимо использовать перенаправления и сохранять значение в переменной, а затем использовать его для обработки в соответствии с логикой вашей программы.
NEW_USER=$(whiptail --title "Create New User" --inputbox "Username to be created" 8 40 3>&1 1>&2 2>&3)
Поле ввода
Сохранить вывод в переменную
Вы также можете установить текст для ввода по умолчанию. Все, что вам нужно сделать, это добавить текст после высоты и ширины. Ниже приведен синтаксис, в котором вместо [init]
вы поместите текст по умолчанию.
--inputbox <text> <height> <width> [init]
Пример:
whiptail --title "Create New User" --inputbox "Username to be created" 8 40 noname
Текст по умолчанию
Теперь давайте объединим поле ввода, поле пароля, поле «Да/Нет» и текстовое поле и напишем простую программу создания пользователя, чтобы увидеть, как эти диалоговые окна можно соединить вместе.
8. Диалоговое окно контрольного списка
Контрольный список позволяет создать список опций, из которых пользователь может выбрать.
--checklist <text> <height> <width> <listheight> [tag item status]...
Выше приведен синтаксис для создания диалогового окна контрольного списка. Вам необходимо использовать флаг --checklist
, а затем настроить высоту и ширину диалогового окна.
Опция <listheight>
указывает, сколько списков вы собираетесь создать. Каждый список будет помечен тегом <status>
, для которого установлено значение ON или OFF. Вкл. указывает на выбранный список, а Выкл. указывает на отсутствие выбора в списке.
whiptail --title "SELECT PACKAGES TO INSTALL" --checklist \
"List of packages" 20 100 10 \
"chrome" "browser" OFF \
"pip3" "Python package manager" OFF \
"ksnip" "Screenshot tool" OFF \
"virtualbox" "virtualization software" ON
Чтобы выбрать список, нажмите пробел и используйте стрелки вверх и вниз для перемещения между списками. После этого нажмите Enter.
Диалоговое окно «Контрольный список»
Вы можете сохранить выходные данные в массив и позже использовать их. Имена тегов («Chrome, pip3, ksnip, virtualbox») будут выведены в поток stderr в зависимости от выбора.
SELECTED=($(whiptail --title "SELECT PACKAGES TO INSTALL" --checklist \
"List of packages" 20 100 10 \
"chrome" "browser" OFF \
"pip3" "Python package manager" OFF \
"ksnip" "Screenshot tool" OFF \
"virtualbox" "virtualization software" ON 3>&1 1>&2 2>&3))
echo ${SELECTED[@]} # Array of values
Пример вывода:
"pip3" "ksnip" "virtualbox"
Если вы понятия не имеете о массивах bash, у нас есть подробная статья о массивах bash. Предлагаю вам просмотреть ссылку ниже.
- Скрипты Bash: индексированные массивы с примерами
9. Диалоговое окно списка радиостанций
Диалоговое окно списка радиоприемников похоже на диалоговое окно контрольного списка, но с той лишь разницей, что вы можете выбрать только один вариант из списка. Синтаксически список радиостанций и контрольный список одинаковы.
--radiolist <text> <height> <width> <listheight> [tag item status]...
Пример:
SELECTED=$(whiptail --title "Choose Only One Package" --radiolist \
"List of packages" 20 100 10 \
"chrome" "browser" OFF \
"pip3" "Python package manager" OFF \
"ksnip" "Screenshot tool" OFF \
"virtualbox" "virtualization software" OFF 3>&1 1>&2 2>&3)
Переключатель
echo $SELECTED
virtualbox
10. Диалоговое окно меню.
Диалоговое окно меню аналогично диалоговому окну переключателя. Единственное отличие, которое я чувствую, заключается в том, что в диалоговом окне переключателя вам нужно нажать <пробел>, чтобы выбрать элемент из списка, а затем нажать Enter. Но в диалоговом окне меню все, что вам нужно сделать, это просто нажать Enter, что вернет имя тега в stderr.
Синтаксис аналогичен контрольному списку и переключателю, но единственное отличие состоит в том, что нет необходимости устанавливать или отключать опцию «статус» в диалоговом окне меню.
--menu <text> <height> <width> <listheight> [tag item]
Пример:
TO_RUN=$(whiptail --title "Menu example" --menu "Choose an option" 25 78 5 \
"backup" "Start taking defined backup" \
"restore" "restore from last backup" \
"Schedule" "Display active backup schedules" 3>&1 1>&2 2>&3)
Диалоговое окно меню
echo $TO_RUN
backup
11. Индикатор выполнения
Чтобы создать индикатор выполнения, вам необходимо использовать следующий синтаксис. Сначала вы передаете текст, который будет печататься при запуске индикатора выполнения, и устанавливаете высоту и ширину окна, а затем процент прогресса.
--gauge <text> <height> <width> <percent>
Процент прогресса будет контролироваться нашей логикой. Взгляните на приведенный ниже фрагмент. Я перенаправляю цикл while на индикатор выполнения и увеличиваю переменную COUNTER на 10 единиц, которые будут использоваться в качестве процента прогресса.
#!/usr/bin/env bash
COUNTER=0
while [[ ${COUNTER} -le 100 ]]; do
sleep 1
COUNTER=$(($COUNTER+10))
echo ${COUNTER}
done | whiptail --gauge "Running Data Loader" 6 50 ${COUNTER}
Индикатор выполнения будет увеличиваться до 10.
Диалоговое окно «Индикатор выполнения»
Заключение
Мы подошли к концу этой статьи. Здесь мы кратко рассмотрели, как использовать Whiptail для создания различных диалоговых окон в сценариях bash. Если вы уже использовали «whiptail» и у вас есть какой-нибудь трюк с подчиненным устройством, поделитесь им с нами через поле для комментариев.
Ресурс:
- Хлыстохвост
Руководства по написанию сценариев Bash:
- Как использовать команду Date в сценариях Bash в Linux
- Как отлаживать сценарии Bash в Linux и Unix
- Сценарии Bash: анализ аргументов в сценариях Bash с помощью getopts
- Как создавать диалоговые окна графического пользовательского интерфейса в сценариях Bash с помощью Zenity в Linux и Unix
- Сценарии Bash - утверждение случая
- Сценарии Bash - условные операторы
- Скрипты Bash: манипулирование строками
- Сценарии Bash: команда Printf с примерами
- Скрипты Bash: индексированные массивы с примерами
- Скрипты Bash: объяснение ассоциативных массивов на примерах
- Скрипты Bash: цикл For с примерами
- Скрипты Bash: циклы while и Until с примерами
- Перенаправление Bash, объясненное примерами
- Скрипты Bash: переменные, поясняемые примерами
- Скрипты Bash: функции, поясняемые примерами
- Команда Bash Echo с примерами для Linux
- Руководство по Bash Heredoc для начинающих