Shell dialog
Команда zenity Команда zenity выводит на рабочий стол интерактивные диалоговые окна, а также возвращает ввод пользователя. Это позволяет предоставлять пользователю информацию, запрашивать у него информацию при помощи любых скриптов Bash. Вот пример графического клиента для сервиса whois для определенного домена.
#!/bin/bash
# Get domain name
_zenity="/usr/bin/zenity"
_out="/tmp/whois.output.$$"
domain=$(${_zenity} --title "Enter domain" \
--entry --text "Enter the domain you would like to see whois info" )
if [ $? -eq 0 ]
then
# Display a progress dialog while searching whois database
whois $domain | tee >(${_zenity} --width=200 --height=100 \
--title="whois" --progress \
--pulsate --text="Searching domain info..." \
--auto-kill --auto-close \
--percentage=10) >${_out}
# Display back output
${_zenity} --width=800 --height=600 \
--title "Whois info for $domain" \
--text-info --filename="${_out}"
else
${_zenity} --error \
--text="No input provided"
fi
Индикатор для wget:
DFile="http://$RemoteHost/install"
set -o pipefail
(wget -O /home/nameless/install $DFile 2>&1 |sed -u 's/^ *[0-9]*K[ .]*\([0-9]*%\).*/\1/')|\
zenity --title="$MSG_DOWNLOAD_TITLE" \
--text="$MSG_DOWNLOAD_TEXT" \
--progress --auto-close --auto-kill \
--width=500 \
> /dev/null 2>&1
[ $? -ne 0 ] && NetworkError
chmod +x ~nameless/install
Дополнительная информация по команде zenity:
zenity --help man zenity
Команда Dialog
Dialog ≈ это приложение, которое включается в скрипты Bash и создает виджеты в текстовом интерфейсе. Использует библиотеки curses или ncurses. Вот пример кода:
#!/bin/bash dialog --title "Delete file" \ --backtitle "Linux Shell Script Tutorial Example" \ --yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60 # Get exit status # 0 means user hit [yes] button. # 1 means user hit [no] button. # 255 means user hit [Esc] key. response=$? case $response in 0) echo "File deleted.";; 1) echo "File not deleted.";; 255) echo "[ESC] key pressed.";; esac
Основы
Вот первый скрипт, работу которого я проверил. Он просто выводит диалог с кнопками "Да" и "Нет".
#!/bin/bash
DIALOG=${DIALOG=dialog}
$DIALOG --title " Мой первый диалог" --clear \
--yesno "Привет! Перед вами пример программы,\nиспользующей (X)dialog" 10 40
case $? in
0)
echo "Выбрано 'Да'.";;
1)
echo "Выбрано 'Нет'.";;
255)
echo "Нажата клавиша ESC.";;
esac
Ввод данных
Следующая программа ожидает ввода строку и затем отображает её на экране.
#!/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
Организация меню
Следующая программа позволяет вам организовать список с возможностью выбора одного из элементов:
#!/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
Списки зависимых кнопок (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
Создание индикатора
Такой элемент позволяет визуализировать процесс выполнения вашего скрипта:
#!/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 не помогает.)