Как добавить графический интерфейс в сценарии оболочки Linux
Опубликовано: 2022-01-29 Вы можете использовать окна графического интерфейса, ползунки, переключатели, индикаторы выполнения и многое другое в своих сценариях Bash. Узнайте, как использовать набор инструментов zenity
и обновите свои сценарии Bash. Мы покажем вам, как это сделать.
Сценарии Bash — это мощный язык программирования, и, поскольку он встроен в оболочку Bash, он легко доступен каждому. На этом языке легко начать программировать. Поскольку он интерпретируемый, вам не нужно компилировать сценарии. Как только вы отредактировали файл сценария и сделали его исполняемым, вы можете запустить его. Это делает цикл кодирования, запуска и отладки достаточно эффективным.
У людей есть две основные жалобы на сценарии Bash, и первая — это скорость. Поскольку оболочка Bash интерпретирует команды сценария, они выполняются не так быстро, как скомпилированный код. Однако это все равно, что жаловаться на то, что трактор не так быстр, как автомобиль; они предназначены для разных вещей.
Однако есть два вида скорости. Часто вы можете составить быстрый сценарий и использовать его для выполнения задачи гораздо быстрее, чем разрабатывать решение на скомпилированном языке, таком как C.
Вторая жалоба, которую люди предъявляют к сценариям Bash, касается пользовательского интерфейса — это окно терминала. Конечно, иногда интерфейс не имеет значения. Если единственным человеком, который когда-либо будет использовать сценарий, является его автор, интерфейс, вероятно, не так важен. Это также не имеет значения для сценариев, выполняющих фоновую и пакетную обработку. Как правило, такие скрипты не требуют особого взаимодействия с пользователем (если оно вообще требуется).
Бывают случаи, когда вам нужно что-то более интуитивно понятное и современное, чем окно терминала. Большинство людей знакомы с графическим пользовательским интерфейсом (GUI). Чтобы предоставить людям как можно более беспрепятственный опыт, вы должны создавать и использовать элементы графического интерфейса пользователя из своих сценариев.
Приложение Zenity
zenity
позволяет включать в сценарии Bash широкий спектр элементов графического интерфейса. Это мощный набор инструментов, который придает вашим сценариям современный вид и современный знакомый внешний вид.
zenity
предустановлен в дистрибутивах Ubuntu, Fedora и Manjaro. Это часть GNOME. Если вы используете KDE, вы можете вместо этого проверить kdialog
, хотя zenity
работает в любой среде рабочего стола.
Примеры в этой статье показывают, как создавать различные диалоговые окна из командной строки, как фиксировать их возвращаемые значения и выбор пользователя в переменных и как использовать диалоговые окна в скриптах.
Мы закончим небольшим приложением, в котором используются все три типа диалоговых окон.
Диалоговое окно календаря
Диалоговое окно календаря позволяет кому-то выбрать дату. Чтобы создать его с zenity
, требуется одна команда из двух слов:
зенити --календарь
Появится диалоговое окно календаря. У него есть все функции, которые вы ожидаете от стандартного средства выбора даты. Вы можете изменить месяц и год и щелкнуть день, чтобы выбрать эту дату. По умолчанию сегодняшняя дата выделяется при появлении окна.
Нажмите «ОК», чтобы закрыть диалоговое окно, и выберите выделенную дату. Двойной щелчок по дате делает то же самое.
Если вы не хотите выбирать дату, нажмите «Отмена», нажмите клавишу «Esc» на клавиатуре или закройте диалоговое окно.
В приведенном выше примере выбрано 19 августа 2019 года. Если пользователь нажимает «ОК», календарь закрывается, а выбранная дата печатается в окне терминала.
Вы можете игнорировать строку «GTKDialog отображается без временного родителя. Это обескураживает».
GTK означает GIMP Tool Kit, набор инструментов, используемый для разработки интерфейса GNOME. Первоначально он был разработан авторами программы обработки изображений GNU (GIMP). GNU расшифровывается как GNU Not Unix.
Движок GTK предупреждает авторов zenity
, что они использовали компонент GTK нестандартным образом.
Получение значения даты
Печать даты на терминале мало что для нас делает. Если мы собираемся вызвать этот календарь из одного из наших скриптов, нам нужно зафиксировать выбранное значение даты, чтобы мы могли сделать с ним что-то полезное в нашем скрипте. Мы также немного настроим календарь.
Мы будем использовать следующие параметры с календарем. Все они должны использоваться с двойным дефисом «–»:
- –text : указывает строку текста для отображения в календаре. Он заменяет значение по умолчанию «Выберите дату снизу».
- –title : устанавливает заголовок диалогового окна календаря.
- –day : устанавливает день, выбранный при открытии календаря.
- –month : устанавливает месяц, выбранный при открытии календаря.
- –year : устанавливает год, выбранный при открытии календаря.
Мы используем переменную ChosenDate
для записи даты, возвращенной из календаря. И мы используем echo $ChosenDate
для вывода этой даты в окно терминала.
Да, мы достигли того же результата в предыдущем примере, но здесь у нас есть выбранная дата, сохраненная в переменной. В предыдущем примере он был напечатан и забыт.
ChosenDate=$(zenity -- calendar --text "Выберите дату" --title "Как сделать компьютерный график" --день 1 -- месяц 9 --год 2019); эхо $ВыбраннаяДата
Теперь в календаре отображается наше приглашение и заголовок нашего окна. Дата устанавливается на выбранную нами дату начала, а не на сегодняшнюю дату.
Мы также можем настроить формат строки даты, возвращаемой при выборе. За --date-format
должен следовать спецификатор формата. Это строка токенов, определяющих данные и форматы, которые должны быть включены в вывод. Токены такие же, как те, которые используются с функцией языка C strftime()
, и их существует огромный выбор.
Токены, которые мы используем:
- %A : Полное название дня недели.
- %d : День месяца в виде цифры.
- %m : месяц в виде цифры.
- %y : год в виде двух цифр (без века).
ChosenDate=$(zenity -- calendar --text "Выберите дату" --title "Как сделать компьютерный график" --date-format="%A %d/%m/%y" --день 1 -- 9 месяц -- 2019 год); эхо $ВыбраннаяДата
Кто-то выбирает дату:
И дата возвращается в нашем формате. Он показывает название дня недели, за которым следует дата в европейском порядке: день, месяц, год.
Диалоговое окно выбора файла: выбор файла
Диалоговые окна выбора файла довольно сложны. Люди могут просмотреть файловую систему, выделить файл или файлы, а затем нажать «ОК», чтобы выбрать эти файлы или полностью отменить выбор.
zenity
предоставляет все эти функции и многое другое. И им так же легко пользоваться, как и диалоговым окном календаря.
Новые параметры, которые мы собираемся использовать:
- --file-selection : Сообщает
zenity
, что мы хотим использовать диалоговое окно выбора файла. - --multiple : позволяет кому-то выбрать более одного файла.
- --file-filter : сообщает диалоговому окну файла, какие типы файлов отображать.
zenity --file-selection --tile "Как компьютерщик" --multiple --file-filter='*.mm *.png *.page *.sh *.txt'
Диалоговое окно выбора файла так же функционально, как и любое другое окно выбора файла.
Пользователь может просмотреть файловую систему и выбрать файл по своему выбору.
Мы перешли в новый каталог и выбрали файл с именем «button_hybrid.png».
Когда вы нажимаете «ОК», диалоговое окно выбора файла закрывается, а имя файла и путь печатаются в окне терминала.
Если вам нужно использовать имя файла в какой-либо дальнейшей обработке, вы можете зафиксировать его в переменной, как вы сделали для даты из календаря.
Диалоговое окно выбора файла: сохранение файла
Если мы добавим одну опцию, мы можем превратить диалоговое окно выбора файла в диалоговое окно сохранения файла. Опция --save
. Мы также собираемся использовать параметр --confirm-overwrite
. Это побуждает человека подтвердить, что он хочет перезаписать существующий файл.
Ответ=$(zenity --file-selection --save --confirm-overwrite); эхо $ ответ
Появится диалоговое окно сохранения файла. Обратите внимание, что есть текстовое поле, где кто-то может ввести имя файла.
Пользователь может перейти к своему выбору в файловой системе, указать имя файла или щелкнуть существующий файл, чтобы перезаписать его.
В приведенном выше примере пользователь выделил существующий файл.
Когда он нажимает «ОК», появляется диалоговое окно подтверждения с просьбой подтвердить, что он хочет заменить существующий файл. Обратите внимание, что имя файла отображается в диалоговом окне предупреждения. Именно такое внимание к деталям придает zenity
профессиональный вид.
Если бы мы не использовали параметр --confirm-overwrite
, файл был бы автоматически перезаписан.
Имя файла хранится в переменной Response
, которая выводится в окно терминала.
Диалоговые окна уведомлений
С zenity
включение гладких диалоговых окон уведомлений в ваши сценарии не требует усилий. Существуют стандартные диалоговые окна, которые вы можете вызвать для предоставления информации, предупреждений, сообщений об ошибках и вопросов для пользователя.
Чтобы создать диалоговое окно с сообщением об ошибке, используйте следующую команду:
zenity --error --width 300 --text «Отказано в доступе. Невозможно записать в файл».
Мы используем следующие новые параметры:
- --error : Сообщает
zenity
, что мы хотим использовать диалоговое окно с ошибкой. - –width : устанавливает начальную ширину окна.
Диалоговое окно ошибки отображается с указанной шириной. Он использует стандартный значок ошибки GTK.
Чтобы создать информационное диалоговое окно, используйте следующую команду:
zenity --info --width 300 --text "Обновление завершено. Нажмите OK, чтобы продолжить."
Мы используем новую опцию --info
, которая указывает zenity
создать информационное диалоговое окно.
Чтобы создать диалоговое окно вопроса, используйте следующую команду:
zenity --question --width 300 --text "Вы рады продолжить?"; эхо $?
Мы используем новую опцию --question
, которая указывает zenity
создать диалоговое окно с вопросом.
$?
является специальным параметром. Он содержит возвращаемое значение из последнего запущенного конвейера переднего плана. В общих чертах это значение последнего закрытого процесса. Нулевое значение означает «ОК», а значение, равное единице или более, означает «Отмена».
Это общая техника, которую вы можете применить к любому диалоговому окну zenity
. Проверяя это значение в своем скрипте, вы можете определить, должны ли данные, возвращаемые из диалогового окна, обрабатываться или игнорироваться.
Мы нажали «Да», поэтому код возврата — ноль, указывающий «ОК».
Чтобы создать диалоговое окно с предупреждением, используйте следующую команду:
zenity --warning --title «Недостаточно места на жестком диске» --width 300 --text «Возможно, недостаточно места на жестком диске для сохранения резервной копии».
Мы используем новый параметр --warning
, который указывает zenity
создать диалоговое окно с предупреждением.
Появится диалоговое окно с предупреждением. Это не вопрос, так что у него только одна кнопка.
Диалоговое окно прогресса
Вы можете использовать диалоговое окно прогресса zenity
, чтобы отобразить индикатор выполнения, который показывает, насколько близок к завершению ваш скрипт.
Индикатор выполнения продвигается в соответствии со значениями, переданными в него из вашего скрипта. Чтобы продемонстрировать принцип, используйте следующую команду:
(для i в $(seq 0 10 100); выполнить эхо $i; заснуть 1; выполнить)
Команда разбивается следующим образом:
- Команда
seq
выполняет последовательность от 0 до 100 с шагом 10. - На каждом шаге значение сохраняется в переменной
i
. Это печатает в окно терминала. - Команда приостанавливается на одну секунду из-за команды
sleep 1
.
Мы можем использовать это с диалоговым окном прогресса zenity
, чтобы продемонстрировать индикатор выполнения. Обратите внимание, что мы передаем вывод предыдущей команды в zenity:
(для i в $(seq 0 10 100); выполнить эхо $i; заснуть 1; выполнить) | zenity --progress --title "Как компьютерщик" -- auto-close
Мы используем следующие новые параметры:
- --progress : Сообщает
zenity
, что мы хотим использовать диалоговое окно прогресса. - --auto-close : закрывает диалоговое окно, когда индикатор выполнения достигает 100 процентов.
Появляется диалоговое окно прогресса, и полоса приближается к 100 процентам с паузой в одну секунду между каждым шагом.
Мы можем использовать эту концепцию передачи значений в zenity
, чтобы включить диалоговое окно прогресса в сценарий.
Введите этот текст в редакторе и сохраните его как «progress.sh».
!/бин/баш рабочий список функций () { echo "# Первый рабочий элемент" эхо "25" спать 1 echo "# Второй рабочий элемент" эхо "50" спать 1 echo "# Третий рабочий элемент" эхо "75" спать 1 echo "# Последний рабочий элемент" эхо "100" спать 1 } рабочий список | zenity --progress --title "Как компьютерщик" --auto-close выход 0
Вот разбивка сценария:
- Сценарий определяет функцию под названием
work-list
. Здесь вы размещаете свои команды и инструкции для выполнения реальной работы. Замените каждую из командsleep 1
своими реальными. -
zenity
принимаетecho "# ..."
и отображает их в диалоговом окне прогресса. Измените текст этих строк, чтобы они передавали информативные сообщения пользователю. -
echo
-строки, содержащие числа, такие какecho "25"
, также принимаютсяzenity
и устанавливают значение индикатора выполнения. - Функция рабочего списка вызывается и передается в
zenity
.
Используйте эту команду, чтобы сделать скрипт исполняемым:
chmod +x progress.sh
Используйте эту команду для запуска скрипта:
./прогресс.ш
Сценарий запускается, и текстовое сообщение изменяется по мере выполнения каждой фазы сценария. Индикатор выполнения постепенно приближается к 100 процентам.
Диалоговое окно «Масштаб»
Диалоговое окно масштаба позволяет кому-то перемещать ползунок, чтобы выбрать числовое значение. Это означает, что она не может ввести слишком высокое или слишком низкое значение.
Мы используем следующие новые параметры:
- --scale : Сообщает
zenity
, что мы хотим использовать диалоговое окно масштаба. - –min-value : устанавливает минимальное значение шкалы.
- –max-value : устанавливает максимальное значение шкалы.
- –step : устанавливает величину перемещения ползунка при использовании клавиш со стрелками. Это не влияет на движения ползунка, если кто-то использует мышь.
- –value : устанавливает начальное значение и положение ползунка.
Это команда, которую мы используем:
Response=$(zenity --scale --title "Пошаговое руководство" --text "Выберите увеличение." --min-value=0 --max-value=30 --step=3 --value15); эхо $ответ
Появится диалоговое окно ползунка с ползунком, установленным на 15.
Пользователь может перемещать ползунок, чтобы выбрать новое значение.
Когда она нажимает «ОК», значение передается в переменную Response
и печатается в окне терминала.
Диалоговое окно ввода
Диалоговое окно ввода позволяет кому-либо вводить текст.
Мы используем следующие новые параметры:
- --entry : Сообщает
zenity
, что мы хотим использовать диалоговое окно ввода. - --entry-text : вы можете использовать это, если хотите ввести предлагаемое значение в поле ввода текста. Мы используем « », чтобы заполнить пустое поле. Это не является строго обязательным, но мы хотели задокументировать эту опцию.
Полная команда выглядит так:
Response=$(zenity --entry --text "Введите поисковый запрос" --title "Howe-To Geek" --entry-text=""); эхо $ответ
Появится простое диалоговое окно, содержащее поле ввода текста.
Кто-то может набирать и редактировать текст.
Когда он нажимает «ОК», введенное им значение присваивается переменной Response. Мы используем эхо для вывода значения переменной в окно терминала.
Собираем все вместе
Давайте объединим эти методы и создадим функциональный скрипт. Сценарий выполнит сканирование информации об оборудовании и представит результаты пользователю в прокручиваемом текстовом окне. Она может выбрать длинный или короткий тип сканирования.
В этом скрипте мы будем использовать три типа диалоговых окон, два из которых являются для нас новыми:
- Первое представляет собой диалоговое окно со списком. Это позволяет кому-то сделать выбор.
- Второе — это диалоговое окно прогресса, которое сообщает пользователю, что что-то происходит, и ему следует подождать.
- Третье — это окно с текстовой информацией, которое отображает результаты для пользователя.
Введите этот текст в редакторе и сохраните его как «hardware-info.sh».
#!/бин/баш # Показать список оборудования для этого компьютера Временный файл=$(mktemp) ListType=`zenity --width=400 --height=275 --list --radiolist \ --title 'Сканирование оборудования' \ --text 'Выберите тип сканирования:' \ --column 'Выбрать' \ --column 'Тип сканирования' TRUE "Короткий" FALSE "Длинный"` если [[$? -экв 1 ]]; тогда # они нажали Cancel или закрыли диалоговое окно zenity --error --title="Сканирование отклонено" --width=200 \ --text="Сканирование оборудования пропущено" выход 1 Элиф [$ListType == "Короткий"]; тогда # они выбрали короткий переключатель Флаг="--короткий" еще # они выбрали длинный переключатель Флаг="" фи # поиск информации об оборудовании с соответствующим значением в $Flag hwinfo $ Флаг | тройник >(zenity --width=200 --height=100 \ --title="Сопоставление информации" --progress \ --pulsate --text="Проверка оборудования..." \ --auto-kill --auto-close) >${TempFile} # Отображение информации об оборудовании в прокручивающемся окне зенити --ширина=800 --высота=600 \ --title "Сведения об оборудовании" \ --text-info --filename="${TempFile}" выход 0
Используйте эту команду, чтобы сделать его исполняемым:
chmod +x hardware-info.sh
Этот скрипт создает временный файл, и имя файла хранится в переменной TempFile:
Временный файл=$(mktemp)
Сценарий использует параметр --list
для создания диалогового окна zenity
, называемого диалоговым окном списка. Символы «\» в конце строк указывают сценарию обрабатывать их как одну длинную строку, обернутую вокруг. Вот процесс:
- Мы указываем ширину и высоту окна.
- Диалоговое окно списка поддерживает столбцы. Опция
--radiolist
делает первый столбец столбцом переключателей. - Мы устанавливаем заголовок и текстовую подсказку для окна.
- Мы устанавливаем заголовок первого столбца «Выбрать». Содержимое этого столбца будет переключателями.
- Мы устанавливаем заголовок второго столбца «Выбрать» и предоставляем содержимое второго столбца. Этот столбец содержит две текстовые метки: «Короткая» и «Длинная». Индикаторы TRUE и FALSE означают, что опция «Short» выбрана по умолчанию при появлении диалогового окна.
- Мы сохраняем результат из этого диалогового окна в переменной с именем
ListType
.
ListType=`zenity --width=400 --height=275 --list --radiolist \ --title 'Сканирование оборудования' \ --text 'Выберите тип сканирования:' \ --column 'Выбрать' \ --column 'Тип сканирования' TRUE "Короткий" FALSE "Длинный"`
Если пользователь нажимает «Отмена», нам не нужно проверять значение в ListType,
мы можем просто выйти. Если он нажимает «ОК», нам нужно выяснить, выбрал ли он переключатель «Короткий» или «Длинный»:
- Специальный параметр
$?
равняется нулю, если пользователь нажал «ОК». Он равен единице, если он нажал «Отмена» или закрыл окно. - Если оно равно единице, сценарий отображает диалоговое окно с информацией об ошибке и завершает работу. Если он нажимает «ОК», мы переходим к проверке значения в переменной
ListType
. - Если переменная
ListType
содержит значение «Short», сценарий устанавливает для переменной с именемFlag
значение «–short». - Если переменная
ListType
не содержит значение «Short», она должна содержать значение «Long». Сценарий устанавливает переменную с именемFlag
равной «», что является пустой строкой. - Сценарий использует переменную
Flag
в следующем разделе.
если [[$? -экв 1 ]]; тогда # они нажали Cancel или закрыли диалоговое окно zenity --error --title="Сканирование отклонено" --width=200 \ --text="Сканирование оборудования пропущено" выход 1 Элиф [$ListType == "Короткий"]; тогда # они выбрали короткий переключатель Флаг="--короткий" еще # они выбрали длинный переключатель Флаг="" фи
Теперь, когда скрипт знает, какой тип сканирования хочет пользователь, мы можем выполнить сканирование информации об оборудовании:
- Сценарий вызывает команду
hwinfo
и передает ей значение переменнойFlag
. - Если
Flag
содержит «–short», командаhwinfo
выполняет короткое сканирование. Если значениеFlag
равно «», ничего не передается вhwinfo
и по умолчанию выполняется длительное сканирование. - Скрипт направляет вывод
hwinfo
вtee
.tee
отправляет вывод вzenity
иTempFile
. - Сценарий создает диалоговое окно индикатора выполнения. Он устанавливает ширину и высоту диалогового окна, а также заголовок и текст подсказки.
- Сценарий не может знать заранее, сколько информации выдаст команда
hwinfo
, поэтому он не может настроить индикатор выполнения так, чтобы он корректно продвигался на 100 процентов. Параметр--pulsate
заставляет диалоговое окно прогресса отображать движущийся индикатор. Это информирует пользователя о том, что что-то происходит, и ему следует подождать. - Опция
--auto-kill
завершает работу скрипта, если кто-то нажимает «Отмена». - Параметр
--auto-close
автоматически закрывает диалоговое окно прогресса, когда процесс, который он отслеживает, завершается.
# поиск информации об оборудовании с соответствующим значением в $Flag hwinfo $ Флаг | тройник >(zenity --width=200 --height=100 \ --title="Сопоставление информации" --progress \ --pulsate --text="Проверка оборудования..." \ --auto-kill --auto-close) >${TempFile}
Когда сканирование hwinfo
завершается, сценарий вызывает zenity
для создания диалогового окна с текстовой информацией с --text-info
. В диалоговом окне текстовой информации отображается содержимое файла TempFile
:
- Скрипт устанавливает ширину и высоту диалогового окна и текста заголовка.
- Параметр
--flename
используется для чтения содержимого файла, содержащегося в переменнойTempFIle
.
# Отображение информации об оборудовании в прокручивающемся окне зенити --ширина=800 --высота=600 \ --title "Сведения об оборудовании" \ --text-info --filename="${TempFile}"
Когда пользователь закрывает диалоговое окно с текстовой информацией, скрипт завершает работу.
выход 0
Давайте зажжем его и посмотрим.
./оборудование-info.sh
Появится окно со списком. По умолчанию выбран вариант «Короткий».
Давайте выберем «Длинный», а затем нажмите «ОК».
Появится окно прогресса со скользящим индикатором. Он остается на экране до завершения сканирования оборудования.
Когда сканирование оборудования будет завершено, появится диалоговое окно с текстовой информацией и сведениями о сканировании.
Нажмите «ОК».
Даже несгибаемый жокей командной строки должен признать, что пара диалоговых окон с графическим интерфейсом могут придать скромному сценарию Bash профессиональный вид.