Написание скриптов с графическим интерфейсом

()

Да-да. Именно так. И это не глупость. Есть множество различных инструментов для создания несложных скриптов с минимальным, но всё-таки графическим интерфейсом. В качестве примера можно привести консольный dialog, и графические gtkdialog и kdialog.

Консольный dialog строит интерфейс используя библиотеку ncurses. Это удобно для скриптов, которые будут запускаться администратором на серверах. Для скриптов, которые будут запускаться пользователем в графическом режиме лучше использовать gtkdialog или kdialog. gtkdialog использует библиотеку gtk и потому удобен для скриптов, которые будут запускаться в GNOME/XFCE. kdialog является частью пакета kdebase графической среды KDE и соответственно использует её библиотеки.

Поскольку автор этих строк является приверженцем KDE, то рассматриваться далее будет исключительно kdialog. Если кто-то из читателей хочет использовать dialog или gtkdialog - кему следует обратиться к документации на эти проекты. Хотя общие принципы использования одинаковы для всех реализаций, и эта заметка, несомненно, будет полезна и им.

Кроме того есть интересная библиотека для создания пользовательских оповещений - libnotify. Она тоже будет нам полезна. Использовать её можно с помощью утилиты notify-send для командной строки.

Задача #1: скрипт для перекодирования файлов

Итак. Для начала поставим простую задачу: написать скрипт, перекодирующий произвольный текстовый файл в utf-8. Нам нужно организовать выбор исходного файла, конечного файла и кодировки исходного файла. Дабы не говорить лишних слов, сразу посмотрим на готовый скрипт с комментариями автора:

#!/bin/sh

# Получаем имя исходного файла
SRCFILENAME=`kdialog --getopenfilename . '*.*'`

# Если имя файла не пустое идём дальше
if (test ${SRCFILENAME}1 != "1") then

    # Получаем имя конечного файла
    DSTFILENAME=`kdialog --getsavefilename . '*.*'`

    # Если имя файла не пустое идём дальше
    if (test ${DSTFILENAME}1 != "1") then

        # Если конечный и начальный файл один и тот же -
        # Завершаем скрипт с сообщением об ошибке
        if (test ${SRCFILENAME} = ${DSTFILENAME}) then
            kdialog --sorry 'Нельзя перекодировать файл сам в себя!'
            exit 1
        fi

        # Получаем список доступных кодировок
        ENCODINGLIST=`iconv -l | sed 's/\/\///'| awk '{ print $1 " " $1}'|sort`

        # Запрашиваем кодировку исходного файла
        ENCODING=`kdialog --menu 'Выберите кодировку:' ${ENCODINGLIST}`

        # Если кодировка выбрана - перекодируем файл и сообщаем об
        # успешном завершении скрипта
        if (test ${ENCODING}1 != "1") then

            iconv -f ${ENCODING} -t utf-8 ${SRCFILENAME} > ${DSTFILENAME}
            kdialog --msgbox 'Перекодирование выполнено!'

        fi

    fi

fi

В скрипте мы сначала показываем диалог выбора имени файла, если файл выбран - запрашиваем второе имя. Если первое и второе имя совпадают - завершаем скрипт. Если же нет - запрашиваем кодировку исходного файла. Если кодировка выбрана - выполняем перекодировку. Больше к этому добавить нечего. Перейдём ко второй задаче:

Задача #2: Проверка доступности сетевого ресурса.

Вторая задача чуть проще - нам нужно периодически проверять доступность сетевого ресурса и как только он становится недоступным - оповестить пользователя. Так же пользователя нужно оповестить и в момент доступности ресурса. Опять же сразу готовое решение с комментариями автора:

#!/bin/sh

# Ресурс, доступность которого нужно проверять.
PINGRESOURCE="ylsoftware.com"

# Файл, который будет создаваться если ресурс недоступен
LOCKFILE="/tmp/${PINGRESOURCE}.lock"

# Интервал (в секундах) между проверками
CHECKTIME=60

# Организуем бесконечный цикл
while true; do

    # Если ресурс не доступен
    if (! ping -c 3 ${PINGRESOURCE} > /dev/null 2> /dev/null) then

        # Проверяем наличие временного файла
        if (! test -f ${LOCKFILE}) then
            # Если временный файл не существует - создаём его
            # и оповещаем пользователя
            touch ${LOCKFILE}
            kdialog --sorry 'Ресурс недоступен!'
        fi

    # Если же доступен
    else
        # Проверяем наличие временного файл
        if (test -f ${LOCKFILE}) then

            # Если файл существует - удаляем его и оповещаем
            # Пользователя о доступности
            rm ${LOCKFILE}
            kdialog --msgbox 'Ресурс доступен!'
        fi
    fi

    sleep ${CHECKTIME}
done

Комментарии тут вобщем-то излишни. Однако диалоговые окна иногда отвлекают. Проблему можно решить заменив их на всплывающие оповещения. Для этого вызовы kdialog надо заменить на вызовы notify-send. В этом случае скрипт примет вид:

#!/bin/sh

# Ресурс, доступность которого нужно проверять.
PINGRESOURCE="ylsoftware.com"

# Файл, который будет создаваться если ресурс недоступен
LOCKFILE="/tmp/${PINGRESOURCE}.lock"

# Интервал (в секундах) между проверками
CHECKTIME=60

# Организуем бесконечный цикл
while true; do

    # Если ресурс не доступен
    if (! ping -c 3 ${PINGRESOURCE} > /dev/null 2> /dev/null) then

        # Проверяем наличие временного файла
        if (! test -f ${LOCKFILE}) then
            # Если временный файл не существует - создаём его
            # и оповещаем пользователя
            touch ${LOCKFILE}
            notify-send ${PINGRESOURCE} 'Ресурс недоступен!'
        fi

    # Если же доступен
    else
        # Проверяем наличие временного файл
        if (test -f ${LOCKFILE}) then

            # Если файл существует - удаляем его и оповещаем
            # Пользователя о доступности
            rm ${LOCKFILE}
            notify-send ${PINGRESOURCE} 'Ресурс доступен!'
        fi
    fi

    sleep ${CHECKTIME}
done

Заключение

В принципе на этом можно закончить. Подробное рассмотрение этой темы займёт целую книгу, в то время как здесь представлены лишь поверхностные сведения, которые показывают только основные идеи, используемые при написании скриптов с графическим интерфейсом. Автор надеется что эта заметка получилась полезной и интересной.

Комментарии:

Anonymous 2010-10-04 17:04:58 (#)

вместо notify-send в KDE4 можно сделать вот так:
kdialog --title ${PINGRESOURCE} --passivepopup "<font color=green>Ресурс доступен</font>" 10

kdialog --title ${PINGRESOURCE} --passivepopup "<font color=red>Ресурс <b>не</b> доступен</font>" 10

MooSE 2010-10-05 09:34:36 (#)

Цитата:

вместо notify-send в KDE4 можно сделать вот так:
kdialog --title ${PINGRESOURCE} --passivepopup "<font color=green>Ресурс доступен</font>" 10

kdialog --title ${PINGRESOURCE} --passivepopup "<font color=red>Ресурс <b>не</b> доступен</font>" 10


Прикольно. Жалко на момент написания статьи этого счастья ещё не было.

Anonymous 2010-10-05 18:40:11 (#)

Вопрос в тему:
Как с помощью kdialog --progressbar вывести прогресс от wget или lame?
почитал статью http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs но там только голимые циклы, а как получить данные с процесса нет.
Может автор статьи, или еще кто-нибудь знает?

MooSE 2010-10-06 02:11:11 (#)

Я к сожалению перестал пользоваться KDE. Вообще для wget вроде как был пример в официальной документации Zenity. Вполне может быть что оно тебе поможет.

Anonymous 2010-10-06 08:23:33 (#)

Спасибо! Нашел!
Может еще кому пригодится, вот ссылка:
http://habrahabr.ru/blogs/linux/68668/
Новый комментарий



© 2006-2016 Вадим Калинников aka MooSE