Основы программирования в Linux
Результат, возвращаемый функцией
, — символ следующей опции, хранящийся в массивеgetopt(если он есть). Вызывайтеargvповторно для поочередного получения каждой опции. Функция ведет себя следующим образом.getopt□ Если опция принимает значение, на него указывает внешняя переменная
.optarg□ Функция
вернет -1, когда не останется опций для обработки. Специальный аргументgetoptзаставит--прекратить перебор опций.getopt□ Функция
вернетgetopt, если есть нераспознанная опция, которую она сохранит во внешней переменной?.optopt□ Если опции требуется значение (например, в нашем примере опции
) и не задана никакая величина,-fобычно возвращаетgetopt. Если поместить двоеточие как первый символ в строке опций, при отсутствии заданной величины функция?вернетgetoptвместо:.?Во внешней переменной
хранится номер следующего обрабатываемого аргумента. Функцияoptindиспользует ее, чтобы знать, как далеко она продвинулась. Программы редко нуждаются в установке этой переменной. Когда все аргументы с опциями обработаны, переменнаяgetoptуказывает, где в конце массива argv можно найти оставшиеся аргументы.optindНекоторые версии функции
прекратят выполнение при обнаружении первого аргумента не опции, вернув значение -1 и установив переменнуюgetopt. Другие, например предлагаемые в ОС Linux, могут обрабатывать опции, где бы они ни встретились в аргументах программы. Учтите, что в данном случаеoptindфактически перепишет массивgetoptтак, что все аргументы не опции будут собраны вместе, начиная с элемента массиваargv. В случае версии GNU функцииargv[optind]ее поведение определяется переменной окруженияgetopt. Если переменная установлена,POSIXLY_CORRECTостановится на первом аргументе не опции. Кроме того, некоторые реализацииgetoptвыводят сообщения об ошибке для незнакомых опций. Имейте в виду, что в стандарте POSIX написано о том, что если переменнаяgetoptне равна нулю, функция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);}Теперь, когда вы выполните программу, то увидите, что все аргументы командной строки обрабатываются автоматически:
$ <b>./argopt -i -lr 'hi there' -f fred.с -q</b>option: ioption: loption: rfilename: fred.cunknown option: qargument: hi thereКак это работает
Программа многократно вызывает функцию
для обработки аргументов-опций до тех пор, пока не останется ни одного, в этот моментgetoptвернет -1. Для каждой опции выбирается подходящее действие, включая обработку неизвестных опций и пропущенных значений. Если у вас другая версияgetopt, то вы получите вывод, слегка отличающийся от показанного, — особенно сообщения об ошибках — но смысл будет понятен.getoptКогда все опции обработаны, программа просто выводит оставшиеся аргументы, как и раньше, но начиная с номера, хранящегося в переменной
.optindgetopt_long
Многие приложения Linux принимают более информативные аргументы, чем использованные в предыдущем примере односимвольные опции. Библиотека С проекта GNU содержит версию функции
, названнуюgetopt, которая принимает так называемые длинные аргументы, которые вводятся с помощью двойного дефиса.getopt_longРассмотрим упражнение 4.3.
Упражнение 4.3. Функцияgetopt_longПримените функцию
для создания новой версии примера программы, которая может вызываться с использованием длинных эквивалентов опций, например, следующих:getopt_long$ <b>./longopt --initialize --list 'hi there' --file fred.c -q</b>option: ioption: lfilename: fred.c./longopt: invalid option --q