Книга: Основы программирования в Linux
getopt_long
getopt_long
Многие приложения Linux принимают более информативные аргументы, чем использованные в предыдущем примере односимвольные опции. Библиотека С проекта GNU содержит версию функции getopt
, названную getopt_long
, которая принимает так называемые длинные аргументы, которые вводятся с помощью двойного дефиса.
Рассмотрим упражнение 4.3.
Упражнение 4.3. Функция getopt_long
Примените функцию getopt_long
для создания новой версии примера программы, которая может вызываться с использованием длинных эквивалентов опций, например, следующих:
$ ./longopt --initialize --list 'hi there' --file fred.c -q
option: i
option: l
filename: fred.c
./longopt: invalid option --q
unknown option: q
argument: hi there
На самом деле и новые длинные опции, и исходные односимвольные можно смешивать. Длинным опциям также можно давать сокращенные названия, но они
должны отличаться от односимвольных опций. Длинные опции с аргументом можно задавать как единый аргумент в виде --опция= значение, как показано далее:
$ ./longopt --init -l --file=fred.с 'hi there'
option: i
option: l
filename: fred.с
argument: hi there
Далее приведена новая программа longopt.c, полученная из программы argopt.c с изменениями, обеспечивающими поддержку длинных опций, которые в тексте программы выделены цветом.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define _GNU_SOURCE
#include <getopt.h>
int main(int argc, char *argv[]) {
int opt;
struct option_longopts[] = {
{"initialize", 0. NULL, 'i'},
{"file" 1, NULL, 'f'},
{"list", 0, NULL, 'l'},
{0, 0, 0, 0}};
while ((opt = getopt_long(argc, argv, ":if:lr, longopts, NULL)) != -1) {
switch(opt) {
case 'i':
case 'l':
case 'r':
printf("option: %cn", opt);
break;
case 'f':
printf("filename: %sn", optarg);
break;
case ':':
printf("option needs a valuen");
break;
case '?':
printf("unknown option: %cn", optopt);
break;
}
}
for (; optind < argc; optind++)
printf("argument: %sn", argv[optind]);
exit(0);
}
Как это работает
Функция getopt_long
принимает два дополнительных параметра по сравнению с функцией getopt
. Первый из них — массив структур, описывающий длинные опции и сообщающий функции getopt_long
способ их обработки. Второй дополнительный параметр — адрес переменной, которая может использоваться как вариант optind
, предназначенный для длинных опций; для каждой распознанной длинной опции ее номер в массиве длинных опций может быть записан в эту переменную. В данном примере вам не нужна эта информация, поэтому вы используете NULL
в качестве значения второго дополнительного параметра.
Массив длинных опций состоит из ряда структур типа struct option
, в каждой из которых описано требуемое поведение длинной опции. Массив должен заканчиваться структурой, содержащей все нули.
Структура длинной опции определена в заголовочном файле getopt.h и должна подключаться с помощью константы _GNU_SOURCE
, определенной для того, чтобы разрешить использование функции getopt_long
.
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
Элементы структуры описаны в табл. 4.1.
Таблица 4.1.
Параметр опции | Описание |
---|---|
name |
Название длинной опции. Сокращения будут приниматься до тех пор, пока они не создадут путаницы при определении названий других опций |
has_arg |
Принимает ли эта опция аргумент. Задайте 0 для опций без аргументов, 1 для опций, у которых должно быть значение, и 2 для опций с необязательным аргументом |
flag |
Задайте NULL , чтобы getopt_long вернула при обнаружении данной опции значение, заданное в val . В противном случае getopt_long возвращает 0 и записывает значение val в переменную, на которую указывает flag |
val |
Значение getopt_long для данной опции, предназначенное для возврата |
Для получения сведений о других опциях, связанных с расширениями функции getopt
в проекте GNU и родственных функциях, см. страницы интерактивного справочного руководства к функции getopt
.
- 2.1.3. Функция getopt_long()
- 5.2.1. long long
- 2.3. Разбор опций: getopt() и getopt_long()
- 2.3.3 3. Сводка возвращаемых значений getopt_long()
- 2.3.3.4. GNU getopt() или getopt_long() в программах пользователей
- Листинг 2.2. (getopt_long.c) Использование функции getopt_long()
- Действие
- Appendix I. GNU General Public License
- Where to get iptables