Чтение онлайн

ЖАНРЫ

Основы программирования в Linux
Шрифт:

Например, для обработки предыдущего примера можно было бы применить следующий вызов:

getopt(argc, argv, "if:lr");

В нем учтены простые опции

– i
,
– l
,
– r
и
– f
, за которыми последует аргумент с именем файла. Вызов команды с теми же параметрами, но указанными в другом порядке, изменит поведение. Вы сможете попробовать сделать это, когда получите пример кода из упражнения 4.2.

Результат, возвращаемый функцией

getopt
, — символ следующей опции, хранящийся в массиве
argv
(если он есть). Вызывайте
getopt
повторно для поочередного получения каждой опции. Функция
ведет себя следующим образом.

 Если опция принимает значение, на него указывает внешняя переменная

optarg
.

Функция

getopt
вернет -1, когда не останется опций для обработки. Специальный аргумент 
– -
заставит
getopt
прекратить перебор опций.

 Функция

getopt
вернет
?
, если есть нераспознанная опция, которую она сохранит во внешней переменной
optopt
.

Если опции требуется значение (например, в нашем примере опции

– f
) и не задана никакая величина,
getopt
обычно возвращает
?
. Если поместить двоеточие как первый символ в строке опций, при отсутствии заданной величины функция
getopt
вернет
:
вместо
?
.

Во внешней переменной

optind
хранится номер следующего обрабатываемого аргумента. Функция
getopt
использует ее, чтобы знать, как далеко она продвинулась. Программы редко нуждаются в установке этой переменной. Когда все аргументы с опциями обработаны, переменная
optind
указывает, где в конце массива argv можно найти оставшиеся аргументы. 

Некоторые версии функции

getopt
прекратят выполнение при обнаружении первого аргумента не опции, вернув значение -1 и установив переменную
optind
. Другие, например предлагаемые в ОС Linux, могут обрабатывать опции, где бы они ни встретились в аргументах программы. Учтите, что в данном случае
getopt
фактически перепишет массив
argv
так, что все аргументы не опции будут собраны вместе, начиная с элемента массива
argv[optind]
. В случае версии GNU функции
getopt
ее поведение определяется переменной окружения
POSIXLY_CORRECT
. Если переменная установлена,
getopt
остановится на первом аргументе не опции. Кроме того, некоторые реализации
getopt
выводят сообщения об ошибке для незнакомых опций. Имейте в виду, что в стандарте POSIX написано о том, что если переменная
opterr
не равна нулю, функция
getopt
выведет сообщение об ошибке в
stderr
.

Итак, выполните упражнение 4.2.

Упражнение 4.2. Функция
getopt
 

В этом упражнении вы используете функцию getopt; назовите новую программу argopt.c.

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

int main(int argc, char *argv[]) {

 int opt;

 while ((opt = getopt(argc, argv, ":if:lr")) != -1) {

switch(opt) {

case 'i':

case 'l':

case 'r':

printf("option: %c\n", opt);

break;

case 'f':

printf("filename: %s\n", optarg);

break;

case ':':

printf("option needs a value\n");

break;

case '?':

printf("unknown option: %c\n", optopt);

break;

}

 }

 for (; optind < argc; optind++)

printf("argument: %s\n", argv[optind]);

 exit(0);

}

Теперь,

когда вы выполните программу, то увидите, что все аргументы командной строки обрабатываются автоматически:

$ ./argopt -i -lr 'hi there' -f fred.с -q

option: i

option: l

option: r

filename: fred.c

unknown option: q

argument: hi there

Как это работает

Программа многократно вызывает функцию

getopt
для обработки аргументов-опций до тех пор, пока не останется ни одного, в этот момент
getopt
вернет -1. Для каждой опции выбирается подходящее действие, включая обработку неизвестных опций и пропущенных значений. Если у вас другая версия
getopt
, то вы получите вывод, слегка отличающийся от показанного, — особенно сообщения об ошибках — но смысл будет понятен.

Когда все опции обработаны, программа просто выводит оставшиеся аргументы, как и раньше, но начиная с номера, хранящегося в переменной

optind
.

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

Поделиться с друзьями: