Читаем Linux API. Исчерпывающее руководство полностью

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

$ awk 'script' input-file…

Но скрипт также может находиться в файле. Например, следующий awk-скрипт выводит длину самой длинной входящей строки:

$ cat longest_line.awk

#!/usr/bin/awk

length > max { max = length; }

END { print max; }

Попытаемся запустить этот скрипт с помощью следующего кода на языке С:

execl("longest_line.awk", "longest_line.awk", "input.txt", (char *) NULL);

Этот вызов execl(), в свою очередь, запускает функцию execve(), которая выполняет команду awk со следующими аргументами:

/usr/bin/awk longest_line.awk input.txt

Данный вызов execve() завершается неудачей, поскольку awk интерпретирует строку longest_line.awk как скрипт, содержащий некорректную команду. Нам нужно как-то сообщить awk о том, что этот аргумент является именем файла со скриптом. Для этого можно воспользоваться параметром — f, указав его в качестве опционального аргумента в начальной строке скрипта. Так awk сможет понять, что в следующем аргументе находится скриптовый файл:

#!/usr/bin/awk — f

length > max { max = length; }

END { print max; }

Теперь наш вызов execl() генерирует следующий список аргументов:

/usr/bin/awk — f longest_line.awk input.txt

Это приводит к успешному запуску интерпретатора awk, который обрабатывает файл input.txt.


Выполнение скриптов с помощью вызовов execlp() и execvp()

Обычно отсутствие в скрипте начальной строки (начинающейся с #!) приводит к неудачному завершению функций exec(). Однако вызовы execlp() и execvp() ведут себя немного иначе. Как вы помните, с помощью переменной среды PATH они получают список каталогов, в которых ищется исполняемый файл. Если найденный файл действительно является исполняемым, но состоит не из бинарного кода и первая строка не начинается с символов #! эти вызовы обращаются к командной оболочке, чтобы та интерпретировала файл. В контексте Linux это означает, что такие файлы обрабатываются так, как будто начинаются с #!/bin/sh.


27.4. Дескрипторы файлов и вызовы exec()


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

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

$ ls /tmp > dir.txt

Для ее выполнения командная оболочка проделывает следующие операции.

1. Выполняется вызов fork(), который создает дочерний процесс, представляющий собой копию командной оболочки (то есть в том числе и копию команды).

2. Дочерняя командная оболочка открывает для вывода файл dir.txt, используя файловый дескриптор 1 (стандартный вывод). Это можно сделать одним из двух способов.

• Дочерняя командная оболочка закрывает дескриптор 1 (STDOUT_FILENO), после чего открывает файл dir.txt. Поскольку вызов open() всегда использует наименьший доступный номер дескриптора, а стандартный ввод (дескриптор 0) остается открытым, файл будет открыт в дескрипторе 1.

Код будет выглядеть примерно так:

fd = open("dir.txt", O_WRONLY | O_CREAT,

S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

/* rw-rw-rw- */

if (fd!= STDOUT_FILENO) {

dup2(fd, STDOUT_FILENO);

close(fd);

}

• Командная оболочка открывает файл dir.txt, получая новый файловый дескриптор. Затем, если этот дескриптор не соответствует стандартному выводу, она использует вызов dup2(), чтобы принудить стандартный вывод стать дубликатом нового дескриптора. После этого новый дескриптор закрывается за ненадобностью (этот подход является более безопасным, чем предыдущий, поскольку он не полагается на открытие дескриптора с наименьшим номером).

3. Дочерняя командная оболочка выполняет команду ls, которая записывает результат своей работы в стандартный вывод, то есть в файл dir.txt.

Приводимое здесь объяснение того, как командная оболочка выполняет перенаправление ввода/вывода, упрощает некоторые моменты. В частности, некоторые так называемые встроенные команды выполняются оболочкой напрямую, без вызовов fork() или exec(). В контексте перенаправления ввода/вывода с ними нужно работать особым образом.

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных