Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Программирование и алгоритмические языки в Linux

Обработка аргументов командной строки с помощью process-getopt

Оригинал: Command-Line Processing with 'process-getopt'
Автор: Боб Хэппл (Bob Hepple)
Дата: май 2009 г.
Перевод: Сергей Супрунов
Дата перевода: 30 мая 2009 г.

Вы знаете, что должны...

... "вылизывать" свои bash-скрипты так же, как ваш код на C, но почему-то на это никогда не хватает времени. Если ими будете пользоваться только вы, то можно особо не беспокоиться - до тех пор, пока вы не забудете, что делает скрипт foobar и не запустите foobar -h. Вот чёрт, теперь вспомнил - -h означает "halt" и останавливает работу! Упс...

Эта статья посвящена простому способу привести ваши скрипты в порядок, чтобы их работа была предсказуема, а опции и аргументы соответствовали соглашениям, принятым в Unix. Но сперва обсудим те проблемы, с которыми обычно сталкивается разработчик на bash.

Если ваши скрипты используют другие люди или если вы не можете полагаться на свою память (не переживайте - в один из прекрасных дней это обязательно случится), тогда становится настоящим мучением предусмотреть ответ на любой возможный ввод - а некоторые люди весьма изобретательны, "ломая" работу вашего скрипта синтаксисом, который вы и представить не можете.

Далее возникает вопрос соответствия стандартам. Вы вообще в курсе, что для подобных вещей существует стандарт GNU?

Например, поддерживает ли ваш скрипт "длинные" опции (--verbose) наряду с "короткими" (-V)? Длинные опции обеспечивают "самодокументируемость" скрипта, короткие удобны опытным пользователям (и тем из нас, кто до сих пор сидит за экранным терминалом).

Адекватно ли реагирует ваш скрипт на пробелы между опциями и их аргументами? Например, -n 123 должно восприниматься так же, как -n123, --number 123 и --number=123.

Можно ли задавать "длинные" опции с сокращением до уникальной подстроки, например, --numb как сокращение для --number?

Можно ли объединять "короткие" опции вместе, например, -t -s -u задавать как -tsu?

Предусмотрено ли отображение справки по -h, --help (на стандартный вывод stdout, будьте любезны, чтобы пользователь мог передать его по конвейеру программе просмотра типа less)?

А как насчёт -v, --verbose или -V, --version? ... и так далее. Пользователи (ладно, пользователи, постигшие Unix) ожидают, что это будет работать - так что следование этим соглашениям всем упрощает жизнь.

Но это действительно утомительно и очень сложно - добиться, чтобы всё работало правильно, когда вы пишете свой bash-код, и неудивительно, что так мало скриптов в конечном итоге получаются "пользователеустойчивыми".

Особенно мучительным это становится, когда вы начинаете такой код сопровождать. Даже при помощи getopt это может быть трудно (синтаксис getopt сам по себе довольно запутанный), поскольку структура команды getopt требует от вас повторять буквы и строки опций в трёх местах:

  • вызов getopt
  • оператор case, обрабатывающий эти опции
  • страницы справки и man

Из-за этого ошибкам гораздо проще проникнуть в ваш код.

Решение

В компилируемых языках существуют функции-обёртки для getopt(3), что позволяет значительно упростить работу и снизить вероятность ошибок при написании подобного кода. Среди них - argp(3) разработки GNU и popt(3) от Red Hat.

На Python можно использовать модуль OptionParse.

Для скриптов на bash ничего подобного нет с тех пор, как "застопорился" проект getoptx. Но во всех своих скриптах последние несколько лет я использую собственную библиотеку: process-getopt. Это "обёртка" к getopt, значительно упрощающая жизнь разработчикам на bash и тем, кто эти скрипты сопровождает и использует.

В качестве примера приведу крошечный скрипт, использующий её для обработки командной строки:

И всё. Вот вывод, который вы получаете без какого-либо дополнительного кода:

$ tiny --help 
Usage: tiny [-shVvq-] [--slot --help --version --verbose --quiet] [-t ,--token=] 
A tiny example 

Options: 
  -s, --slot                boolean option 
  -t n, --token=number      this option takes a value 
  -h, --help                print this help and exit 
  -V, --version             print version and exit 
  -v, --verbose             do it verbosely 
  -q, --quiet               do it quietly (negates -v) 
  --                        explicitly ends the options 

А вот пример использования опций и аргументов командной строки:

$ tiny -s --token="my token" arg1 arg2 
SLOT=yes 
TOKEN=my token 
args=arg1 arg2 

process-getopt работает с bash-2.04 и более поздними версиями, найти её можно по следующей ссылке:

http://sourceforge.net/projects/process-getopt

Переработать ваши существующие скрипты для использования process-getopt довольно просто: следуйте примерам и руководствам, которые можно найти здесь:

http://bhepple.freeshell.org/oddmuse/wiki.cgi/process-getopt

А вот - прямая ссылка на руководство:

http://bhepple.freeshell.org/scripts/process-getopt.pdf

Пользуйтесь на здоровье!


Об авторе

Боб Хэппл - самый молодой среди раздражительных стариков из Prompty Corp (Золотой Берег, Австралия), заслуживший свои нашивки юниксоида в Hewlett-Packard в 1981 году. С тех пор он работал в Азии и Австралии с различными поставщиками Unix и компаниями, специализирующимися на криптографии - но всегда только в UNIX и GNU/Linux.

Потомок землемера из северо-восточной Англии, после 30 лет проживания в "стране Оз" [Австралийцы именуют себя Aussie, что произносится как "Оззи" - отсюда и жаргонное название страны. - прим.перев.] он считает себя настоящим австралийцем, но британский акцент выдаёт его с головой.