Эх суету красоту навести охота! Привет. С помощью чего можно сделать красивые диалоговые боксы в скриптах и утилитах? Много всяких есть штук, но мне больше всего зашло использовать whiptail.

А зачем вообще красивые диалоговые окна в консоли? Можно же через read в bash всё прекрасно запрашивать. Да! Справедливо! Но это скучно, гораздо интереснее получить какой-нибудь мало-мальски красивый и интуитивный интерфейс.

Например, когда ты устанавливаешь mysql, оно тебе выводит красивый инпут где нужно ввести root пароль. Либо устанавливаешь linux и нужно выбрать галочками, какие пакеты ты хочешь установить. Ну короче ты понял. Некий GUI.

Вот whiptail и позволяет сделать этот GUI с минимальными усилиями + интегрировать его в свои скрипты.

Устанавливается банально: apt/yum install whiptail, но обычно уже идет из коробки в дистрибутиве.

После установки, можно творить. Синтаксис очень простой:

whiptail --yesno "читаешь @bashdays?" 10 50

Откроется диалоговое окно с двумя кнопками yes/no, с текстом + высотой и длиной.

Помимо инпута yes/no имеется ряд других опций:

msgbox - информативное окно с кнопкой OK
infobox - херня какая-то, мигает и закрывается
inputbox - поле для ввода текста
passwordbox - поле для ввода пароля, скрыт звездочками
textbox - выводит содержимое файла в окне
menu - реализация меню
checklist - чекбоксы
radiolist - радиобатоны
gauge - прогрессбар
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
В общем подойдет на все случаи жизни. Что интересно, можно реализовать неплохое меню, либо красиво отобразить на экране результат работы утилиты. Полет фантазии безграничный.

Теперь про то, как все это замешать в bash скрипты.

Логика простая. Если пользователь выбирает Yes, то whiptail вернет 1. Если No, то вернет 0. Если возникла ошибка, либо принудительное завершение, будет возвращен код -1.

Например:

if (whiptail --yesno "Choose Yes or No" 10 60)  then
     echo "You chose Yes. Exit status was $?"
else
     echo "You chose No. Exit status was $?"
fi

Дефолтные кнопки Yes/No можно зареврайтить с помощью опций –yes-button и –no-button.

whiptail --yes-button "Fuck" --no-button "Yeee" --yesno  "What?" 10 60

Теперь вместо Yes/No наблюдаем Fuck/Yeee.

Ну а как получать данные, которые ввели руками? А вот так:

NAME=$(whiptail --inputbox "What is your name?" 10 60 3>&1 1>&2 2>&3)

exitstatus=$?
if [ $exitstatus = 0 ]; then
     echo "Your name is:" $NAME
else
     echo "You chose Cancel"
fi

На экран выведется то, что ты введёшь в инпуте. Таким образом можно дальше строить диалоговые боксы и гонять лысого между ними введенные и выбранные переменные.

Реализация меню:

OPTION=$(whiptail --menu "Choose" 15 60 2 "1" "Linux" "2" "Windows" 3>&1 1>&2 2>&3)

exitstatus=$?
if [ $exitstatus = 0 ]; then
     echo "Your chosen:" $OPTION
else
     echo "You chose Cancel."
fi

В остальных случаях всё делается идентично. Но что такое 3>&1 1>&2 2>&3? Это магия и скучная теория.

Перенаправление ввода-вывода stdin/stdout/stderr. Если коротко, без этого ничего не заработает. Скучная теория. В будущем расскажу про все эти перенаправления stdin/stdout/stderr на котиках. Пока просто делай как написано.

На закуску лови реализацию прогрессбара, тут хоть что-то происходит и движется:

{
  for ((i = 0 ; i <= 100 ; i+=20));  do
     sleep 1
     echo $i
  done
} | whiptail --gauge  "Loading..." 6 60 0

Основное рассмотрели. Можно брать и что-то уже клепать вменяемое. У whiptail есть аналог, называется dialog, посмотри, возможно он подойдет именно тебе, синтаксис похожий.

Картиночки собрал тут, чтобы визуально оценить масштабы всей этой суеты.

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