Текст книги "Основы программирования в Linux"
Автор книги: Нейл Мэтью
Соавторы: Ричард Стоунс
Жанры:
Программирование
,сообщить о нарушении
Текущая страница: 4 (всего у книги 67 страниц)
Получение справки
Подавляющее большинство систем Linux хорошо документировано в отношении системных программных интерфейсов и стандартных утилит. Это на самом деле так, потому что со времени первых систем UNIX программистов призывали снабжать свои приложения справочными материалами или описаниями. Эти справочные страницы (man pages), которые иногда предоставлялись в печатной форме, всегда доступны и в электронном виде.
Доступ к интерактивным справочным руководствам обеспечивает команда man
. Эти справочные руководства отличаются качеством и деталями. Одни могут просто переадресовать читателя к другой, более полной документации, в то время как другие дают полный перечень всех опций и команд, поддерживаемых утилитой. В любом случае справочные руководства – подходящий способ знакомства с приложением.
Комплект программного обеспечения проекта GNU и другое свободное ПО используют интерактивную систему документации, названную info. Вы можете просмотреть всю документацию в интерактивном режиме с помощью специальной программы info или команды info
редактора emacs. Достоинство системы info в том, что вы можете перемещаться по разделам документации с помощью связей и перекрестных ссылок, переходя непосредственно к нужному вам разделу. Для разработчика документации преимущество в том, что справочные файлы могут автоматически генерироваться из того же источника, что и печатные или набранные на клавиатуре страницы документации.
Упражнение 1.3. Справочные руководства и система info
Давайте познакомимся с документацией для компилятора GNU С (gcc).
1. Сначала посмотрим на справочное руководство.
$ man gcc
GCC(1) GNU GCC(1)
NAME
gcc – GNU project С and С++ compiler
SYNOPSIS
gcc [-с|-S|-E] [-std=standard]
[-g] [-pg] [-Olevel]
[-Wwarn...] [-pedantic]
[-Idir...] [-Ldir...]
[-Dmacro[=defn]...] [-Umacro]
[-foption...] [-mmachine-option...]
[-о outfile] infile...
Only the most useful options are listed here; see below
for the remainder. g++ accepts mostly the same options as
gcc.
DESCRIPTION
When you invoke GCC, it normally does preprocessing, com-
pilation, assembly and linking. The «overall options»
allow you to stop this process at an intermediate stage.
For example, the -c option says not to run the linker.
Then the output consists of object files output by the assembler.
Other options are passed on to one stage of processing.
Some options control the preprocessor and others the com-
piler itself. Yet other options control the assembler and
linker; most of these are not documented here, since we
rarely need to use any of them.
...
Если хотите, можно прочесть об опциях, поддерживаемых транслятором. В этом случае справочное руководство очень длинное, хотя содержит лишь малую часть полной документации по компилятору GNU С (и С++).
При чтении справочных страниц можно использовать клавишу <Пробел> для перехода к следующей странице, клавишу для полного выхода из программы.
2. Для получения более подробной информации о компиляторе GNU С можно попробовать применить команду info
.
$ info gcc
File: gcc.info. Node: Top, Next: G++ and GCC, Up: (DIR)
Introduction
************
This manual documents how to use the GNU compilers, as well as their
features and incompatibilities, and how to report bugs. It corresponds to
GCC version 4.1.3. The internals of the GNU compilers, including how to port
them to new targets and some information about how to write front ends for
new languages, are documented in a separate manual.
*Note Introduction: (gccint)Top.
*Menu:
* G++ and GCC:: You can compile С or С++ Applications.
* Standards:: Language standards supported by GCC,
* Invoking GCC:: Command options supported by `gcc'.
* С Implementation:: How GCC implements theISO С specification.
* С Extensions:: GNU extensions to the С language family.
* С++ Extensions:: GNU extensions to the С++ language.
* Objective-C:: GNU Objective-C runtime features.
* Compatibility:: Binary Compatibility
–zz-Info: (gcc.info.gz)Top, 39 lines –Top–
Welcome to Info version 4.8. Type ? for help, m for menu item.
Вам предоставляется длинное меню опций, которые можно выбирать для перемещения в полной текстовой версии документации. Элементы меню и иерархия страниц позволяют находить нужные разделы в очень большом документе. На бумаге документация к компилятору GNU С занимает многие сотни страниц.
У системы info есть собственная справка, конечно, в формате страниц info. Если нажать комбинацию клавиш
Резюме
В этой вводной главе мы познакомились с программированием в ОС Linux и другими компонентами ОС Linux, общими с патентованными системами UNIX. Мы отметили огромное разнообразие систем программирования, доступных UNIX-разработчикам. Мы также представили простые программу и библиотеку, чтобы показать базовые средства языка С и сравнить их с эквивалентными средствами в ОС Windows.
Глава 2
Программирование средствами командной оболочки
Начав книгу с программирования в ОС Linux на языке С, теперь мы сделаем отступление и остановимся на написании программ в командной оболочке. Почему? ОС Linux не относится к системам, у которых интерфейс командной строки – запоздалое детище графического интерфейса. У систем UNIX, прообраза Linux, первоначально вообще не было графического интерфейса; все выполнялось из командной строки. Поэтому оболочка командной строки UNIX все время развивалась и превратилась в очень мощный инструмент. Эти свойства перекочевали и в Linux, и некоторые самые серьезные задачи вы можете выполнить наиболее легким способом именно из командной оболочки. Поскольку она так важна для ОС Linux и столь полезна для автоматизации простых задач, программирование средствами командной оболочки рассматривается прежде всего.
В этой главе мы познакомим вас с синтаксисом, структурами и командами, доступными при программировании в командной оболочке, как правило, используя интерактивные (основанные на экранах) примеры. Они помогут продемонстрировать функциональные возможности командной оболочки и собственные действия. Мы также бросим беглый взгляд на пару особенно полезных утилит режима командной строки, часто вызываемых из командной оболочки: grep и find. Рассматривая утилиту grep, мы познакомимся с основными положениями, касающимися регулярных выражений, которые появляются в утилитах ОС Linux и языках программирования, таких как Perl, Ruby и PHP. В конце главы вы узнаете, как писать настоящие сценарии, которые будут перепрограммироваться и расширяться на языке С на протяжении всей книги. В этой главе рассматриваются следующие темы:
□ что такое командная оболочка;
□ теоретические основы;
□ тонкости синтаксиса: переменные, условия и управление программой;
□ списки;
□ функции;
□ команды и их выполнение;
□ встроенные (here) документы;
□ отладка;
□ утилита grep и регулярные выражения;
□ утилита find.
Если вы столкнулись со сложным сценарием командной оболочки при администрировании системы, хотите смоделировать вашу последнюю грандиозную (но удивительно простую) идею или просто повысить производительность какой-либо итеративной задачи, эта глава вам будет полезна.
Почему программа в командной оболочке?
Одна из причин применения командной оболочки – возможность быстрого и простого программирования. Более того, командная оболочка всегда есть даже в самых упрощенных установках ОС Linux, поэтому благодаря простому моделированию вы сможете понять, работает ли ваша идея. Командная оболочка очень удобна и для небольших утилит, выполняющих относительно простую задачу, для которой производительность менее важна, чем простые настройка, сопровождение и переносимость. Вы можете применять оболочку для управления процессами, обеспечивая выполнение команд в заданном порядке, зависящем от успешного завершения каждого этапа выполнения.
Хотя внешне командная оболочка очень похожа на режим командной строки в ОС Windows, она гораздо мощнее и способна выполнять самостоятельно очень сложные программы. Вы можете не только выполнять команды и вызывать утилиты ОС Linux; но и разрабатывать их. Командная оболочка выполняет программы оболочки, часто называемые сценариями или скриптами, которые интерпретируются во время выполнения. Такой подход облегчает отладку, потому что вы легко можете выполнять программу построчно и не тратить время на перекомпиляцию. Но для задач, которым важно время выполнения или необходимо интенсивное использование процессора, командная оболочка оказывается неподходящей средой.
Немного теории
Вот мы и добрались до теоретических основ UNIX и, конечно, Linux. ОС UNIX основана на интенсивном многократном применении кода и зависит от него. Вы разработали маленькую простую утилиту, и пользователи применяют ее как одну из ссылок в строке, формирующей команду. Одно из наслаждений, доставляемых ОС Linux, – разнообразие имеющихся отличных средств. Примером может служить следующая команда:
$ ls -al | more
Эта команда применяет утилиты ls
и more
и передает вывод списка файлов для поэкранного отображения. Каждая утилита – это отдельный блок. Зачастую вы можете применять множество мелких утилит для создания больших и сложных комплексов программ.
Например, если вы хотите напечатать контрольную копию справочного руководства оболочки bash, примените следующую команду:
$ man bash | col -b | lpr
Более того, благодаря автоматической обработке типов файлов пользователям этих утилит обычно не нужно знать, на каком языке данные программы написаны. Если необходимо ускорить выполнение утилиты, как правило, ее сначала моделируют в командной оболочке и затем, когда работоспособность утилиты проверена, реализуют ее на языке С или С++, Perl, Python или каком-либо другом, обеспечивающем более быстрое выполнение. В противном случае, если в командной оболочке утилита действует адекватно, вы вполне можете оставить ее в покое.
Необходимость переделки сценария зависит от того, нуждается ли он в оптимизации, должен ли он быть переносимым, необходимо ли обеспечить легкую модификацию и не перерос ли он (как это обычно случается) первоначально поставленную задачу.
Примечание
Для удовлетворения вашего любопытства в вашу ОС Linux уже загружены многочисленные примеры сценариев, включая инсталляторы пакетов,
.xinitrc
иstartx
, и сценарии в каталоге /etc/rc.d, предназначенные для настройки системы в процессе загрузки.
Что такое командная оболочка?
Прежде чем переходить к обсуждению того, как программа использует оболочку, давайте рассмотрим, как функционирует оболочка и какие оболочки есть в Linux-подобных системах. Командная оболочка – это программа, которая действует как интерфейс между вами и ОС Linux, позволяя вам вводить команды, которые должна выполнить операционная система. В этом смысле она похожа на командную строку в ОС Windows, но, как уже упоминалось, командные оболочки Linux гораздо мощнее. Например, ввод и вывод можно перенаправить с помощью символов <
и >
, передавать данные между двумя одновременно выполняющимися программами с помощью символа |
, а перехватывать вывод подпроцесса с помощью конструкции $(...)
. В ОС Linux вполне может сосуществовать несколько установленных командных оболочек, и разные пользователи могут выбрать ту, которая им больше нравится. На рис. 2.1 показано, как командная оболочка (на самом деле, две командные оболочки: bash и csh) и другие программы располагаются вокруг ядра Linux.
Рис. 2.1
Поскольку ОС Linux – модульная система, вы можете вставить и применять одну из множества различных стандартных командных оболочек, хотя большинство из них – потомки первоначальной оболочки Bourne. В Linux стандартная командная оболочка, всегда устанавливаемая как /bin/sh и входящая в комплект средств проекта GNU, называется bash (GNU Bourne-Again SHell). Именно ее мы будем применять, т. к. это отличная командная оболочка, всегда устанавливаемая в системах Linux, со свободно распространяемым программным кодом и переносимая почти на все варианты UNIX-систем. В данной главе используется оболочка bash версии 3, и в большинстве случаев применяются ее функциональные возможности, общие для всех командных оболочек, удовлетворяющих требованиям стандарта POSIX. Мы полагаем, что командная оболочка, установленная как /bin/sh и для вашей учетной записи, считается командной оболочкой по умолчанию. В большинстве дистрибутивов Linux программа /bin/sh, командная оболочка по умолчанию, – это ссылка на программу /bin/bash.
Вы можете определить используемую в вашей системе версию bash с помощью следующей команды:
$ /bin/bash –version
GNU bash, version 3.2.9(1)-release (i686-pc-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
Примечание
Для перехода на другую командную оболочку, если в вашей системе по умолчанию установлена не bash, просто выполните программу нужной вам командной оболочки (т.е. /bin/bash) для запуска новой оболочки и смены приглашения в командной строке. Если вы используете ОС UNIX, и командная оболочка bash не установлена, вы можете бесплатно загрузить ее с Web-сайта www.gnu.org. Исходный код обладает высокой степенью переносимости, и велика вероятность, что он откомпилируется в вашей версии UNIX прямо в готовую к использованию программу.
Когда создаются учетные записи пользователей ОС Linux, вы можете задать командную оболочку, которой они будут пользоваться, в момент создания учетной записи пользователя или позже, откорректировав ее параметры. На рис. 2.2 показан выбор командной оболочки для пользователя дистрибутива Fedora.
Рис. 2.2
Существует много других командных оболочек, распространяемых свободно или на коммерческой основе. В табл. 2.1 предлагается краткая сводка некоторых самых распространенных командных оболочек.
Таблица 2.1
sh (Bourne) | Первоначальная оболочка в ранних версиях ОС UNIX |
csh, tcsh, zsh | Командная оболочка C-shell (и ее производные), первоначально созданная Биллом Джойем (Bill Joy) для систем Berkeley UNIX. C-shell, возможно, третья по популярности командная оболочка после оболочек bash и Korn |
ksh, pdksh | Командная оболочка Korn и ее безлицензионный родственник. Написанная Дэвидом Корном (David Korn) эта оболочка применяется по умолчанию во многих коммерческих версиях UNIX |
bash | Основная командная оболочка ОС Linux из проекта GNU или Bourne Again SHell со свободно распространяемым программным кодом. Если в настоящий момент она не выполняется в вашей системе UNIX, вероятно, есть вариант оболочки, перенесенный на вашу систему. У bash много сходств с оболочкой Korn |
За исключением оболочки C-shell и небольшого числа ее производных все перечисленные оболочки очень похожи и очень близки к оболочке, определенной в спецификациях Х/Оpen 4.2 и POSIX 1003.2. В спецификации POSIX 1003.2 задан минимум, необходимый для создания командной оболочки, а в спецификации Х/Open представлена более дружественная и мощная оболочка.
Каналы и перенаправление
Прежде чем заняться подробностями программ командной оболочки, необходимо сказать несколько слов о возможностях перенаправления ввода и вывода программ (не только программ командной оболочки) в ОС Linux.
Перенаправление выводаВозможно, вы уже знакомы с некоторыми видами перенаправления, например, таким как:
$ ls -l > lsoutput.txt
сохраняющим вывод команды ls в файле с именем lsoutput.txt.
Однако перенаправление позволяет сделать гораздо больше, чем демонстрирует этот простой пример. В главе 3 вы узнаете больше о дескрипторах стандартных файлов, а сейчас вам нужно знать только то, что дескриптор файла 0 соответствует стандартному вводу программы, дескриптор файла 1 – стандартному выводу, а дескриптор файла 2 – стандартному потоку ошибок. Каждый из этих файлов можно перенаправлять независимо друг от друга. На самом деле можно перенаправлять и другие дескрипторы файлов, но, как правило, нет нужды перенаправлять любые другие дескрипторы, кроме стандартных: 0, 1 и 2.
В предыдущем примере стандартный вывод перенаправлен в файл с помощью оператора >
. По умолчанию, если файл с заданным именем уже есть, он будет перезаписан. Если вы хотите изменить поведение по умолчанию, можно применить команду set -о noclobber
(или set -С
), которая устанавливает опцию noclobber
, чтобы помешать перезаписи при перенаправлении. Отменить эту опцию можно с помощью команды set +о noclobber
. Позже в этой главе будут приведены другие опции команды set
.
Для дозаписи в конец файла используйте оператор >>
. Например, команда
$ ps >> lsoutput.txt
добавит вывод команды ps
в конец заданного файла.
Для перенаправления стандартного потока ошибок перед оператором >
вставьте номер дескриптора файла, который хотите перенаправить. Поскольку у стандартного потока ошибок дескриптор файла 2, укажите оператор 2>
. Часто бывает полезно скрывать стандартный поток ошибок, запрещая вывод его на экран.
Предположим, что вы хотите применить команду kill
для завершения процесса из сценария. Всегда существует небольшой риск, что процесс закончится до того, как выполнится команда kill
. Если это произойдет, команда kill выведет сообщение об ошибке в стандартный поток ошибок, который по умолчанию появится на экране. Перенаправив стандартный вывод команды и ошибку, вы сможете помешать команде kill
выводить какой бы то ни было текст на экран.
Команда
$ kill -HUP 1234 >killout. txt 2>killer.txt
поместит вывод и информацию об ошибке в разные файлы.
Если вы предпочитаете собрать оба набора выводимых данных в одном файле, можно применить оператор >&
для соединения двух выводных потоков. Таким образом, команда
$ kill -1 1234 >killerr.txt 2>&1
поместит свой вывод и стандартный поток ошибок в один и тот же файл. Обратите внимание на порядок следования операторов. Приведенный пример читается как "перенаправить стандартный вывод в файл killerr.txt, а затем перенаправить стандартный поток ошибок туда же, куда и стандартный вывод". Если вы нарушите порядок, перенаправление выполнится не так, как вы ожидаете.
Поскольку обнаружить результат выполнения команды kill
можно с помощью кода завершения (который будет подробно обсуждаться далее в этой главе), часто вам не потребуется сохранять какой бы то ни было стандартный вывод или стандартный поток ошибок. Для того чтобы полностью отбросить любой вывод, вы можете использовать универсальную «мусорную корзину» Linux, /dev/null, следующим образом:
$ kill -l 1234 >/dev/null 2>&1
Также как вывод вы можете перенаправить ввод. Например,
$ more < killout.txt
Понятно, что это тривиальнейший пример для ОС Linux; команда more
в системе Linux в отличие от своего эквивалента командной строки в ОС Windows с радостью принимает имена файлов в качестве параметров.
Вы можете соединять процессы с помощью оператора канала (|
). В ОС Linux, в отличие от MS-DOS, процессы, соединенные каналами, могут выполняться одновременно и автоматически переупорядочиваться в соответствии с потоками данных между ними. Как пример, можно применить команду sort
для сортировки вывода команды ps
.
Если не применять каналы, придется использовать несколько шагов, подобных следующим:
$ ps > psout.txt
$ sort psout.txt > pssort.out
Соединение процессов каналом даст более элегантное решение:
$ ps | sort > pssort.out
Поскольку вы, вероятно, захотите увидеть на экране вывод, разделенный на страницы, можно подсоединить третий процесс, more
, и все это в одной командной строке:
$ ps | sort | more
Практически нет ограничений на допустимое количество процессов. Предположим, что вы хотите видеть все имена выполняющихся процессов, за исключением командных оболочек. Можно применить следующую командную строку:
$ ps -хо соmm | sort | uniq | grep -v sh | more
В ней берется вывод команды ps
, сортируется в алфавитном порядке, из него извлекаются процессы с помощью команды uniq
, применяется утилита grep -v sh
для удаления процесса с именем sh
и в завершение полученный список постранично выводится на экран.
Как видите, это гораздо более элегантное решение, чем строка из отдельных команд, каждая со своими временными файлами. Но в этом случае имейте в виду следующее. Если строка состоит из команд, файл вывода создается или записывается сразу, как только сформирован набор команд, поэтому в строке из нескольких команд никогда не используйте дважды одно и то же имя файла. Если вы попытаетесь сделать что-то подобное:
cat mydata.txt | sort | uniq > mydata.txt
то в результате получите пустой файл, т.к. вы перезапишете файл mydata.txt, прежде чем прочтете его.