Поиск по сайту:

Создание диалоговых окон графического пользовательского интерфейса в сценариях 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. Окно сообщений

В окне сообщений будут отображаться сообщения пользователю, и он будет ждать, пока пользователь не нажмет клавишу или . Когда вы нажимаете , он выдает код возврата 0, а если вы нажимаете , он выдает код возврата 255. .

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, и когда вы нажмете , он выдаст код возврата 1.

Используйте флаг --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"

Диалоговое окно «Пароль»

Когда вы нажимаете , он выдает код возврата 0 и возвращает введенный вами пароль в консоль (stderr), если вы работаете с терминала.

Выход в терминале

Вам необходимо записать пароль в переменную, а затем использовать его в скрипте. Как обсуждалось в разделе «Перенаправление», вам необходимо перенаправить результат.

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 для начинающих

Статьи по данной тематике