Еще один недостаток некоторых программ — создание опции +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
вернет :
вместо ?
.
Читать дальше