getopt - это C библиотека функция, используемая для синтаксического анализа команды . параметры строки стиля Unix / POSIX. Он является частью спецификации POSIX и универсален для Unix-подобных систем.
Это также имя программы Unix для анализа аргументов командной строки в сценариях оболочки.
Давняя проблема с программами командной строки было как указать опции; ранние программы использовали много способов сделать это, включая односимвольные параметры (-a
), несколько параметров, указанных вместе (-abc
эквивалентно -a -b -c
), параметры с несколькими символами (-inum
), параметры с аргументами (-a arg
, -inum 3
, -a = arg
) и различные символы префикса (-a
, +b
, /c
).
Функция getopt была написана как стандартный механизм, который все программы могли бы использовать для синтаксического анализа параметров командной строки, чтобы иметь общий интерфейс, на котором все может зависеть. Таким образом, первоначальные авторы выбрали из вариантов поддержки односимвольных параметров, нескольких параметров, указанных вместе, и параметров с аргументами (-a arg
или -aarg
), и все они контролируются строка параметров.
getopt восходит как минимум к 1980 году и впервые был опубликован ATT на конференции UNIFORUM 1985 года в Далласе, штат Техас, с намерением сделать его общедоступным. Его версии впоследствии были подхвачены другими разновидностями Unix (4.3BSD, Linux и т. Д.). Он указан в стандарте POSIX.2 как часть заголовочного файла unistd.h . Производные от getopt были созданы для многих языков программирования для анализа параметров командной строки.
getopt - это системно-зависимая функция, и ее поведение зависит от реализации в библиотеке C. Однако доступны некоторые специальные реализации, такие как gnulib.
Обычная обработка (POSIX и BSD) заключается в том, что параметры заканчиваются, когда встречается первый аргумент, не являющийся параметром, и что getopt вернет -1, чтобы сигнализировать об этом. Однако в расширении glibc параметры разрешены где угодно для простоты использования; getopt неявно переставляет вектор аргументов, поэтому в конце он все равно оставляет без параметров. Поскольку в POSIX уже есть соглашение о возврате -1 в -
и его пропуске, его всегда можно переносимо использовать как указатель конца параметров.
A GNU extension, getopt_long, позволяет анализировать более читаемые, многозначные параметры, которые вводятся двумя дефисами вместо одного. Выбор двух тире позволяет отличать параметры с несколькими символами (--inum
) от параметров с одним символом, заданных вместе (-abc
). Расширение GNU также допускает альтернативный формат для параметров с аргументами: --name = arg
. Этот интерфейс оказался популярным и был принят (без разрешения) многими дистрибутивами BSD, включая FreeBSD, а также Solaris. Альтернативный способ поддержки длинных параметров можно найти в Solaris и Korn Shell (расширение optstring), но он не был так популярен.
Еще одним распространенным расширенным расширением getopt является сброс состояния синтаксического анализа аргументов; это полезно в качестве замены расширения GNU options-anyware или как способ "наслоить" набор интерфейсов командной строки с различными параметрами на разных уровнях. Это достигается в системах BSD с использованием переменной optreset, а в системах GNU путем установки для optind значения 0.
Обычной функцией-компаньоном для getopt
является getsubopt.
. Он анализирует строку подпараметров, разделенных запятыми.
Синтаксис командной строки для программ на основе getopt - это рекомендуемый POSIX аргумент утилиты Синтаксис. Вкратце:
-
(дефис-минус).o
принимает аргумент, -ofoo
совпадает с -o foo
.a
и b
не принимают аргументов, а e
принимает необязательный аргумент, -abe
совпадает с -a - b -e
, но -bea
не то же самое, что -b -ea
из-за предыдущего правила.-
всегда обозначает конец параметров.Расширения синтаксиса включают соглашение GNU и спецификацию Sun CLIP.
В руководстве по getopt от GNU указано такое использование getopt:
#includeint getopt (int argc, char * const argv, const char * optstring);
Здесь argc и argv определены точно так же, как в прототипе основной функции C, т.е. argc указывает длину массива строк argv. Строка optstring содержит спецификацию того, какие параметры следует искать (обычные буквенно-цифровые символы, кроме W), и какие параметры принимать аргументы (двоеточия). Например, «vf :: o:» относится к трем параметрам: без аргументов v, необязательный-аргумент f и обязательный-аргумент o. GNU здесь реализует расширение W. для длинных синонимов параметров. Сам
getopt возвращает целое число, которое является либо символом параметра, либо -1 для конца параметров. Идиома состоит в том, чтобы использовать цикл while для просмотра параметров и использовать оператор switch-case для выбора параметров и действий с ними. См. Раздел примеров в этой статье.
Для передачи дополнительной информации программе программа обращается к нескольким глобальным переменным extern
для получения информации из getopt
:
extern char * optarg; extern int optind, opterr, optopt;
Расширение GNU интерфейс getopt_long - похоже, хотя он принадлежит другому заголовочному файлу и имеет дополнительную опцию для определения «коротких» имен длинных опций и некоторых дополнительных элементов управления. Если короткое имя не определено, getopt вместо этого поместит индекс, относящийся к структуре параметров, в указатель longindex.
#includeint getopt_long (int argc, char * const argv, const char * optstring, const struct option * longopts, int * longindex);
#include/ * для printf * / #include / * для выхода * / #include / * для getopt * / int main (int argc, char ** argv) {int c; int digit_optind = 0; int aopt = 0, bopt = 0; char * copt = 0, * dopt = 0; while ((c = getopt (argc, argv, "abc: d: 012"))! = -1) {int this_option_optind = optind? optind: 1; switch (c) {case '0': case '1': case '2': if (digit_optind! = 0 digit_optind! = this_option_optind) printf ("цифры встречаются в двух разных элементах argv. \ n"); digit_optind = this_option_optind; printf ("опция% c \ n", c); сломать; case 'a': printf ("вариант a \ n"); aopt = 1; сломать; case 'b': printf ("вариант b \ n"); bopt = 1; сломать; case 'c': printf ("вариант c со значением '% s' \ n", optarg); copt = optarg; сломать; case 'd': printf ("вариант d со значением '% s' \ n", optarg); dopt = optarg; сломать; case '?': перерыв; по умолчанию: printf ("?? getopt вернул код символа 0% o ?? \ n", c); }} if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); }
#include/ * для printf * / #include / * для выхода * / #include / * для getopt_long; getopt стандарта POSIX находится в unistd.h * / int main (int argc, char ** argv) {int c; int digit_optind = 0; int aopt = 0, bopt = 0; char * copt = 0, * dopt = 0; static struct option long_options = {/ * NAME ARGUMENT FLAG SHORTNAME * / {"add", required_argument, NULL, 0}, {"append", no_argument, NULL, 0}, {"delete", required_argument, NULL, 0}, {"verbose ", no_argument, NULL, 0}, {" create ", required_argument, NULL, 'c'}, {" file ", required_argument, NULL, 0}, {NULL, 0, NULL, 0}}; int option_index = 0 ; while ((c = getopt_long (argc, argv, "abc: d: 012", long_options, option_index))! = -1) {int this_option_optind = optind? optind: 1; switch (c) {case 0: printf ( "option% s", long_options [option_index].name); if (optarg) printf ("with arg% s", optarg); printf ("\ n"); break; case '0': case '1': case '2': if (digit_optind! = 0 digit_optind! = this_op tion_optind) printf ("цифры встречаются в двух разных элементах argv. \ n"); digit_optind = this_option_optind; printf ("опция% c \ n", c); сломать; case 'a': printf ("вариант a \ n"); aopt = 1; сломать; case 'b': printf ("вариант b \ n"); bopt = 1; сломать; case 'c': printf ("вариант c со значением '% s' \ n", optarg); copt = optarg; сломать; case 'd': printf ("вариант d со значением '% s' \ n", optarg); dopt = optarg; сломать; case '?': перерыв; по умолчанию: printf ("?? getopt вернул код символа 0% o ?? \ n", c); }} if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); }
программисты сценариев оболочки обычно хотят предоставить согласованный способ предоставления параметров. Для достижения этой цели они обращаются к getopts и стремятся перенести ее на свой язык.
Первой попыткой переноса была программа getopt, реализованная Unix System Laboratories (USL). Эта версия не могла иметь дело с цитированием и метасимволами оболочки, поскольку она не показывает попыток цитирования. Он унаследован от FreeBSD.
В 1986 году USL решила, что небезопасность в отношении метасимволов и пробелов больше не приемлема, и вместо этого они создали встроенную команду getopts для Unix SVR3 Bourne Shell. Преимущество встраивания команды в оболочку состоит в том, что теперь у нее есть доступ к переменным оболочки, поэтому значения можно безопасно записывать без кавычек. Он использует собственные переменные оболочки для отслеживания положения текущих позиций и позиций аргументов, OPTIND и OPTARG и возвращает имя параметра в переменной оболочки.
В 1995 г. getopts
был включен в Single UNIX Specification version 1 / X / Open Руководство по переносимости, проблема 4. Теперь getopts является частью стандарта POSIX Shell. и широко используется во многих других оболочках, пытающихся быть совместимыми с POSIX.
getopt был практически забыт, пока util-linux не вышел с расширенной версией, которая исправила все старые проблемы getopt путем экранирования. Он также поддерживает длинные имена опций GNU. С другой стороны, длинные параметры редко реализуются в команде getopts
в других оболочках, ksh93 является исключением.
getopt - это краткое описание общей структуры аргументов команды POSIX, и оно широко тиражируется программистами, стремящимися предоставить аналогичный интерфейс как для себя, так и для пользователя в командную строку.
getopt
в библиотеке C, но также gnulib и MinGW (оба принимают стиль GNU) в качестве дополнительных минимальных библиотек можно использовать для обеспечения функциональности. Также существуют альтернативные интерфейсы: popt
, используемая менеджером пакетов RPM, имеет дополнительное преимущество: повторно входим.Семейство функций argp
в glibc и gnulib обеспечивает дополнительное удобство и модульность.flag
, который позволяет использовать длинные имена флагов. Пакет getopt
поддерживает обработку, близкую к функции C. Существует также другой пакет getopt
, предоставляющий интерфейс, намного более близкий к исходному пакету POSIX.