Псевдографика в консоли Unix/Linux. Немного больше User Friendly чем вы могли себе позволить
21:57Привет! Бывает, хочется забыть о «скучной» консоли, разбавить ее хоть
капелькой интерактива, особенно если часто приходиться делать одни и
теже операции и тем более если вы пишите для облегчения своей участи
скрипты. Итак, псевдографика. За мной читатель, я покажу тебе такую
консоль!
Наверняка многие задумывались, запуская make && make install во
FreeBSD или apt-get install, например в Debian, как же хорошо было бы
использовать подобные диалоги конфигурирования. Они неоправданно забыты и
практически вообще не используются в пользовательских скриптах. Очень и
очень зря.
Исправить это может замечательная утилита dialog.
Она присутствует во FreeBSD седьмой, восьмой ветки, а в Debian,
например, можно сделать apt-get install dialog. Вообще-то, это разные
программы.
Во FreeBSD немного попроще версия:
$ dialog
dialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).
patched to version 0.4 by Stuart Herbert (S.Herbert@shef.ac.uk)
Changes Copyright © 1995 by Andrey A. Chernov, Moscow, Russia
patched by Anatoly A. Orehovsky (tolik@mpeks.tomsk.su)
* Display dialog boxes from shell scripts *
Usage: dialog --clear
dialog --create-rc <file>
dialog [--title <title>] [--clear] [--hline <line>] [--hfile <file>]\
<Box options>
Box options:
--yesno <text> <height> <width> [yes|no]
--msgbox <text> <height> <width>
--prgbox "<command line>" <height> <width>
--infobox <text> <height> <width>
--inputbox <text> <height> <width> [<init string>]
--textbox <file> <height> <width>
--menu <text> <height> <width> <menu height> <tag1> <item1>...
--checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...
--radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...
--ftree <file> <FS> <text> <height> <width> <menu height>
--tree <FS> <text> <height> <width> <menu height> <item1>...
В Linux-версии возможностей побольше:
$ dialog
cdialog (ComeOn Dialog!) version 1.1-20080316
Copyright 2000-2006,2007 Thomas E. Dickey
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* Display dialog boxes from shell scripts *
Usage: dialog <options> { --and-widget <options> }
where options are "common" options, followed by "box" options
Special options:
[--create-rc "file"]
Common options:
[--ascii-lines] [--aspect <ratio>] [--backtitle <backtitle>]
[--begin <y> <x>] [--cancel-label <str>] [--clear] [--colors]
[--cr-wrap] [--default-item <str>] [--defaultno] [--exit-label <str>]
[--extra-button] [--extra-label <str>] [--help-button]
[--help-label <str>] [--help-status] [--ignore] [--input-fd <fd>]
[--insecure] [--item-help] [--keep-tite] [--keep-window]
[--max-input <n>] [--no-cancel] [--no-collapse] [--no-kill]
[--no-label <str>] [--no-lines] [--no-ok] [--no-shadow] [--nook]
[--ok-label <str>] [--output-fd <fd>] [--print-maxsize] [--print-size]
[--print-version] [--separate-output] [--separate-widget <str>]
[--shadow] [--single-quoted] [--size-err] [--sleep <secs>] [--stderr]
[--stdout] [--tab-correct] [--tab-len <n>] [--timeout <secs>]
[--title <title>] [--trace <file>] [--trim] [--version] [--visit-items]
[--yes-label <str>]
Box options:
--calendar <text> <height> <width> <day> <month> <year>
--checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...
--dselect <directory> <height> <width>
--editbox <file> <height> <width>
--form <text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1>...
--fselect <filepath> <height> <width>
--gauge <text> <height> <width> [<percent>]
--infobox <text> <height> <width>
--inputbox <text> <height> <width> [<init>]
--inputmenu <text> <height> <width> <menu height> <tag1> <item1>...
--menu <text> <height> <width> <menu height> <tag1> <item1>...
--mixedform <text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1> <itype>...
--mixedgauge <text> <height> <width> <percent> <tag1> <item1>...
--msgbox <text> <height> <width>
--passwordbox <text> <height> <width> [<init>]
--passwordform <text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1>...
--pause <text> <height> <width> <seconds>
--progressbox <height> <width>
--radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...
--tailbox <file> <height> <width>
--tailboxbg <file> <height> <width>
--textbox <file> <height> <width>
--timebox <text> <height> <width> <hour> <minute> <second>
--yesno <text> <height> <width>
Собственно уже из списка опций понятно, что эта программа позволит сделать, однако для наглядности я продемонстрирую пример.
Бэкап файлов и принудительный сброс на диск дампа выбранной базы (или всех) MySQL:
$ cat ./xbackup.sh
#!/bin/sh
SRC="/usr/home/dev/"
SITE="${SRC}_Web/"
PROJECT="${SRC}_Project/"
# куда будем складывать бэкапы
DST="/usr/home/share/BACKUP/"
# реквизиты для Mysql
SQLLOGIN="root"
SQLPASS="TopSecretPassword"
SQLHOST="localhost"
/* --------------------------------------------------------------------------------------------------------- */
# именовать файлы дампов и архивов будем по дате
DATE=`date "+%Y.%m.%d_%H-%M-%S"`
DSRC=""
# переменная для сохранения выбранного типа бэкапа (база или сайт)
backupType=0
# вызываемая программа для создания диалога
DIALOG=dialog
# временный файл
tempfile=`mktemp /tmp/bkp.XXXXXX`
trap "rm -f $tempfile" 0 1 2 5 15
# функция для вывода информационного окна
InfoDialog() {
${DIALOG} --msgbox "$1" 5 70
}
# упаковка файлов из выбранной директории
BackupFiles() {
if [ ! -d ${2} ]; then
mkdir -p ${2}
fi
tar -c --gzip -f "${2}${DATE}.tar.gz" "${1}"
InfoDialog "OK -> ${2}${DATE}.tar.gz"
}
# сохранения дампа базы в файл
BackupMySQL() {
case ${1} in
"All_Database")
mysqldump -R -E --triggers -u"${SQLLOGIN}" -p"${SQLPASS}" --all-databases > "${tempfile}"
;;
"")
InfoDialog "Backup has been canceled"
exit
;;
*)
mysqldump -R -E --triggers -u"${SQLLOGIN}" -p"${SQLPASS}" ${DBase} > "${tempfile}"
;;
esac
cp "${tempfile}" "${DST}${1}-${DATE}.sql"
# компрессия gzip, отключено за ненадобностью — распаковывать неудобно
echo tar -c --gzip -f "${2}${DATE}.dump" "${tempfile}"
InfoDialog "OK -> ${2}${DATE}.dump"
}
# выбор базы данных из списка существующих на сервере
ChooseDatabase() {
# получаем листинг баз
DBases=` echo "SHOW DATABASES" | mysql -u"${SQLLOGIN}" -p"${SQLPASS}" `
# хитро обеспечиваем опцию All_Database
List="All_${DBases}"
# выводим диалог выбора базы из списка
$DIALOG --title "Please choose a Database " --tree "FS" "List of existing databases" 14 78 7 ${List} 2> ${tempfile}
case $? in
0)
# выбор сделан
DBase=`cat ${tempfile}`
BackupMySQL ${DBase}
;;
1|255)
# диалог прерван (ескейп например)
InfoDialog "Backup has been canceled"
exit
;;
esac
}
# выбор папки с сайтом (реализованвыбор нужного из денвероподобной структуры папок с сайтами)
ChooseDomain() {
Paths=`ls ${1}`
List=""
isEmpty=true
for dName in ${Paths}
do
# выводим только папки внутри которых есть корен сайта или поддомен www (структура реализована совсем как в денвере)
if [ -d "${1}${dName}/www" ] || [ -d "${1}${dName}/htdocs" ]; then
List="${List} ${dName}"
isEmpty=false
fi
done
# таким образом проверяем что выбран корень сайта и пора всетаки паковать его, иначе выводим список подпапок
if ${isEmpty}; then
Count=`echo ${SRC} | wc -c | tr -d ' '`
DSRC=`echo ${1} | awk "{ print substr($ 1, ${Count}) }"`
return 0;
fi
# собстно вывод список папок внутри выбранной
$DIALOG --title "Please choose a path " --tree "FS" "List of existing domains" 14 78 7 ${List} 2> ${tempfile}
case $? in
0)
DName=`cat ${tempfile}`
ChooseDomain "${1}${DName}/"
;;
1|255)
InfoDialog "Backup has been canceled"
exit
;;
esac
}
ProcessBackup() {
case $1 in
Site)
ChooseDomain ${SITE}
BackupFiles "${SRC}${DSRC}" "${DST}${DSRC}"
;;
MySQL)
ChooseDatabase
;;
*)
;;
esac
}
TypeDialog() {
${DIALOG} --title "Choose backup type:" --menu "This is backup types" 12 50 4 \
"Site" "backup web-site" \
"MySQL" "Mysql database" 2> ${tempfile}
case $? in
0)
ProcessBackup `cat ${tempfile}`
TypeDialog
;;
1|255)
InfoDialog "Backup has been canceled"
exit
;;
esac
}
TypeDialog
Выглядит это вот так:
Вот и все. Теперь при работе скрипта можно любоваться интерактивными
«окошечками». Таким же образом легко реализовать выполнение любых
консольных команд, а сочетая это с запуском putty из командной строки с
авторизацией по ключу, можно дать красивый консольный интерфейс для,
например, рестарта апачи на дев-сервере(конечно через sudo с жесткими
ограничениями), всем разработчикам в команде, даже незнакомым с *nix
системами.
Уверен, кому-то изложенные знания пригодятся для того чтобы сделать консоль своего сервера «более User Friendly».
P.S. В процессе написания наткнулся на хорошие примеры http://www.oszone.net/2833/, кое-что оттуда сразу внедрил.
(c)