Программирование в Bash: различия между версиями
imported>Vix (Новая страница: «=='''Bash учебное пособие. Часть 3: Специальные параметры'''== Специальные параметры, те парам…») |
imported>Vix Нет описания правки |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 1: | Строка 1: | ||
=='''Разработка простых интерфейсов с помощью dialog/Xdialog'''== | |||
(Примеры, рассмотренные здесь, вы сможете найти в архиве по адресу | |||
http://gazette.linux.ru.net/lg101/misc/sunil/examples_sh.tar.gz. -- прим. А.К.) | |||
1) Введение | |||
----------- | |||
Статья рассматривает применение программ dialog и Xdialog для | |||
реализации простых интерфейсов к скриптам. Это предполагает, что вы | |||
знакомы с написанием скриптов командного интерпретатора. Последняя | |||
версия статьи доступна по адресу http://gnubox.dyndns.org:8080/~sunil/dialog.php. | |||
dialog это утилита для построения консольных интерфейсов. Xdialog | |||
аналогичная программа для X. Обе программы более-менее совместимы и | |||
легко интегрируются в скрипты. Dialog входит в состав большинства | |||
дистрибутивов GNU/Linux. Если вы хотите собрать её из исходников, то | |||
архив можно найти на http://hightek.org/dialog/. Программа Xdialog | |||
доступна на сайте http://xdialog.dyns.net/ | |||
Эти программы являются свободными и работают на большом количестве | |||
платформ *nix. Большинство приведённых примеров в данном руководстве | |||
являются адаптацией примеров, поставляемых с исходными кодами | |||
программ. | |||
2) Основы | |||
--------- | |||
Вот первый скрипт, работу которого я проверил. Он просто выводит | |||
диалог с кнопками "Да" и "Нет". | |||
#!/bin/bash | |||
DIALOG=${DIALOG=dialog} | |||
$DIALOG --title " Мой первый диалог" --clear \ | |||
--yesno "Привет! Перед вами пример программы,\nиспользующей (X)dialog" 10 40 | |||
case $? in | |||
0) | |||
echo "Выбрано 'Да'.";; | |||
1) | |||
echo "Выбрано 'Нет'.";; | |||
255) | |||
echo "Нажата клавиша ESC.";; | |||
esac | |||
Скопируйте приведённые строки в файл, например, yesno.sh и установите | |||
атрибут выполнения. | |||
$chmod u+x yesno.sh | |||
Теперь попробуйте запустить его (см.рисунок [8]1). | |||
$./yesno.sh | |||
Изменим строку | |||
DIALOG=${DIALOG=dialog} | |||
на | |||
DIALOG=${DIALOG=Xdialog} | |||
и запустим скрипт из xterm. | |||
Давайте детально разберём приведённую программу. Первая строка | |||
является комментарием, который также указывает, что для выполнения | |||
требуется командный интерпретатор bash. (Последовательность #! в мире | |||
Unix называется sha-bang. Она указывает системе какой именно | |||
интерпретатор следует использовать для исполнения сценария -- | |||
http://gazette.linux.ru.net/rus/articles/abs-guide/c112.html. -- прим. А.К.) | |||
DIALOG=${DIALOG=dialog} | |||
Эта строка присваивает переменной DIALOG значение 'dialog'. Сам же | |||
диалог формируется следующей строкой: | |||
$DIALOG --title " Мой первый диалог" --clear \ | |||
--yesno "Привет! Перед вами пример программы,\nиспользующей (X)dialog" 10 40 | |||
Применяемые опции: | |||
--title задаёт заголовок диалога | |||
--clear очищает экран перед отображением диалога | |||
--yesno задаёт тип диалога и текст для отображения. | |||
Выводимый текст нужно брать в двойные кавычки. Текст переносится в | |||
зависимости от ширины диалогового окна. Можно использовать символ \n | |||
для указания принудительного перевода строки. Последние два числа | |||
задают ширину и высоту диалога. (Размеры окна задаются в символах. Это | |||
верно как для dialog, так и Xdialog. При этом для вывода текстовой | |||
информации Xdialog использует моноширинный шрифт. -- прим. А.К.) Между | |||
кнопками можно переключатся при помощи клавиши табуляции. | |||
Теперь программа ждёт пользовательского выбора. В зависимости от того, | |||
нажмёте кнопку "Да" или "Нет", или нажмёте клавишу Escape, переменная | |||
командного интерпретатора $? будет содержать код завершения программы, | |||
который можно так или иначе обработать. | |||
2) Ввод данных | |||
-------------- | |||
Следующая программа ожидает ввода строку и затем отображает её на | |||
экране. | |||
#!/bin/sh | |||
DIALOG=${DIALOG=dialog} | |||
tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$ | |||
trap "rm -f $tempfile" 0 1 2 5 15 | |||
$DIALOG --title "Ввод данных" --clear \ | |||
--inputbox "Привет! Перед вами пример ввода даных\nВведите своё имя:" 16 51 2> $tempfile | |||
retval=$? | |||
case $retval in | |||
0) | |||
echo "Вы ввели `cat $tempfile`" | |||
;; | |||
1) | |||
echo "Отказ от ввода.";; | |||
255) | |||
if test -s $tempfile ; then | |||
cat $tempfile | |||
else | |||
echo "Нажата клавиша ESC." | |||
fi | |||
;; | |||
esac | |||
Запустите программу в консоли и под X (после замены dialog на Xdialog) | |||
Эта программа немного сложнее, чем предыдущая. Следующие строки | |||
определяют временный файл и его удаление при завершении программы: | |||
tempfile=`mktemp 2>/dev/null` || tempfile=/tmp/test$$ | |||
trap "rm -f $tempfile" 0 1 2 5 15 | |||
(В оригинальном скрипте для формирования имени временного файла | |||
использовалась утилита tempfile, но такую обнаружить не удалось, | |||
поэтому пришлось её заменить на mktemp. Хотя скрипт работать будет в | |||
любом случае, т.к. в случае ошибки конструкция || позволяет | |||
сформировать имя файла вида /tmp/test$$, где $$ -- значение генератора | |||
случайных чисел. Хотя, на мой взгляд, корректней было бы использовать | |||
переменную $RANDOM. -- прим. А.К.) | |||
В первой строке делается попытка создать временный файл с помощью | |||
утилиты mktemp. Если это не получается, он создается вручную, в | |||
каталоге /tmp. Вторая строка определяет обработчик сигналов. При | |||
завершении скрипта (вне зависимости, корректном или не корректном) | |||
обработчик удаляет временный файл. Числа -- это номера обрабатываемых | |||
сигналов. | |||
После этого вызывается программа dialog: | |||
$DIALOG --title "Ввод данных" --clear \ | |||
--inputbox "Привет! Перед вами пример ввода даных\nВведите своё имя:" 16 51 2> $tempfile | |||
Программа по умолчанию выводит результат в файл ошибок (stderr - прим. | |||
И.П.). Благодаря этому вы можете перехватить введённый текст для | |||
последующей его обработки. | |||
3) Организация меню | |||
------------------- | |||
Следующая программа позволяет вам организовать список с возможностью | |||
выбора одного из элементов: | |||
#!/bin/sh | |||
DIALOG=${DIALOG=dialog} | |||
tempfile=`mktemp 2>/dev/null` || tempfile=/tmp/test$$ | |||
trap "rm -f $tempfile" 0 1 2 5 15 | |||
$DIALOG --clear --title "Мои любимые исполнители" \ | |||
--menu "Все любят песни хинди, поэтому выбирайте:" 20 51 4 \ | |||
"Rafi" "Mohammed Rafi" \ | |||
"Mukesh" "Mukesh" \ | |||
"Kishore" "Kishore Kumar" \ | |||
"Saigal" "K L Saigal" \ | |||
"Lata" "Lata Mangeshkar" \ | |||
"Yesudas" "K J Yesudas" 2> $tempfile | |||
retval=$? | |||
choice=`cat $tempfile` | |||
case $retval in | |||
0) | |||
echo "Да вы эстет! '$choice' -- это лучшее, что вы слышали в своей жизни!";; | |||
1) | |||
echo "Отказ от ввода.";; | |||
255) | |||
echo "Нажата клавиша ESC.";; | |||
esac | |||
Логика работы скрипта аналогична той, что реализована в скрипте | |||
inputbox.sh -- результат выполнения скрипта перенаправляется во | |||
временный файл, откуда он может быть взят для дальнейшей обработки. | |||
4) Списки зависимых кнопок (radiolist) и флажков (checklist). | |||
------------------------------------------------------------- | |||
Формирование таких списков аналогично организации меню, описанного в | |||
предыдущем разделе. | |||
#! /bin/sh | |||
DIALOG=${DIALOG=dialog} | |||
tempfile=`mktemp 2>/dev/null` || tempfile=/tmp/test$$ | |||
trap "rm -f $tempfile" 0 1 2 5 15 | |||
$DIALOG --backtitle "Не стесняйтесь, выберите любимого певца" \ | |||
--title "Выбор исполнителя" --clear \ | |||
--radiolist "Мой любимый певец, это... " 20 61 5 \ | |||
"Rafi" "Mohammed Rafi" off \ | |||
"Lata" "Lata Mangeshkar" ON \ | |||
"Hemant" "Hemant Kumar" off \ | |||
"Dey" "MannaDey" off \ | |||
"Kishore" "Kishore Kumar" off \ | |||
"Yesudas" "K. J. Yesudas" off 2> $tempfile | |||
retval=$? | |||
choice=`cat $tempfile` | |||
case $retval in | |||
0) | |||
echo "Ого! Кто бы мог подумать, но выбор пал на '$choice'";; | |||
1) | |||
echo "Отказ от ввода.";; | |||
255) | |||
echo "Нажата клавиша ESC.";; | |||
esac | |||
Для того, чтобы использовать список флажков, вместо радиокнопок, | |||
замените в скрипте опцию --radiolist на --checklist. | |||
5) Создание индикатора | |||
---------------------- | |||
Такой элемент позволяет визуализировать процесс выполнения вашего | |||
скрипта: | |||
#!/bin/sh | |||
DIALOG=${DIALOG=dialog} | |||
COUNT=10 | |||
( | |||
while test $COUNT != 110 | |||
do | |||
echo $COUNT | |||
echo "XXX" | |||
echo "Новое сообщение ($COUNT процентов)" | |||
echo "Строка 2" | |||
echo "XXX" | |||
COUNT=`expr $COUNT + 10` | |||
sleep 1 | |||
done | |||
) | | |||
$DIALOG --title "Индикатор" --gauge "А вот пример простейшего индикатора" 20 70 0 | |||
Особенность реализации индикатора заключается в том, что программа | |||
dialog получает данные через конвейер от кода, который заключён внутри | |||
круглых скобок. Есть два момента, на которые необходимо обратить | |||
внимание. Первый -- это обязательное использование переменной $COUNT. | |||
Именно из неё dialog/Xdialog считывает текущее значение индикатора. | |||
При этом желательно, чтобы значение переменной колебалось в диапазоне | |||
от 0 до 100. Второй -- это использование строк вида "XXX" в качестве | |||
ограничителей сообщения, выводящегося на экран. | |||
(В реализации этого элемента есть ошибка. Если используется dialog, то | |||
всё отрабатывается корректно, а в случае с Xdialog строка "Строка 2" | |||
не переносится на новую строку. Использьзование тоже \n не помогает. | |||
-- прим. А.К.) | |||
6) Выбор файла | |||
-------------- | |||
Вот пример простейшего диалога для выбора файла: | |||
#!/bin/sh | |||
DIALOG=${DIALOG=dialog} | |||
FILE=`$DIALOG --stdout --title "Выберите файл" --fselect $HOME/ 10 60` | |||
case $? in | |||
0) | |||
echo "Выбран \"$FILE\"";; | |||
1) | |||
echo "Отказ от ввода.";; | |||
255) | |||
echo "Нажата клавиша ESC.";; | |||
esac | |||
Обратите внимание, что в этом примере используется другой механизм | |||
получения данных от dialog. По умолчанию большинство элементов, | |||
представленных в dialog, возвращают значение через stderr, поэтому в | |||
предыдущих примерах использовалось перенаправление данных с stderr в | |||
файл. Используя опцию --stdout, можно сразу перенаправлять данные на | |||
стандартный вывод, что и демонстрируется в последнем примере. | |||
Диалоговое окно для выбора файла состоит из панелей. Вы можете | |||
перемещаться между ними при помощи клавиши "Tab". Кроме этого, у вас | |||
есть возможность вводить данные непосредственно в строке ввода, | |||
расположенной под панелями. | |||
(Правда есть пара "но", на которые следует обратить внимание. На | |||
первое "но" вы наступите, если попробуете последний пример выполнить, | |||
используя Xdialog. Получается, что добиться | |||
100%-го портирования из текста в графику невозможно -- приходится | |||
менять размер окна. Второе "но" -- это навигация по файловому дереву. | |||
В текстовом режиме (dialog) у меня это не получилось -- клавиша | |||
"Enter" воспринимается как окончательный выбор и использовать её для | |||
перемещения по подкаталогам не удаётся. В графике (Xdialog) с этим | |||
проще -- там поддерживается мышка и перемещение по подкаталогам не | |||
вызывает проблем. -- прим. А.К.) | |||
7) Календарь и настройка часов | |||
------------------------------ | |||
а) Календарь | |||
Информация о годе, месяце и дне выводится на отдельных панелях. Если | |||
значение дня,месяца или года не указано, либо оно отрицательное, то | |||
используются системная дата. (Работает только в dialog. При частичном | |||
отсутствии начальных значений даты (например, вы не указали год) | |||
Xdialog выдаёт сообщение об ошибке. Указать в качестве начального | |||
значения , например, 1000-й год не получится -- dialog воспринимает | |||
это как неверное значение и указывает текущую дату. Xdialog в этом | |||
случае выдаёт сообщение об ошибке. -- прим. А.К.) Для изменения | |||
значений можно использовать стрелки управления курсором, либо | |||
воспользоваться горячими клавишами, используемыми в vi при навигации | |||
по тексту: h, j, k и l. (Верно для dialog. В Xdialog используются | |||
управление при помощи мышки и только навигация по дням месяца возможна | |||
при помощи клавиш управления курсором. -- прим. А.К.) Если год | |||
устанавливается равным 0, то по умолчанию используется значение | |||
текущего года. Результат выводится в формате день/месяц/год | |||
#!/bin/sh | |||
DIALOG=${DIALOG=dialog} | |||
USERDATE=`$DIALOG --stdout --title "Календарь" --calendar "Выберите дату..." 00 7 7 1981` | |||
case $? in | |||
0) | |||
echo "Выбрано: $USERDATE.";; | |||
1) | |||
echo "Отказ от ввода.";; | |||
255) | |||
echo "Нажата клавиша ESC.";; | |||
esac | |||
б) Настройка часов | |||
Этот диалог позволяет вам выбирать время: | |||
#!/bin/sh | |||
DIALOG=${DIALOG=Xdialog} | |||
USERTIME=`$DIALOG --stdout --title "Настройка часов" \ | |||
--timebox "Укажите,пожалуйста, время..." 0 0 12 34 56` | |||
case $? in | |||
0) | |||
echo "Указано время: $USERTIME.";; | |||
1) | |||
echo "Отказ от ввода.";; | |||
255) | |||
echo "Нажата клавиша ESC.";; | |||
esac | |||
8) Другие возможности | |||
--------------------- | |||
Кроме этого, Xdialog располагает такими элементами, как деревья | |||
(tree-view), выбор значения из заданного диапазона (range-box), | |||
редактор текстовых файлов (edit-box) и т.п. За детальной информацией | |||
обращайтесь по адресу | |||
http://thgodef.nerim.net/xdialog/doc/box.html. Не забудьте | |||
заглянуть в справочное руководство для dialog -- оно содержит | |||
интересную информацию о таких возможностях как ввод пароля (password | |||
box), просмотр файла (tailbox) и т.д. Также у вас есть возможность | |||
манипулировать внешним видом окна, меняя цвета, добавляя/убирая тени и | |||
т.п. | |||
9) Подсказки | |||
------------ | |||
Ваш скрипт сможет самостоятельно делать выбор между dialog и Xdialog, | |||
если в его начале дописать следующую конструкцию: | |||
if [ -z $DISPLAY ] | |||
then | |||
DIALOG=dialog | |||
else | |||
DIALOG=Xdialog | |||
fi | |||
Попробуйте запустить скрипт, предложенный ниже, в консоли и "иксах". | |||
#!/bin/sh | |||
if [ -z $DISPLAY ] | |||
then | |||
DIALOG=dialog | |||
else | |||
DIALOG=Xdialog | |||
fi | |||
$DIALOG --yesno "Забавно, не правда ли?" 0 0 | |||
10) Ссылки | |||
---------- | |||
1) Страницы справочного руководства dialog: | |||
http://hightek.org/dialog/manual-0.9a-20010429.html | |||
Обязательно прочтите их (или man dialog), если планируете писать | |||
скрипты, используя dialog. | |||
2) Примеры скриптов: http://www.fifi.org/doc/dialog/examples/. | |||
Все примеры, представленные здесь, являются модифицированными | |||
скриптами, взятыми по этому адресу. Если вы используете Debian | |||
GNU/Linux, то эти примеры вы найдёте в /usr/share/doc/dialog/examples. | |||
3) Страница Thomas'а Dickey: http://dickey.his.com/dialog/ | |||
4) Страница Vincent'а Stemen'а: http://hightek.org/dialog/. | |||
Эта страница содержит исчерпывающую информацию о различных версиях | |||
dialog. | |||
5) Документация по Xdialog: | |||
http://thgodef.nerim.net/xdialog/doc/index.html. | |||
На этой странице вы найдёте полную информацию о функциональных | |||
возможностях Xdialog. | |||
ИСТОЧНИКИ | |||
<hr> | |||
* [Утилита dialog для использования диалоговых окон в shell-скриптах](https://www.ibm.com/developerworks/ru/library/l-dialog/) | |||
* [Разработка простых интерфейсов с помощью dialog/Xdialog](https://www.opennet.ru/base/dev/linux_dialog.txt.html) | |||
* [dialog - en](http://linuxcommand.org/lc3_adv_dialog.php) | |||
* [Bash display dialog boxes](https://bash.cyberciti.biz/guide/Bash_display_dialog_boxes) | |||
* [Автоматический вход в систему при загрузке](https://wiki.debian.org/ru/AutoLoginX) | |||
* [Как сделать автоматический логин в консоль Linux?](https://ru.stackoverflow.com/questions/591993/%D0%9A%D0%B0%D0%BA-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9-%D0%BB%D0%BE%D0%B3%D0%B8%D0%BD-%D0%B2-%D0%BA%D0%BE%D0%BD%D1%81%D0%BE%D0%BB%D1%8C-linux) | |||
* [Автологин в консоль или Xorg](http://support.qbpro.ru/index.php?title=Linux#.D0.90.D0.B2.D1.82.D0.BE.D0.BB.D0.BE.D0.B3.D0.B8.D0.BD_.D0.B2_.D0.BA.D0.BE.D0.BD.D1.81.D0.BE.D0.BB.D1.8C_.D0.B8.D0.BB.D0.B8_Xorg) | |||
=='''Bash учебное пособие. Часть 3: Специальные параметры'''== | =='''Bash учебное пособие. Часть 3: Специальные параметры'''== | ||
Строка 197: | Строка 649: | ||
Запускаем сценарий, и результатом будет: | Запускаем сценарий, и результатом будет: | ||
-ln | -ln | ||
'''ИСТОЧНИКИ:''' | |||
[http://eddnet.org/?p=1173 | <hr> | ||
* [http://eddnet.org/?p=1173 Программирование в BASH] | |||
* [http://eddnet.org/?p=1311 Структура If…then…else] | * [http://eddnet.org/?p=1311 Структура If…then…else] | ||
* [http://habrahabr.ru/post/126701/ Взаимодействие bash-скриптов с пользователем] | * [http://habrahabr.ru/post/126701/ Взаимодействие bash-скриптов с пользователем] | ||
* [http://rus-linux.net/nlib.php?name=/MyLDP/consol/bash-scripts/sh_scripts_for_GUI_ru.html пользовательские диалоги] | * [http://rus-linux.net/nlib.php?name=/MyLDP/consol/bash-scripts/sh_scripts_for_GUI_ru.html пользовательские диалоги] | ||
* [http://docstore.mik.ua/manuals/ru/lfs6/chapter06/ncurses.html библиотека ncurses] | * [http://docstore.mik.ua/manuals/ru/lfs6/chapter06/ncurses.html библиотека ncurses] | ||
* [http://support.serverside.su/knowledgebase/32/--bash---HTTP--DDoS.html Защита от Ddos] | * [http://support.serverside.su/knowledgebase/32/--bash---HTTP--DDoS.html Защита от Ddos] | ||
* [http://rus-linux.net/MyLDP/internet/curlrus.html http - запросы] | * [http://rus-linux.net/MyLDP/internet/curlrus.html http - запросы] | ||
* [http://www.ibm.com/developerworks/ru/library/au-learningtput/ утилита tput] | * [http://www.ibm.com/developerworks/ru/library/au-learningtput/ утилита tput] | ||
* [http://www.opennet.ru/docs/RUS/bash_scripting_guide/ все по bash] | * [http://www.opennet.ru/docs/RUS/bash_scripting_guide/ все по bash] | ||
* [http://www.examplenow.com/ru/whiptail/usage wiptail] | * [http://www.examplenow.com/ru/whiptail/usage wiptail] | ||
* [http://www.ibm.com/developerworks/ru/library/l-zenity/index.html Zenity - графический интерфейс для командной строки] | * [http://www.ibm.com/developerworks/ru/library/l-zenity/index.html Zenity - графический интерфейс для командной строки] | ||
* [https://www.ibm.com/developerworks/ru/library/l-dialog/ Утилита dialog для использования диалоговых окон в shell-скриптах] | |||
* [https://www.opennet.ru/base/dev/linux_dialog.txt.html Разработка простых интерфейсов с помощью dialog/Xdialog] | |||
* [http://tdkare.ru/sysadmin/index.php/Dialog Статья об утилите создания диалогов в скриптах Dialog] |
Текущая версия от 16:31, 10 мая 2018
Разработка простых интерфейсов с помощью dialog/Xdialog
(Примеры, рассмотренные здесь, вы сможете найти в архиве по адресу
http://gazette.linux.ru.net/lg101/misc/sunil/examples_sh.tar.gz. -- прим. А.К.)
1) Введение
Статья рассматривает применение программ dialog и Xdialog для реализации простых интерфейсов к скриптам. Это предполагает, что вы знакомы с написанием скриптов командного интерпретатора. Последняя версия статьи доступна по адресу http://gnubox.dyndns.org:8080/~sunil/dialog.php.
dialog это утилита для построения консольных интерфейсов. Xdialog аналогичная программа для X. Обе программы более-менее совместимы и легко интегрируются в скрипты. Dialog входит в состав большинства дистрибутивов GNU/Linux. Если вы хотите собрать её из исходников, то архив можно найти на http://hightek.org/dialog/. Программа Xdialog доступна на сайте http://xdialog.dyns.net/
Эти программы являются свободными и работают на большом количестве платформ *nix. Большинство приведённых примеров в данном руководстве являются адаптацией примеров, поставляемых с исходными кодами программ.
2) Основы
Вот первый скрипт, работу которого я проверил. Он просто выводит диалог с кнопками "Да" и "Нет".
- !/bin/bash
DIALOG=${DIALOG=dialog}
$DIALOG --title " Мой первый диалог" --clear \
--yesno "Привет! Перед вами пример программы,\nиспользующей (X)dialog" 10 40
case $? in
0) echo "Выбрано 'Да'.";; 1) echo "Выбрано 'Нет'.";; 255) echo "Нажата клавиша ESC.";;
esac
Скопируйте приведённые строки в файл, например, yesno.sh и установите атрибут выполнения.
$chmod u+x yesno.sh
Теперь попробуйте запустить его (см.рисунок [8]1).
$./yesno.sh
Изменим строку
DIALOG=${DIALOG=dialog}
на DIALOG=${DIALOG=Xdialog}
и запустим скрипт из xterm.
Давайте детально разберём приведённую программу. Первая строка является комментарием, который также указывает, что для выполнения требуется командный интерпретатор bash. (Последовательность #! в мире Unix называется sha-bang. Она указывает системе какой именно интерпретатор следует использовать для исполнения сценария -- http://gazette.linux.ru.net/rus/articles/abs-guide/c112.html. -- прим. А.К.)
DIALOG=${DIALOG=dialog}
Эта строка присваивает переменной DIALOG значение 'dialog'. Сам же диалог формируется следующей строкой: $DIALOG --title " Мой первый диалог" --clear \ --yesno "Привет! Перед вами пример программы,\nиспользующей (X)dialog" 10 40
Применяемые опции: --title задаёт заголовок диалога --clear очищает экран перед отображением диалога --yesno задаёт тип диалога и текст для отображения.
Выводимый текст нужно брать в двойные кавычки. Текст переносится в зависимости от ширины диалогового окна. Можно использовать символ \n для указания принудительного перевода строки. Последние два числа задают ширину и высоту диалога. (Размеры окна задаются в символах. Это верно как для dialog, так и Xdialog. При этом для вывода текстовой информации Xdialog использует моноширинный шрифт. -- прим. А.К.) Между кнопками можно переключатся при помощи клавиши табуляции.
Теперь программа ждёт пользовательского выбора. В зависимости от того, нажмёте кнопку "Да" или "Нет", или нажмёте клавишу Escape, переменная командного интерпретатора $? будет содержать код завершения программы, который можно так или иначе обработать.
2) Ввод данных
Следующая программа ожидает ввода строку и затем отображает её на экране.
- !/bin/sh
DIALOG=${DIALOG=dialog} tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$ trap "rm -f $tempfile" 0 1 2 5 15
$DIALOG --title "Ввод данных" --clear \
--inputbox "Привет! Перед вами пример ввода даных\nВведите своё имя:" 16 51 2> $tempfile
retval=$?
case $retval in
0) echo "Вы ввели `cat $tempfile`" ;; 1) echo "Отказ от ввода.";; 255) if test -s $tempfile ; then cat $tempfile else echo "Нажата клавиша ESC." fi ;;
esac
Запустите программу в консоли и под X (после замены dialog на Xdialog)
Эта программа немного сложнее, чем предыдущая. Следующие строки определяют временный файл и его удаление при завершении программы:
tempfile=`mktemp 2>/dev/null` || tempfile=/tmp/test$$ trap "rm -f $tempfile" 0 1 2 5 15
(В оригинальном скрипте для формирования имени временного файла использовалась утилита tempfile, но такую обнаружить не удалось, поэтому пришлось её заменить на mktemp. Хотя скрипт работать будет в любом случае, т.к. в случае ошибки конструкция || позволяет сформировать имя файла вида /tmp/test$$, где $$ -- значение генератора случайных чисел. Хотя, на мой взгляд, корректней было бы использовать переменную $RANDOM. -- прим. А.К.)
В первой строке делается попытка создать временный файл с помощью утилиты mktemp. Если это не получается, он создается вручную, в каталоге /tmp. Вторая строка определяет обработчик сигналов. При завершении скрипта (вне зависимости, корректном или не корректном) обработчик удаляет временный файл. Числа -- это номера обрабатываемых сигналов.
После этого вызывается программа dialog: $DIALOG --title "Ввод данных" --clear \ --inputbox "Привет! Перед вами пример ввода даных\nВведите своё имя:" 16 51 2> $tempfile
Программа по умолчанию выводит результат в файл ошибок (stderr - прим. И.П.). Благодаря этому вы можете перехватить введённый текст для последующей его обработки.
3) Организация меню
Следующая программа позволяет вам организовать список с возможностью выбора одного из элементов:
- !/bin/sh
DIALOG=${DIALOG=dialog} tempfile=`mktemp 2>/dev/null` || tempfile=/tmp/test$$ trap "rm -f $tempfile" 0 1 2 5 15
$DIALOG --clear --title "Мои любимые исполнители" \
--menu "Все любят песни хинди, поэтому выбирайте:" 20 51 4 \ "Rafi" "Mohammed Rafi" \ "Mukesh" "Mukesh" \ "Kishore" "Kishore Kumar" \ "Saigal" "K L Saigal" \ "Lata" "Lata Mangeshkar" \ "Yesudas" "K J Yesudas" 2> $tempfile
retval=$?
choice=`cat $tempfile`
case $retval in
0) echo "Да вы эстет! '$choice' -- это лучшее, что вы слышали в своей жизни!";; 1) echo "Отказ от ввода.";; 255) echo "Нажата клавиша ESC.";;
esac
Логика работы скрипта аналогична той, что реализована в скрипте inputbox.sh -- результат выполнения скрипта перенаправляется во временный файл, откуда он может быть взят для дальнейшей обработки.
4) Списки зависимых кнопок (radiolist) и флажков (checklist).
Формирование таких списков аналогично организации меню, описанного в предыдущем разделе.
- ! /bin/sh
DIALOG=${DIALOG=dialog} tempfile=`mktemp 2>/dev/null` || tempfile=/tmp/test$$ trap "rm -f $tempfile" 0 1 2 5 15
$DIALOG --backtitle "Не стесняйтесь, выберите любимого певца" \
--title "Выбор исполнителя" --clear \ --radiolist "Мой любимый певец, это... " 20 61 5 \ "Rafi" "Mohammed Rafi" off \ "Lata" "Lata Mangeshkar" ON \ "Hemant" "Hemant Kumar" off \ "Dey" "MannaDey" off \ "Kishore" "Kishore Kumar" off \ "Yesudas" "K. J. Yesudas" off 2> $tempfile
retval=$?
choice=`cat $tempfile` case $retval in
0) echo "Ого! Кто бы мог подумать, но выбор пал на '$choice'";; 1) echo "Отказ от ввода.";; 255) echo "Нажата клавиша ESC.";;
esac
Для того, чтобы использовать список флажков, вместо радиокнопок, замените в скрипте опцию --radiolist на --checklist.
5) Создание индикатора
Такой элемент позволяет визуализировать процесс выполнения вашего скрипта:
- !/bin/sh
DIALOG=${DIALOG=dialog}
COUNT=10 ( while test $COUNT != 110 do echo $COUNT echo "XXX" echo "Новое сообщение ($COUNT процентов)" echo "Строка 2" echo "XXX" COUNT=`expr $COUNT + 10` sleep 1 done ) | $DIALOG --title "Индикатор" --gauge "А вот пример простейшего индикатора" 20 70 0
Особенность реализации индикатора заключается в том, что программа dialog получает данные через конвейер от кода, который заключён внутри круглых скобок. Есть два момента, на которые необходимо обратить внимание. Первый -- это обязательное использование переменной $COUNT. Именно из неё dialog/Xdialog считывает текущее значение индикатора. При этом желательно, чтобы значение переменной колебалось в диапазоне от 0 до 100. Второй -- это использование строк вида "XXX" в качестве ограничителей сообщения, выводящегося на экран.
(В реализации этого элемента есть ошибка. Если используется dialog, то всё отрабатывается корректно, а в случае с Xdialog строка "Строка 2" не переносится на новую строку. Использьзование тоже \n не помогает. -- прим. А.К.)
6) Выбор файла
Вот пример простейшего диалога для выбора файла:
- !/bin/sh
DIALOG=${DIALOG=dialog}
FILE=`$DIALOG --stdout --title "Выберите файл" --fselect $HOME/ 10 60`
case $? in
0) echo "Выбран \"$FILE\"";; 1) echo "Отказ от ввода.";; 255) echo "Нажата клавиша ESC.";;
esac
Обратите внимание, что в этом примере используется другой механизм получения данных от dialog. По умолчанию большинство элементов, представленных в dialog, возвращают значение через stderr, поэтому в предыдущих примерах использовалось перенаправление данных с stderr в файл. Используя опцию --stdout, можно сразу перенаправлять данные на стандартный вывод, что и демонстрируется в последнем примере.
Диалоговое окно для выбора файла состоит из панелей. Вы можете перемещаться между ними при помощи клавиши "Tab". Кроме этого, у вас есть возможность вводить данные непосредственно в строке ввода, расположенной под панелями.
(Правда есть пара "но", на которые следует обратить внимание. На первое "но" вы наступите, если попробуете последний пример выполнить, используя Xdialog. Получается, что добиться 100%-го портирования из текста в графику невозможно -- приходится менять размер окна. Второе "но" -- это навигация по файловому дереву. В текстовом режиме (dialog) у меня это не получилось -- клавиша "Enter" воспринимается как окончательный выбор и использовать её для перемещения по подкаталогам не удаётся. В графике (Xdialog) с этим проще -- там поддерживается мышка и перемещение по подкаталогам не вызывает проблем. -- прим. А.К.)
7) Календарь и настройка часов
а) Календарь
Информация о годе, месяце и дне выводится на отдельных панелях. Если значение дня,месяца или года не указано, либо оно отрицательное, то используются системная дата. (Работает только в dialog. При частичном отсутствии начальных значений даты (например, вы не указали год) Xdialog выдаёт сообщение об ошибке. Указать в качестве начального значения , например, 1000-й год не получится -- dialog воспринимает это как неверное значение и указывает текущую дату. Xdialog в этом случае выдаёт сообщение об ошибке. -- прим. А.К.) Для изменения значений можно использовать стрелки управления курсором, либо воспользоваться горячими клавишами, используемыми в vi при навигации по тексту: h, j, k и l. (Верно для dialog. В Xdialog используются управление при помощи мышки и только навигация по дням месяца возможна при помощи клавиш управления курсором. -- прим. А.К.) Если год устанавливается равным 0, то по умолчанию используется значение текущего года. Результат выводится в формате день/месяц/год
- !/bin/sh
DIALOG=${DIALOG=dialog}
USERDATE=`$DIALOG --stdout --title "Календарь" --calendar "Выберите дату..." 00 7 7 1981`
case $? in
0) echo "Выбрано: $USERDATE.";; 1) echo "Отказ от ввода.";; 255) echo "Нажата клавиша ESC.";;
esac
б) Настройка часов
Этот диалог позволяет вам выбирать время:
- !/bin/sh
DIALOG=${DIALOG=Xdialog} USERTIME=`$DIALOG --stdout --title "Настройка часов" \
--timebox "Укажите,пожалуйста, время..." 0 0 12 34 56`
case $? in
0) echo "Указано время: $USERTIME.";; 1) echo "Отказ от ввода.";; 255) echo "Нажата клавиша ESC.";;
esac
8) Другие возможности
Кроме этого, Xdialog располагает такими элементами, как деревья (tree-view), выбор значения из заданного диапазона (range-box), редактор текстовых файлов (edit-box) и т.п. За детальной информацией обращайтесь по адресу http://thgodef.nerim.net/xdialog/doc/box.html. Не забудьте заглянуть в справочное руководство для dialog -- оно содержит интересную информацию о таких возможностях как ввод пароля (password box), просмотр файла (tailbox) и т.д. Также у вас есть возможность манипулировать внешним видом окна, меняя цвета, добавляя/убирая тени и т.п.
9) Подсказки
Ваш скрипт сможет самостоятельно делать выбор между dialog и Xdialog, если в его начале дописать следующую конструкцию:
if [ -z $DISPLAY ] then
DIALOG=dialog
else
DIALOG=Xdialog
fi
Попробуйте запустить скрипт, предложенный ниже, в консоли и "иксах".
- !/bin/sh
if [ -z $DISPLAY ] then
DIALOG=dialog
else
DIALOG=Xdialog
fi $DIALOG --yesno "Забавно, не правда ли?" 0 0
10) Ссылки
1) Страницы справочного руководства dialog: http://hightek.org/dialog/manual-0.9a-20010429.html Обязательно прочтите их (или man dialog), если планируете писать скрипты, используя dialog.
2) Примеры скриптов: http://www.fifi.org/doc/dialog/examples/.
Все примеры, представленные здесь, являются модифицированными скриптами, взятыми по этому адресу. Если вы используете Debian GNU/Linux, то эти примеры вы найдёте в /usr/share/doc/dialog/examples.
3) Страница Thomas'а Dickey: http://dickey.his.com/dialog/
4) Страница Vincent'а Stemen'а: http://hightek.org/dialog/. Эта страница содержит исчерпывающую информацию о различных версиях dialog.
5) Документация по Xdialog: http://thgodef.nerim.net/xdialog/doc/index.html.
На этой странице вы найдёте полную информацию о функциональных возможностях Xdialog.
ИСТОЧНИКИ
- [Утилита dialog для использования диалоговых окон в shell-скриптах](https://www.ibm.com/developerworks/ru/library/l-dialog/)
- [Разработка простых интерфейсов с помощью dialog/Xdialog](https://www.opennet.ru/base/dev/linux_dialog.txt.html)
- [dialog - en](http://linuxcommand.org/lc3_adv_dialog.php)
- [Bash display dialog boxes](https://bash.cyberciti.biz/guide/Bash_display_dialog_boxes)
- [Автоматический вход в систему при загрузке](https://wiki.debian.org/ru/AutoLoginX)
- [Как сделать автоматический логин в консоль Linux?](https://ru.stackoverflow.com/questions/591993/%D0%9A%D0%B0%D0%BA-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9-%D0%BB%D0%BE%D0%B3%D0%B8%D0%BD-%D0%B2-%D0%BA%D0%BE%D0%BD%D1%81%D0%BE%D0%BB%D1%8C-linux)
- [Автологин в консоль или Xorg](http://support.qbpro.ru/index.php?title=Linux#.D0.90.D0.B2.D1.82.D0.BE.D0.BB.D0.BE.D0.B3.D0.B8.D0.BD_.D0.B2_.D0.BA.D0.BE.D0.BD.D1.81.D0.BE.D0.BB.D1.8C_.D0.B8.D0.BB.D0.B8_Xorg)
Bash учебное пособие. Часть 3: Специальные параметры
Специальные параметры, те параметры которые уже установлены и доступны для пользователя. Эти параметры невозможно назначить внутри скрипта. Список таких параметров:
$1 - $9 - Это так называемые позиционные параметры, служат для передачи аргументов командной строки. Если аргументов больше 9, то они должны заключаться в фигурные скобки{} $0 - Имя скрипта который был запущен. $# - Количество аргументов командной строки или позиционных параметров $? - Код с которым была завершена предыдущая команда. Если команда была выполнена удачно, то значение этой переменной будет 0, если же неудачно то не 0. $$ - Номер процесса под которым исполняется данный скрипт, очень удобно использовать в имени файла что бы сделать его уникальным. $! - Номер последнего, запущенного в фоне процесса. $- Список флагов переданных сценарию. Годиться разве что для проверки интерактивного режима. $* - Данный параметр содержит в себе все параметры переданные из командной строки. $@ - То же самое что $*, только каждый параметр представлен отдельно. $_ - Специальная переменная, содержит последний аргумент предыдущей команды.
И так начнем мы с $1-$9.
Создадим script.sh с таким содержимым:
#!/bin/bash # POS1="$1" POS2="$2" POS3="$3" echo "$1 первый параметр, \$1." echo "$2 второй параметр, \$2." echo "$3 третий параметр, \$3." echo echo "$POS1, $POS2, $POS3 параметры" '$1'"," '$2'"," '$3'","
Запускам script.sh с параметрами a v b:
./script.sh a v b
На экране мы увидим:
a первый параметр, $1. v второй параметр, $2. b третий параметр, $3.
a, v, b параметры $1, $2, $3,
Специальный параметр $0
Создадим script.sh с таким содержимым:
#!/bin/bash # echo "Имя сценария: $0"
Запукаем и получим:
script.sh
Специальный параметр $#
Создадим script.sh с таким содержимым:
#!/bin/bash # POS1="$1" POS2="$2" POS3="$3" echo "$1 первый параметр, \$1." echo "$2 второй параметр, \$2." echo "$3 третий параметр, \$3." echo echo "Всего параметров: $#"
Запускам script.sh с параметрами a v b:
./script.sh a v b
И получим :
a первый параметр, $1. v второй параметр, $2. b третий параметр, $3. Всего параметров: 3
Специальный параметр $$
Создадим script.sh с таким содержимым:
#!/bin/bash # TEMFILE=tmp.$$ touch $TEMFILE ls -1 tmp.*
Запускаем скрипт и получаем:
tmp.20375
где 20375 уникальный номер процесса.
Специальный параметр $!
Создадим script.sh с таким содержимым:
#!/bin/bash # COM="ps ax" echo "Вывод на экран номера процессов запущенных команд" echo echo -n "Номер процесса ""$COM"": " ${COM} & echo $!
Результатом будет:
Номер процесса ps ax: 20478
Специальный параметр $*
Создадим script.sh с таким содержимым:
#!/bin/bash # POS1="$1" POS2="$2" POS3="$3" echo "$POS1 первый параметр, \$1." echo "$POS2 второй параметр, \$2." echo "$POS3 третий параметр, \$3." echo echo "Все параметры одной строкой: $*"
Запускам script.sh с параметрами a v b:
./script.sh a v b
Результатом будет:
a первый параметр, $1. v второй параметр, $2. b третий параметр, $3.
Все параметры одной строкой: a v b
Специальный параметр $@
Создадим script.sh с таким содержимым:
#!/bin/bash # N=1 for ARG in "$@" do echo "Входной параметр #$N = $ARG" N=$[$N+1] done
Запускаем его:
./script.sh a v b
Результатом будет:
Входной параметр #1 = a Входной параметр #2 = v Входной параметр #3 = b
Специальный параметр $?
При помощи данного параметра очень удобно проверить результат выполнения какой либо команды. Пример:
#!/bin/bash # PORT=$1 netstat -ln|grep "$PORT" &> /dev/null if [ $? -eq 0 ]; then echo "$PORT поднят. "'$?'"=$?" else echo "$PORT не поднят. "'$?'"=$?" fi
Запускаем его:
./script.sh :80
И если Apache поднят на локальном компьютере, то мы увидим:
:80 поднят. $?=0
Давайте попробуем задать какой то порт, который не слушает ни одна программа:
./script.sh :60000
Результат будет:
:60000 не поднят. $?=1
Специальный параметр $_
Создадим script.sh с таким содержимым:
#!/bin/bash # netstat -ln &> /dev/null echo $_
Запускаем сценарий, и результатом будет:
-ln
ИСТОЧНИКИ:
- Программирование в BASH
- Структура If…then…else
- Взаимодействие bash-скриптов с пользователем
- пользовательские диалоги
- библиотека ncurses
- Защита от Ddos
- http - запросы
- утилита tput
- все по bash
- wiptail
- Zenity - графический интерфейс для командной строки
- Утилита dialog для использования диалоговых окон в shell-скриптах
- Разработка простых интерфейсов с помощью dialog/Xdialog
- Статья об утилите создания диалогов в скриптах Dialog