shell-framework
Материал из Xgu.ru
- Автор: Рома Слєпчик
shell-framework - framework для упрощения написания shell скриптов, а именно такие стандартные решения как help, параметры, конфигурационные файлы. Автором данного фреймворка является Nick Shevelev / Николай Шевелев известный также как Beggy.
Содержание |
[править] Установка в Debian/Ubuntu
Установите пакет apt-transport-https из репозитория.
добавьте в /etc/apt/sources.list строки
deb https://svn.origo.ethz.ch/shell-framework/repositories/debian unstable main deb-src https://svn.origo.ethz.ch/shell-framework/repositories/debian unstable main
добавляем ключ
wget --no-check-certificate https://svn.origo.ethz.ch/shell-framework/repositories/debian/beggyKey.txt -O - | apt-key add -
устанавливаем
aptitude update aptitude install shell-framework
[править] Удаление в Debian/Ubuntu
удаляем стандартным решением
aptitude purge shell-framework
удаляем ключ
apt-key del BeggyCode@gmail.com
чистим /etc/apt/sources.list от ненужных строк
[править] Основные концепции
- Параметры. CLI программа должна уметь работать с параметрами. Параметры могут быть короткими (-M) и длинными(--multi-volume) . Первые нужны непосредственно для ввода их в командной строке и должны быть краткими для скорости ввода, вторые предназначены для использования программы в других скриптах и потому должны быть минимально читаемыми.
- Ожидаемые параметры и поведение. На самом деле я знаю лишь один by default параметр - "-h" и его длинный синоним "--help". Скрипт, будучи запущен с таким параметром, должен распечатать минимальную справку о себе и своих параметрах и закончить выполнение.
- Наличие конфигурационных файлов. Конечно, это не обязательно, но, иногда, крайне желательно, в особенности для скриптов с дюжиной и более возможных параметров.
[править] Пример использования
вот так выглядит обычный скрипт с параметрами
#!/bin/bash function printHelp () { cat - << END_OF_HELP It is test script which just print Hello, <name>. Usage $0 [parameter] ... Paramter: -n <name> - define the <name>. default value is "World" -h - print the help and exit from script END_OF_HELP } declare name="World" while getopts ":n:h" Option do case $Option in n ) name="${OPTARG}" ;; h ) printHelp ; exit 1 ;; esac done echo "Hello, ${name}!"
Тот же скрипт, только с использованием набора библиотек shell-framework
#!/bin/bash shF_PATH_TO_LIB="./shell-framework/lib" source "${shF_PATH_TO_LIB}/base" setDescription "Hello world is example script." #addOption <name> [defaultValue] [shortForm] [longForm] [type] [shortDescription] [longDescription] [priority] [notForConfig]] # type can be shF_SIMPLE_OPTION or shF_OPTION_WITH_VALUE addOption "name" "World" "-n" "--name" "${shF_OPTION_WITH_VALUE}" "you can define your name as ${shF_COMMON_PARAMETER_NAME}." "" "110" if ! initConfig "$@" ; then exit 1 fi echo "Hello, ${name}!"
[править] Подробнее
shF_PATH_TO_LIB="./shell-framework/lib" source "${shF_PATH_TO_LIB}/base"
shF_PATH_TO_LIB определяет, где находится библиотека. Нужно обязательно правильно проинициализировать эту переменную, потому что ее используют все библиотечные скрипты, чтобы подгружать друг-друга. Строка с source подключает файл base, который по сути является набором стандартных подключений - чтобы не писать каждый раз "подключить библиотеку help, config и тд".
setDescription "Hello world is example script."
Определяет краткое описание нашего скрипта. Оно будет использовано потом при показе help-а
#addOption <name> [defaultValue] [shortForm] [longForm] [type] [shortDescription] [longDescription] [priority] [notForConfig]] # type can be shF_SIMPLE_OPTION or shF_OPTION_WITH_VALUE
Небольшая подсказка по параметрам.
addOption "name" "World" "-n" "--name" "${shF_OPTION_WITH_VALUE}" "you can define your name as ${shF_COMMON_PARAMETER_NAME}." "" "110"
Добавляет новый параметр(option) со следующими атрибутами:
- переменная name, которая будет хранить его значение
- значение по умолчанию: World
- краткая форма -n
- длинная --name
- после него ожидается значение (${shF_OPTION_WITH_VALUE})
- описание: "you can define your name as ${shF_COMMON_PARAMETER_NAME}."
- При распечатке в help-е список параметров будет отсортирован в соответствии с весом заданным при инициализации - 110.
if ! initConfig "$@" ; then exit 1 fi
initConfig "$@" пытается "распарсить" строку параметров в соответствии с конфигурацией.
[править] Результат выполнения скрипта
$ ./helloWorld.sh Hello, World! $ ./helloWorld.sh -n Nick Hello, Nick! $ ./helloWorld.sh --name Nick <current time="">: ERROR ./shell-framework/lib/opts.parseOpts:122 The value for option (--name) must be defined.
Как видите последний скрипт запустился с ошибкой. Дело в том, что стандарта на то, как должны быть оформлены параметры и значения нет и автор предпочел следующий подход. Короткие параметры отделяются от значений пробельными символами, а длинные символом "="
$ ./helloWorld.sh --name=Nick Hello, Nick!
пример запуска с параметром help
$ ./helloWorld.sh -h Hello world is example script. Usage: ./helloWorld.sh [option(s)] [command] Options: -h|--help print this help --help-options print detailed description of options using -l <parameter>|--shF_logLevel=<parameter> define the current log level (<parameter>). You can use the following number - 0(shF_EVERYTHING), 1(shF_DEBUG), 2(shF_INFO), 3(shF_HIGH), 4(shF_WARN), 5(shF_ERROR). Config name is shF_currentLogLevel. Default value is "2". --logFile=<parameter> define the <parameter> as log stream. You can use stdError, stdOut or file name. Config name is shF_currentLogFile. Default value is "stdError". -c <parameter>|--config=<parameter> define the <parameter> as property file which will be loaded. -p|--print-config print the current configuration. -n <parameter>|--name=<parameter> you can define your name as <parameter>. Config name is name. Default value is "World"
Как видите сгенерировался не только help, но и множество дополнительных параметров(опций) - уровень логгинга, использование лог файла, поддержка конфигурационных файлов. Если вам нужен только help поменяйте в строке source ${shF_PATH_TO_LIB}/base base на help
[править] Конфигурационные файлы
Когда мы создаем параметр, то мы задаем так же и имя переменной, которая будет проинициализирована значением этого параметра. Порядок инициализации переменной будет следующим:
- значение по умолчанию, если оно есть
- значение из конфигурационного файла(далее "конфиг"), если оно есть
- значение командной строки, если оно есть
Так что если мы создадим файл config.txt с таким содержимым
name="Config"
и запустим наш скрипт то получим следующее
$ ./helloWorld.sh --config=./config.txt Hello, Config!
Ещё одна очень полезная фишка это самостоятельная генерация конфигурационных файлов
$ ./helloWorld.sh -p > config.txt $ cat config.txt #define the current log level (). You can use the following number - 0(shF_EVERYTHING), 1(shF_DEBUG), 2(shF_INFO), 3(shF_HIGH), 4(shF_WARN), 5(shF_ERROR). Default value is "2". #shF_currentLogLevel="2" #define the as log stream. You can use stdError, stdOut or file name. Default value is "stdError". #shF_currentLogFile="stdError" #you can define your name as . Default value is "World". #name="World"
Скрипт генерирует конфиг с комментариями перед каждой переменной (они начинаются со знака #), которые вы можете сами определить при создании нового параметра. Как вы видите, все строки в этом config файле закомментированы - это произошло потому, что ни одна из переменных не отличалась на момент генерации конфига от своего значения по умолчанию. Можно определить параметры и в этом случае конфигурация будет несколько иной:
$ ./helloWorld.sh -p -n zysyl #define the current log level (). You can use the following number - 0(shF_EVERYTHING), 1(shF_DEBUG), 2(shF_INFO), 3(shF_HIGH), 4(shF_WARN), 5(shF_ERROR). Default value is "2". #shF_currentLogLevel="2" #define the as log stream. You can use stdError, stdOut or file name. Default value is "stdError". #shF_currentLogFile="stdError" #you can define your name as . Default value is "World". name="zysyl"
Таким образом, вы можете записать текущие настройки в файл и использовать их в будущем.
[править] Добавляем новый параметр
Предположим мы хотим добавить новый параметр к нашему скрипту. Для этого добавляется всего 1-на строка с параметрами в скрипт
#!/bin/bash shF_PATH_TO_LIB="./shell-framework/lib" source "${shF_PATH_TO_LIB}/base" setDescription "Hello world is example script." #addOption <name> [defaultValue] [shortForm] [longForm] [type] [shortDescription] [longDescription] [priority] [notForConfig]] # type can be shF_SIMPLE_OPTION or shF_OPTION_WITH_VALUE addOption "name" "World" "-n" "--name" "${shF_OPTION_WITH_VALUE}" "you can define your name as ${shF_COMMON_PARAMETER_NAME}." "" "110" addOption "greeting" "Hello" "-b" "--bye" "${shF_OPTION_WITH_VALUE}" "you can define greeting word as ${shF_COMMON_PARAMETER_NAME}." "" "120" if ! initConfig "$@" ; then exit 1 fi echo "${greeting}, ${name}!"
пример запуска
$ ./helloWorld.sh -b "That's all" -n "folks" That's all, folks!
Эта библиотека не ограничивается работой с параметрами коммандной строки, конфигурационными файлами и автоматической генерации описания вашего скрипта. В ней так же есть ассоциативные массивы (их не было в bash до версии 4), некоторое расширение работы с trap и unit тестирование. Конечно же у неё есть и недостатки - например скорость работы или усложнение чтения кода для непросвещённых.
[править] Дополнительная информация
Интерфейс командной строки | |
---|---|
Основы | Потоки ввода/вывода • Командная строка |
Пользовательское окружение | Оболочка интерпретатора • Приглашение командного интерпретатора • bash_completion • shopt |
Скриптинг | Скриптинг • Интерпретатор • Shebang • Shell-скриптинг • shell-framework • expect • awk • sed |