Вызов командного интерпретатора shell из программ на языке Си

Назначение утилита make и изучение порядка написания простейших make-файлов. Описание синтаксиса вызова командного интерпретатора shell. Определение правил формирования и средства разбора командных строк утилита make. Пример использования функции getopt.

Рубрика Программирование, компьютеры и кибернетика
Вид лабораторная работа
Язык русский
Дата добавления 27.11.2013
Размер файла 22,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

1

Вызов командного интерпретатора shell из программ на языке Си

командная строка интерпретатор утилит make

Цель работы: знакомство с утилитой make, получение навыка написания простейших make-файлов

Назначение программы make

Язык shell:

В ряде случаев возникает задача вызова командного интерпретатора shell из программных единиц на языках высокого уровня и в первую очередь из программ на языке C.

Рассмотрим общий синтаксис вызова командного интерпретатора shell.

Вызов командного интерпретатора shell

Вызов командного интерпретатора shell осуществляется командой

sh [опция...] [командный_файл [аргумент ...]]

или

sh -c [опция...] командная_цепочка

[имя_команды [аргумент ...]]

или

sh -s [опция...] [аргумент ...]

В первом случае интерпретируется заданный командный файл (или содержимое стандартного ввода, если файл не указан), во втором - цепочка символов, в третьем команды читаются со стандартного ввода.

Большинство опций команд sh и set (см. выше) совпадают. Им может предшествовать не только знак минус, но и плюс, что означает инвертирование их смысла. Из специфических опций команды sh выделим -i, предписывающую считать shell интерактивным. Shell будет интерактивным и тогда, когда команды читаются со стандартного ввода, направленного, как и стандартный протокол, на терминал.

Заданные в командной строке аргументы становятся значениями фактических аргументов $1, $2 и т.д. Если при наличии опции -c задано имя_команды, то в результате интерпретации командной цепочки оно становится значением $0.

Пример. Команда

sh -c 'echo $0 $1 $2' a b c

выдаст на стандартный вывод

a b c

Читателю предлагается самостоятельно определить, что выдаст на стандартный вывод похожая команда

sh -c "echo $0 $1 $2" a b c

(вместо одиночных кавычек для экранирования пробелов использованы двойные), и объяснить полученный результат.

Командный интерпретатор можно вызвать и из программы на языке C, воспользовавшись функциями system() или popen()

#include <stdlib.h>

int system (const char *command);

#include <stdio.h>

FILE *popen (const char *command,

const char *mode);

Листинг 2.30. Описание функций system() и popen().

Аргумент command язык shell трактует как командную цепочку в вызове sh -c command

и может содержать имя и аргументы любой выполнимой программы. При обращении к system() вызвавшая программа ожидает завершения выполнения переданной команды, а затем продолжает выполнение со следующего выполняемого оператора. Возвращаемое функцией system() значение - код завершения shell. Пример вызова функции system():

code = system

("cd /usr/bin; ./ls > /tmp/lst");

Функция popen(), как и system(), вызывает выполнение указанной команды. Отличие в том, что при использовании функции popen() создается канал между вызвавшей ее программой и командой. Аргумент mode определяет, что программа будет делать с этим каналом: читать ("r") или писать ("w").

Правила формирования и средства разбора командных строк

К теме командного языка и его интерпретатора логически примыкают правила формирования и средства разбора командных строк.

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

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

1. Имя утилиты состоит не менее чем из двух и не более чем из девяти малых латинских букв и/или цифр.

2. Имя опции - это один буквенно-цифровой символ. Опциям предшествует знак минус. После одного минуса могут располагаться несколько опций без аргументов.

3. Опции отделены от своих аргументов.

4. У опций нет необязательных аргументов.

5. Если у опции несколько аргументов, они представляются одним словом и отделяются друг от друга запятыми или экранированными пробелами.

6. Все опции располагаются в командной строке перед операндами.

7. Специальный элемент командной строки --, который не является ни опцией, ни операндом, обозначает конец опций. Все последующие слова трактуются как операнды, даже если они начинаются со знака минус.

8. Порядок разных опций в командной строке не имеет значения. Если повторяется одна опция с аргументами, последние должны интерпретироваться в порядке, указанном в командной строке.

9. Порядок интерпретации операндов может зависеть от утилиты.

10. Если операнд задает читаемый или записываемый файл, то знак минус на его месте используется только для обозначения стандартного ввода (или стандартного вывода, если из контекста ясно, что специфицируется выходной файл).

Стандартным средством разбора опций и их аргументов, заданных в командной строке, является служебная программа getopts (чаще всего реализуемая как обычная встроенная команда shell):

getopts цепочка_имен_опций переменная

[аргумент ...]

Как правило, shell-процедура, запущенная разбираемой командной строкой, вызывает утилиту getopts многократно (в цикле). При каждом таком вызове getopts помещает имя очередной выделенной ею опции в качестве значения заданной переменной. Место продолжения разбора (индекс в командной строке) запоминается в shell-переменной OPTIND, начальным значением которой служит единица.

Если у опции должен быть аргумент (что обозначается двоеточием после имени опции в цепочке имен опций), getopts выделяет его из командной строки и помещает в shell-переменную OPTARG.

Заданную при вызове getopts переменную, а также OPTIND и OPTARG следует использовать в качестве локальных, они не должны экспортироваться в окружение.

Если при вызове getopts указаны аргументы, разбираются они, а не элементы упомянутой выше командной строки.

Когда в командной строке обнаруживается опция, отсутствующая в цепочке имен опций, значением заданной переменной становится знак вопроса. Если первый символ цепочки имен опций - двоеточие, то в OPTARG помещается обнаруженный символ, иначе в стандартный протокол выдается диагностическое сообщение. С точки зрения shell-процедуры, вызвавшей getopts, это должно считаться ошибкой; с точки зрения getopts - нет.

По достижении конца опций утилита getopts возвращает положительный код завершения, а в OPTIND помещается номер первого элемента командной строки, не являющегося опцией.

Если переменой OPTIND присваивается единица, осуществляется (новый) разбор текущей командной строки (сформированной, быть может, с помощью специальной встроенной команды set) или текущих значений заданных при вызове getopts аргументов.

В качестве примера использования служебной программы getopts рассмотрим фрагмент shell-процедуры cmd, где производится разбор заданных при ее вызове опций (см. листинг 2.31).

while getopts :abo: c

do

case $c in

a | b) FLAG=$c;;

o) OARG=$OPTARG;;

?) printf "Использование: %s: [-a | -b] [-o выходной_файл] [аргумент ...]\n" $0

exit 1;;

esac

done

shift $(($OPTIND - 1))

printf "Заданный флаг: %s\n" $FLAG

printf "Аргумент опции o: %s\n" $OARG

printf "Остаток командной строки: %s\n" "$*"

Листинг 2.31. Пример использования служебной программы getopts.

Если вызвать shell-процедуру cmd любым из способов, показанных в листинге 2.32, будет выдан результат, приведенный в листинге 2.33.

cmd -a -o f1.o,f2.o file1 -

cmd -ba -o f1.o,f2.o -- file1 -

cmd -o f1.o,f2.o -b -a file1 -

Листинг 2.32. Возможные варианты вызова shell-процедуры, использующей служебную программу getopts.

Заданный флаг: a

Аргумент опции o: f1.o,f2.o

Остаток командной строки: file1 -

Листинг 2.33. Возможный результат работы shell-процедуры, использующей служебную программу getopts.

Для разбора опций и их аргументов средствами языка C служит функция getopt() и ассоциированные с ней внешние переменные (см. листинг 2.34).

#include <unistd.h>

int getopt (int argc, char *const argv[],

const char *optstring);

extern char *optarg;

extern int optind, opterr, optopt;

Листинг 2.34. Описание функции getopt() и ассоциированных с ней внешних переменных.

В общем и целом логика ее работа та же, что и у служебной программы getopts (с соответствующим переименованием используемых переменных). Аргументы argc и argv задают командную строку в том виде, как она передается функции main(), optstring представляет собой цепочку имен опций. Переменная optind (с начальным значением 1) служит индексом в массиве argv []. Стандарт POSIX-2001 не специфицирует, как именно getopt() разбирает несколько расположенных поочередно (после одного знака минус) имен опций и определяет, какие опции уже обработаны.

В итоге функция getopt() возвращает имя очередной опции из числа перечисленных в цепочке optstring (если таковое удалось выделить). При наличии у опции аргумента указатель на него помещается в переменную optarg с соответствующим увеличением значения optind.

Если у опции аргумент отсутствует, а на первом месте в optstring задано двоеточие, оно и служит результатом.

Если встретилось имя опции, не перечисленное в optstring, или у опции нет аргумента, а на первом месте в optstring задано не двоеточие, то результатом станет знак вопроса.

В любой из перечисленных выше ошибочных ситуаций в переменную optopt помещается имя "проблемной" опции. Кроме того, в стандартный протокол выдается диагностическое сообщение по образу и подобию утилиты getopts. Для подавления выдачи следует присвоить переменной opterr нулевое значение.

Наконец, если при вызове getopt() указатель argv [optind] не отмечает начало опции (например, он пуст или первый символ указуемой цепочки отличен от знака минус), результат равен -1 как признак того, что разбор опций закончен.

Следующий пример программы (см. листинг 2.35) возвращает нас к рассмотренной выше shell-процедуре cmd. Он показывает, как можно обработать командную строку вызова утилиты, допускающей взаимоисключающие опции a и b, а также опцию o, которая должна иметь аргумент.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* Программа разбирает опции вызвавшей ее командной строки */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include <unistd.h>

#include <stdio.h>

int main (int argc, char *argv []) {

int c; /* Имя анализируемой опции */

int aflg = 0; /* Признак того, что задана опция a */

int bflg = 0; /* Признак того, что задана опция b */

int errflg = 0; /* Флаг наличия ошибки в командной строке */

int flg = '?'; /* Флаг (a или b), заданный в командной строке */

char *ofile = NULL; /* Указатель на аргумент опции o */

/* Подавим стандартную диагностику */

/* независимо от первого символа */

/* цепочки имен опций */

opterr = 0;

while ((c = getopt (argc, argv, ":abo:")) != -1) {

switch (c) {

case 'a':

aflg++;

flg = c;

if (bflg) {

fprintf (stderr, "Опции a и b несовместимы\n");

errflg++;

}

break;

case 'b':

bflg++;

flg = c;

if (aflg) {

fprintf (stderr, "Опции a и b несовместимы\n");

errflg++;

}

break;

case 'o':

ofile = optarg;

break;

case ':':

fprintf (stderr, "Отсутствует аргумент опции -%c\n", optopt);

errflg++;

break;

case '?':

fprintf (stderr, "Недопустимая опция -%c\n", optopt);

errflg++;

break;

}

}

if (errflg) {

(void) fprintf (stderr, "Использование: %s: [-a | -b] [-o выходной_файл] "

"[аргумент ...]\n", argv [0]);

return (1);

}

printf ("Заданный флаг: %c\n", flg);

printf ("Аргумент опции o: %s\n", ofile);

printf ("Остаток командной строки:");

for (; optind < argc; optind++) {

printf (" %s", argv [optind]);

}

printf ("\n");

return 0;

}

Листинг 2.35. Пример использования функции getopt().

Приведенная программа отличается от shell-процедуры cmd более тщательным анализом ошибочных ситуаций и детальной диагностикой.

Размещено на Allbest.ru


Подобные документы

  • Базовые инструменты Linux Shell и Make. Скриптовый язык Shell. Make как утилита, автоматизирующая процесс преобразования файлов из одной формы в другую. Встраиваемые системы Buildroot и OpenWrt на базе Linux. Переменные и блоки define BuildPackage.

    курсовая работа [27,4 K], добавлен 19.01.2016

  • Анализ различных командных интерпретаторов. Разработка структуры программы на языке программирования С и ее алгоритма. Требования для работы с ней. Действия, необходимые для её запуска и функционирования. Описание функций translate, sozd, info и f.

    курсовая работа [238,2 K], добавлен 06.12.2014

  • Аналитический обзор существующих программ-редакторов схем (Microsoft Office Visio 2007, FCEditor, редактор блок-схем). Математическое описание программы и её интерпретатора. Описание системы и руководство пользователя, XML и текст редактора схем.

    дипломная работа [2,1 M], добавлен 07.07.2012

  • Особенности графической среды разработки и Visual C++. Разработка проекта с использованием функций библиотеки MFC для удаления комментариев из текстов программ, автоматического выбора языка, на котором написана утилита и сохранения результата в файл.

    курсовая работа [22,7 K], добавлен 07.11.2010

  • Назначение системного программного обеспечения и его классификация. Операционные системы и их виды. Краткая характеристика сервисного ПО. Утилита - компьютерная программа, расширяющая ОС, ее функции, примеры. Работа с табличным процессором MS Excel.

    контрольная работа [668,6 K], добавлен 27.07.2010

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

    презентация [1,4 M], добавлен 24.01.2014

  • BIOS как базовая система ввода-вывода, его внутренняя структура и основные элементы, модуль расширения и его задачи. Базовый модуль DOS. Функции командного процессора. Утилиты: понятие и содержание, особенности функционирования, главные цели и задачи.

    презентация [219,7 K], добавлен 13.08.2013

  • Разработка программы-интерпретатора, способной получать на входе текстовый файл (в формате ASCII или ANSI) с текстом программы и на выходе выводить на экран результаты вычислений, определяемых программистом. Выбор лексем, интерфейс и листинг программы.

    курсовая работа [132,0 K], добавлен 12.03.2013

  • Эволюция развития персональных компьютеров и программного обеспечения. Переменные и подстановка их значений. Синтаксис языка shell. Подстановка результатов выполнения команд. Структура реестра Windows NT/2000. MS-DOS: ввод информации с клавиатуры.

    контрольная работа [377,9 K], добавлен 22.11.2013

  • Структура данных с указанием типов. Общая структурная схема программы. Алгоритмы сортировки вставками. Назначение make-файла. Функции управления программой; перемещения и корректировки введенных данных и их удаления справочника, загрузки данных из файла.

    курсовая работа [1,3 M], добавлен 12.01.2016

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.