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

на главную - закладки

Жанры

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

Еще один недостаток некоторых программ — создание опции

+x
(например) для выполнения функции, противоположной
– х
. В главе 2 мы применяли команду
set -о xtrace
для включения отслеживания действий командной оболочки и команду
set +о xtrace
для выключения этого режима.

Вы, вероятно, можете сказать, что запомнить порядок и назначение всех этих программных опций достаточно трудно без необходимости освоения вызывающих идиосинкразию форматов. Часто единственный выход — применение опции

– h
(от англ. help) или страниц интерактивного справочного руководства (
man
), если программист предоставил
одну из этих возможностей. Чуть позже в этой главе мы покажем, что функция
getopt
предоставляет изящное решение этих проблем. А сейчас, тем не менее, в упражнении 4.1 давайте посмотрим, как передаются аргументы программы.

Упражнение 4.1. Аргументы программы

Далее приведена программа args.c, проверяющая собственные аргументы.

#include <stdio.h>

#include <stdlib.h>

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
.

getopt

Для того чтобы вам легче было следовать правилам, приведенным в этих руководствах, ОС Linux предлагает очень простое в применении средство

getopt
, поддерживающее использование опций со значениями и без них.

#include <unistd.h>

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
вернет
:
вместо
?
.

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

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) {

Поделиться:
Популярные книги

Дважды одаренный. Том IV

Тарс Элиан
4. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
7.00
рейтинг книги
Дважды одаренный. Том IV

Вперед в прошлое 5

Ратманов Денис
5. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 5

Спасите меня, Кацураги-сан!

Аржанов Алексей
1. Токийский лекарь
Фантастика:
городское фэнтези
попаданцы
дорама
5.00
рейтинг книги
Спасите меня, Кацураги-сан!

Тихие ночи

Владимиров Денис
2. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Тихие ночи

Требую развода! Что значит- вы отказываетесь?

Мамлеева Наталья
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Требую развода! Что значит- вы отказываетесь?

Идеальный мир для Лекаря 13

Сапфир Олег
13. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 13

Отщепенец

Ермоленков Алексей
1. Отщепенец
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Отщепенец

Матабар V

Клеванский Кирилл Сергеевич
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар V

Идеальный мир для Лекаря 25

Сапфир Олег
25. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 25

Ермак. Противостояние. Книга одиннадцатая

Валериев Игорь
11. Ермак
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Ермак. Противостояние. Книга одиннадцатая

Вечный. Книга I

Рокотов Алексей
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга I

Железный Воин Империи

Зот Бакалавр
1. Железный Воин Империи
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Железный Воин Империи

Фиктивный брак

Завгородняя Анна Александровна
Фантастика:
фэнтези
6.71
рейтинг книги
Фиктивный брак

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3