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

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

Жанры

Linux программирование в примерах
Шрифт:

183 if (optc == 'u')

184 putenv(optarg); /* Требуется GNU putenv. */

185

186 if (optind !=argc && !strcmp(argv[optind], "-")) /* Пропустить опции */

187 ++optind;

188

189 while (optind < argc && strchr(argv[optind], '=')) /* Установить

переменные окружения * /

190 putenv(argv[optind++]);

191

192 /* Если программа не указана, напечатать переменные окружения и выйти. */

193 if (optind == argc)

194 {

195 while (*environ)

196 puts (*environ++);

197 exit(EXIT_SUCCESS);

198 }

Строки 174–179

переносят существующие переменные в новую копию окружения. В глобальную переменную
environ
помещается указатель на пустой локальный массив. Параметр
envp
поддерживает доступ к первоначальному окружению.

Строки 181–184 удаляют переменные окружения, указанные в опции

– u
. Программа осуществляет это, повторно сканируя командную строку и удаляя перечисленные там имена. Удаление переменных окружения основывается на обсуждавшейся ранее особенности GNU
putenv
: при вызове с одним лишь именем переменной (без указанного значения)
putenv
удаляет ее из окружения.

После опций в командной строке помещаются новые или замещающие переменные окружения. Строки 189–190 продолжают сканирование командной строки, отыскивая установки переменных окружения в виде '

имя=значение
'.

По достижении строки 192, если в командной строке ничего не осталось, предполагается, что

env
печатает новое окружение и выходит из программы. Она это и делает (строки 195–197).

Если остались аргументы, они представляют имя команды, которую нужно вызвать, и аргументы для передачи этой новой команде. Это делается с помощью системного вызова

execvp
(строка 200), который замещает текущую программу новой. (Этот вызов обсуждается в разделе 9.1.4 «Запуск новой программы: семейство
exec
»; пока не беспокойтесь о деталях.) Если этот вызов возвращается в текущую программу, он потерпел неудачу. В таком случае
env
выводит сообщение об ошибке и завершает программу.

200 execvp(argv[optind], &argv[optind]);

201

202 {

203 int exit_status = (errno == ENOENT ? 127 : 126);

204 error(0, errno, "%s", argv[optind]);

205 exit(exit_status);

206 }

207 }

Значения кода завершения

126
и
127
(определяемые в строке 203) соответствуют стандарту POSIX.
127
означает, что программа, которую
execvp
попыталась запустить, не существует. (
ENOENT
означает, что файл не содержит записи в каталоге.)
126
означает, что файл существует, но была какая-то другая ошибка.

2.5. Резюме

• Программы на С получают аргументы своей командной строки через параметры

argc
и
argv
. Функция
getopt
предоставляет стандартный способ для последовательного разбора опций и их аргументов GNU версия
getopt
предоставляет некоторые расширения, a
getopt_long
и
getopt_long_only
дает возможность легкого разбора длинных опций.

• Окружение представляет собой набор пар '

имя=значение
', который каждая программа наследует от своего родителя. Программы могут по прихоти своего автора использовать для изменения своего поведения переменные окружения, в дополнение к любым аргументам командной строки. Для получения значений переменных окружения, изменения их значений или удаления существуют стандартные процедуры (
getenv
,
setenv
,
putenv
и
unsetenv
).
При необходимости можно получить доступ ко всему окружению через внешнюю переменную
environ
или через третий аргумент
char **envp
функции
main
. Последний способ не рекомендуется.

Упражнения

1. Предположим, что программа принимает опции

– a
,
– b
и
– с
, и что
– b
требует наличия аргумента. Напишите для этой программы код ручного разбора аргументов без использования
getopt
или
getopt_long
. Для завершения обработки опций принимается
– -
. Убедитесь, что -ас работает, также, как
– bYANKEES
,
– b YANKEES
и
– abYANKEES
. Протестируйте программу.

2. Реализуйте

getopt
. Для первой версии вы можете не беспокоиться насчет случая '
optstring[0] == ':'
'. Можете также игнорировать
opterr
.

3. Добавьте код для '

optstring[0] == ':'
' и
opterr
к своей версии
getopt
.

4. Распечатайте и прочтите файлы GNU

getopt.h
,
getopt.с
и
getopt1.с
.

5. Напишите программу, которая объявляет как

environ
, так и
envp
, и сравните их значения.

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

getopt
и
getopt_long
, такими, как:

 • библиотека анализа аргументов Plan 9 From Bell Labs arg(2) [31] ,

 • Argp [32] ,

 • Argv [33] ,

31

http://plan9.bell-labs.com/magic/man2html/2/arg
Примеч. автора.

32

http://www.gnu.org/manual/glibc/html_node/Argp.html
Примеч. автора.

33

http://256.com/sources/argv
Примеч. автора.

 • Autoopts [34] ,

 • GNU Gengetopt [35] ,

 • Opt [36] ,

 • Popt [37] . См. также справочную страницу popt(3) системы GNU/Linux.

7. Дополнительный балл, почему компилятор С не может полностью игнорировать ключевое слово register? Подсказка: какие действия невозможно совершать с регистровой переменной?

34

http://autogen.sourceforge.net/autoopts.html
Примеч. автора.

35

ftp://ftp.gnu.org/gnu/gengetopt/
Примеч. автора.

36

http://nis-www.lanl.gov/~jt/Software/opt/opt-3.19.tar.gz
Примеч. автора.

37

http://freshmeat.net/projects/popt/?topic_id=809
Примеч. автора.

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

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Сердце для стража

Каменистый Артем
5. Девятый
Фантастика:
фэнтези
боевая фантастика
9.20
рейтинг книги
Сердце для стража

Жандарм 3

Семин Никита
3. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 3

Жена на пробу, или Хозяйка проклятого замка

Васина Илана
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Жена на пробу, или Хозяйка проклятого замка

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

Неучтенный. Дилогия

Муравьёв Константин Николаевич
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Неучтенный. Дилогия

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Бастард Императора. Том 4

Орлов Андрей Юрьевич
4. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 4

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII

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

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

Камень. Книга 3

Минин Станислав
3. Камень
Фантастика:
фэнтези
боевая фантастика
8.58
рейтинг книги
Камень. Книга 3

Матабар

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