Еще один недостаток некоторых программ — создание опции +x(например) для выполнения функции, противоположной -х. В главе 2 мы применяли команду set -о xtraceдля включения отслеживания действий командной оболочки и команду set +о xtraceдля выключения этого режима.
Вы, вероятно, можете сказать, что запомнить порядок и назначение всех этих программных опций достаточно трудно без необходимости освоения вызывающих идиосинкразию форматов. Часто единственный выход — применение опции -h(от англ. help ) или страниц интерактивного справочного руководства ( man), если программист предоставил одну из этих возможностей. Чуть позже в этой главе мы покажем, что функция getoptпредоставляет изящное решение этих проблем. А сейчас, тем не менее, в упражнении 4.1 давайте посмотрим, как передаются аргументы программы.
Упражнение 4.1. Аргументы программы
Далее приведена программа args.c, проверяющая собственные аргументы.
#include
#include
int main(int argc, char *argv[]) {
int arg;
for (arg = 0; arg < argc; arg++) {
if (argv[arg][0] == '-')
printf("option: %s\n", argv[arg]+1);
else
printf("argument %d: %s\n", arg, argv[arg]);
}
exit(0);
}
Когда вы выполните эту программу, она просто выведет свои аргументы и определит опции. Суть в том, что программа принимает строковый аргумент и необязательный аргумент с именем файла, вводимый опцией -f. Могут быть определены и другие опции.
$ ./args -i -lr 'hi there' -f fred.c
argument 0: ./args
option: i
option: lr
argument 3: hi there option: f
argument 5: fred.с
Как это работает
Программа просто использует аргумент-счетчик argcдля задания цикла, просматривающего все аргументы программы. Она находит опции поиском начального дефиса.
В данном примере, если мы предполагаем, что доступны опции -lи -r, то упускаем тот факт, что группа -lr, возможно, должна интерпретироваться так же, как -lи -r.
В стандарте X/Open (который можно найти по адресу http://opengroup.org/) определено стандартное применение опций командной строки (Utility Syntax Guidelines, руководство по синтаксису утилит) и стандартный программный интерфейс для представления переключателей командной строки в программах на языке С: функция getopt.
Для того чтобы вам легче было следовать правилам, приведенным в этих руководствах, ОС Linux предлагает очень простое в применении средство getopt, поддерживающее использование опций со значениями и без них.
#include
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
Функция getoptпринимает параметры argcи argvв том виде, в каком они передаются функции mainв программе, и строку спецификатора опций, которая сообщает getopt, какие опции определены для программы и есть ли у них связанные с ними значения. optstring— это просто список символов, каждый из которых представляет односимвольную опцию. Если за символом следует двоеточие, это означает, что у опции есть ассоциированное значение, которое будет принято как следующий аргумент. Команда getoptоболочки bash выполняет аналогичную функцию.
Например, для обработки предыдущего примера можно было бы применить следующий вызов:
getopt(argc, argv, "if:lr");
В нем учтены простые опции -i, -l, -rи -f, за которыми последует аргумент с именем файла. Вызов команды с теми же параметрами, но указанными в другом порядке, изменит поведение. Вы сможете попробовать сделать это, когда получите пример кода из упражнения 4.2.
Результат, возвращаемый функцией getopt, — символ следующей опции, хранящийся в массиве argv(если он есть). Вызывайте getoptповторно для поочередного получения каждой опции. Функция ведет себя следующим образом.
□ Если опция принимает значение, на него указывает внешняя переменная optarg.
□ Функция getoptвернет -1, когда не останется опций для обработки. Специальный аргумент --заставит getoptпрекратить перебор опций.
□ Функция getoptвернет ?, если есть нераспознанная опция, которую она сохранит во внешней переменной optopt.
□ Если опции требуется значение (например, в нашем примере опции -f) и не задана никакая величина, getoptобычно возвращает ?. Если поместить двоеточие как первый символ в строке опций, при отсутствии заданной величины функция getoptвернет :вместо ?.
Читать дальше