Спасибо, что скачали книгу в бесплатной электронной библиотеке BooksCafe.Net
Все книги автора
Эта же книга в других форматах
Приятного чтения!
- Об авторах
- Благодарности
- Предисловие
- Введение
- Глава 1
- Глава 2
- Глава 3
- Глава 4
- Глава 5
- Глава 6
- Глава 7
- Глава 8
- Глава 9
- Глава 10
- Глава 11
- Глава 12
- Глава 13
- Глава 14
- Глава 15
- Глава 16
- Глава 17
- Глава 18
- Сноски
Алан Кокс (Alan Сох)
Поскольку книга задумана как учебник, знакомящий с различными средствами и наборами функций/библиотек, доступных вам в большинстве систем Linux, а также удобный справочник, к которому вы можете обращаться время от времени, она отличается четкой и понятной формой изложения, исчерпывающими пояснениями и подробными примерами.Примечание
Особое примечание для тех, кто впервые знакомится с ОС Linux. Эта книга не об установке и настройке Linux. Если вы хотите узнать больше об администрировании системы Linux, возможно вы захотите познакомиться с дополнительными книгами.
После загрузки программного кода из Интернета просто распакуйте его своей любимой программой сжатия. Вы также можете перейти на главную страницу загрузки программного кода издательства Wrox http://www.wrox.com/dynamic/books/download.aspx, для того чтобы просмотреть код к данной книге и ко всем остальным книгам издательства.Примечание
Поскольку у многих книг похожие заголовки, легче всего найти нужную книгу по номеру ISBN (International Standard Book Number); ISBN этой книги (оригинальной) — 978-0-470-14762-7.
Когда вводятся важные понятия, мы выделяем их курсивом. Символы, которые вы должны ввести, выделяются жирным моноширинным шрифтом. Элементы интерфейса выделены полужирным шрифтом. Комбинации клавиш обозначаются следующим образом: <Ctrl>+<A>Примечание
Фрагменты, подобные данному, содержат требующую запоминания критически важную информацию, которая непосредственно относится к окружающему тексту, а также советы, подсказки, особенности и замечания, касающиеся текущего обсуждения.
После присоединения к форуму вы можете посылать новые сообщения и отвечать на сообщения, посланные другими пользователями. Читать сообщения можно будет в любое время, находясь в Web-пространстве. Если вы хотите получать по электронной почте новые сообщения, появляющиеся на конкретном форуме, щелкните мышью пиктограмму Subscribe to this Forum (Подписаться на этот форум), расположенную рядом с именем форума в списке форумов.Примечание
Читать сообщения на форумах вы сможете и без регистрации в Р2Р, но для того чтобы отправлять собственные сообщения, придется зарегистрироваться.
В системах Linux доступен широкий диапазон языков программирования, многие из них свободно распространяются и есть на компакт-дисках или в архивах на FTP- сайтах в Интернете. Далее перечислена часть языков программирования, доступных программистам Linux:Примечание
На самом деле первая версия UNIX была написана в 1969 г. на ассемблере PDP 7. Язык С был задуман Деннисом Ритчи (Dennis Ritchie) примерно в это время, и в 1973 г. он вместе с Кеном Томпсоном (Ken Tompson) по существу переписал на С все ядро UNIX, совершив настоящий подвиг в эпоху разработки системного программного обеспечения на языке ассемблера.
Обратите внимание на то, что в ОС Linux, как и UNIX, для разделения отдельных элементов в переменной PATH применяется символ двоеточия (:) в отличие от символа точки с запятой, используемого в ОС MS-DOS и Windows. (ОС UNIX сделала выбор первой, поэтому спрашивайте, почему отличается Windows, а не почему в UNIX все не так!) Далее приведен пример переменной PATH:Примечание
Не стоит удалять каталоги из переменной PATH, пока нет полной уверенности в результате, который будет получен.
Элемент | UNIX | Windows |
---|---|---|
Объектный модуль | func.o | FUNC.OBJ |
Статическая библиотека | lib.a | LIB.LIB |
Программа | program | PROGRAM.EXE |
В системах Linux программа (динамический загрузчик), отвечающая за загрузку совместно используемых библиотек и разрешение ссылок на функции в клиентских программах, называется ld.so и может присутствовать в системе как ld-linux.so.2, или li-lsb.so.2, или li-lsb.so.3. Дополнительные каталоги поиска совместно используемых библиотек настраиваются в файле /etc/ld.so.conf, который после внесения изменений (например, если добавляются совместно используемые библиотеки X11 при установке графической оболочки X Window System) следует обработать командой ldconfig.Примечание
Вывод в следующем примере получен из дистрибутива SUSE 10.3. Если вы применяете другой дистрибутив, ваш вывод может слегка отличаться.
Примечание
Для удовлетворения вашего любопытства в вашу ОС Linux уже загружены многочисленные примеры сценариев, включая инсталляторы пакетов, .xinitrc и startx, и сценарии в каталоге /etc/rc.d, предназначенные для настройки системы в процессе загрузки.
Когда создаются учетные записи пользователей ОС Linux, вы можете задать командную оболочку, которой они будут пользоваться, в момент создания учетной записи пользователя или позже, откорректировав ее параметры. На рис. 2.2 показан выбор командной оболочки для пользователя дистрибутива Fedora.Примечание
Для перехода на другую командную оболочку, если в вашей системе по умолчанию установлена не bash, просто выполните программу нужной вам командной оболочки (т.е. /bin/bash) для запуска новой оболочки и смены приглашения в командной строке. Если вы используете ОС UNIX, и командная оболочка bash не установлена, вы можете бесплатно загрузить ее с Web-сайта www.gnu.org. Исходный код обладает высокой степенью переносимости, и велика вероятность, что он откомпилируется в вашей версии UNIX прямо в готовую к использованию программу.
Название командной оболочки | Краткие исторические сведения |
---|---|
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 |
Поскольку сценарий по существу обрабатывается как стандартный ввод командной оболочки, он может содержать любые команды ОС Linux, на которые ссылается переменная окружения PATH.Примечание
Обратите внимание на абсолютный путь, заданный в комментарии. Принято сохранять его длиной не более 32 символов для обратной совместимости, поскольку некоторые старые версии ОС UNIX могут использовать только такое ограниченное количество символов в комментарии #!, хотя у ОС Linux обычно нет подобного ограничения.
После этого вы можете выполнять файл с помощью командыПримечание
Конечно, превращение файла в исполняемый — это не единственный вариант применения команды chmod. Для того чтобы узнать больше о восьмеричных аргументах и других опциях команды, наберите man chmod.
После того как вы убедитесь в корректной работе вашего сценария, можете переместить его в более подходящее место, чем текущий каталог. Если команда предназначена только для собственных нужд, можете создать каталог bin в своем исходном каталоге и добавить его в свой путь. Если вы хотите, чтобы сценарий выполняли другие пользователи, можно использовать каталог /usr/local/bin или другой системный каталог как удобное, хранилище для вновь созданных программ. Если в вашей системе у вас нет прав суперпользователя, можно попросить системного администратора скопировать ваш файл для вас, хотя сначала, возможно, придется убедить его в неоспоримых достоинствах вашего файла. Для того чтобы установить владельца и права доступа к файлу, администратору придется задать такую последовательность команд:Примечание
Не следует вносить подобные изменения в переменную PATH для суперпользователя, как правило, с именем root. Это лазейка в системе безопасности, т.к. системного администратора, зарегистрировавшегося как root, обманным путём могут заставить запустить фиктивную версию стандартной команды. Один из авторов однажды разрешил сделать это — конечно только для того, чтобы поставить перед системным администратором вопрос о безопасности! В случае обычных учетных записей включение текущего каталога в полный путь сопряжено с очень небольшим риском, поэтому, если вам это нужно, примите за правило добавление комбинации символов ./ перед всеми командами, находящимися в локальном каталоге.
Примечание
В ОС Linux вы можете удалить файл, если у вас есть право записи в каталог, содержащий этот файл. Для безопасности убедитесь в том, что право записи в каталоги, содержащие файлы, которые вы хотели бы защитить, есть только у суперпользователя. В этом есть смысл, потому что каталог — это всего лишь еще один файл, и наличие права записи в файл каталога позволяет пользователям добавлять и удалять имена.
Вы можете присвоить переменной пользовательский ввод с помощью команды read. Она принимает один параметр — имя переменной, в которую будут считываться данные, и затем ждет, пока пользователь введет какой-либо текст. Команда read обычно завершается после нажатия пользователем клавиши <Enter>. При чтении переменной с терминала, как правило, заключать ее значения в кавычки не требуется:Примечание
Обратите внимание на то, что при наличии пробелов в содержимом переменной ее заключают в кавычки. Кроме того, не может быть пробелов справа и слева от знака равенства.
Переменная окружения | Описание |
---|---|
$НОМЕ | Исходный каталог текущего пользователя |
$PATH | Разделенный двоеточиями список каталогов для поиска команд |
$PS1 | Подсказка или приглашение командной строки. Часто знак $, но в оболочке bash можно применять и более сложные варианты. Например, строка [\u@\h \w]$ — популярный стандарт, сообщающий в подсказке пользователя имя компьютера и текущий каталог, а также знак $ |
$PS2 | Дополнительная подсказка или приглашение, применяемое как приглашение для дополнительного ввода; обычно знак > |
$IFS | Разделитель полей ввода. Список символов, применяемых для разделения слов при чтении оболочкой ввода, как правило, пробел, знак табуляции и символ перехода на новую строку |
$0 | Имя сценария командной оболочки |
$# | Количество передаваемых параметров |
$$ | ID (идентификатор) процесса сценария оболочки, часто применяемый внутри сценария для генерации уникальных имен временных файлов; например, /tmp/tmpfile_$$ |
Примечание
Если вы хотите проверить с помощью команды env <команда>, как работает программа в разных окружениях, познакомьтесь с интерактивным справочным руководством к команде env. Далее в этой главе вы увидите, как задавать переменные окружения в подоболочках (subshells), применяя команду export.
Переменная-параметр | Описание |
---|---|
$1, $2, ... | Параметры, передаваемые сценарию |
$* | Список всех параметров в единственной переменной, разделенных первым символом из переменной окружения IFS. Если IFS корректируется, способ разделения командной строки на параметры в переменной $* изменяется |
$@ | Едва различимая вариация $*; не использует переменную окружения IFS, поэтому параметры не сольются, даже если переменная IFS пуста |
Мы представим команду test на примере одного простейшего условия: проверки наличия файла. Для нее понадобится следующая команда: test -f <имя_файла>, поэтому в сценарии можно написатьПримечание
Эти команды в некоторых ранних оболочках UNIX вызывают внешнюю программу, но в более современных версиях их стараются делать встроенными. Мы вернемся к этому, когда будем рассматривать команды в следующем разделе.
Поскольку команда test не часто применяется за пределами сценариев командной оболочки, многие пользователи ОС Linux, никогда раньше не писавшие сценариев, пытаются создавать простые программы и называют их test. Если такая программа не работает, вероятно, она конфликтует с командой оболочки test. Для того чтобы выяснить, есть ли в вашей системе внешняя команда с данным именем, попытайтесь набрать что-нибудь вроде which test и проверить, какая именно команда test выполняется в данный момент, или используйте форму ./test, чтобы быть уверенным в том, что вы выполняете сценарий из текущего каталога. Если сомневаетесь, примите за правило выполнять свои сценарии, предваряя при запуске их имена комбинацией символов ./.
Варианты условий, которые вы можете применять в команде test, делятся на три типа: строковые сравнения, числовые сравнения и проверка файловых флагов (file conditionals). Эти типы условий описаны в табл. 2.4.Примечание
Имейте в виду, что вы должны вставлять пробелы между квадратной скобкой [ и проверяемым условием. Это легко усвоить, если запомнить, что вставить символ [ — это все равно, что написать test, а после имени команды вы всегда должны вставлять пробел.
Если вы предпочитаете помещать слово then в той же строке, что и if, нужно добавить точку с запятой для отделения команды test от then:
if [ -f fred.c ]; then
...
fi
Варианты условий | Результат |
---|---|
Сравнения строк | |
Строка1 = Строка2 | True (истина), если строки одинаковы |
Строка1 != Строка2 | True (истина), если строки разные |
-n Строка | True (истина), еслиСтрока не null |
-z Строка | True (истина), еслиСтрока null (пустая строка) |
Сравнения чисел | |
Выражение1 -eq Выражение2 | True (истина), если выражения равны |
Выражение1 -ne Выражение2 | True (истина), если выражения не равны |
Выражение1 -gt Выражение2 | True (истина), еслиВыражение1 больше, чемВыражение2 |
Выражение1 -ge Выражение2 | True (истина), еслиВыражение1 не меньшеВыражение2 |
Выражение1 -lt Выражение2 | True (истина), еслиВыражение1 меньше, чемВыражение2 |
Выражение1 -lе Выражение2 | True (истина), еслиВыражение1 не большеВыражение2 |
! Выражение | True (истина), еслиВыражение ложно, и наоборот |
Файловый флаг | |
-d файл | True (истина), еслифайл— каталог |
-е файл | True (истина), еслифайл существует. Исторически, опция -e не была переносима на другие платформы, поэтому обычно применяется -f |
-f файл | True (истина), еслифайл— обычный файл |
-g файл | True (истина), если дляфайла установлен бит set-group-id |
-r файл | True (истина), если файл доступен для чтения |
-s файл | True (истина), если файл ненулевого размера |
-u файл | True (истина), если дляфайла установлен бит set-user-id |
-v файл | True (истина), еслифайл доступен для записи |
-х файл | True (истина), если файл — исполняемый файл |
Мы немного сами себя обогнали, но далее следует пример тестирования состояния файла /bin/bash, так что вы сможете увидеть, как это выглядит на практике.Примечание
Вас могли заинтересовать непонятные биты set-group-id и set-user-id (также называемые set-gid и set-uid). Бит set-uid предоставляет программе права владельца, а не просто ее пользователя, бит set-gid предоставляет программе права группы. Эти биты устанавливаются командой chmod с помощью опций s и g. На файлы, содержащие сценарии, флаги set-gid и set-uid не влияют, они оказывают влияние только на исполняемые двоичные файлы.
Примечание
В следующих разделах элемент синтаксической записи операторы — это последовательности команд, которые выполняются, когда или пока условие удовлетворяется или пока оно не удовлетворяется.
Примечание
Обратите внимание на дополнительные пробелы, используемые для формирования отступа внутри оператора if. Это делается только для удобства читателя; командная оболочка игнорирует дополнительные пробелы.
Примечание
Если вы хотите, чтобы команда echo удалила новую строку в конце, наиболее легко переносимый вариант — применить команду printf (см. разд. "printf" далее в этой главе) вместо команды echo. В некоторых командных оболочках применяется команда echo -е, но она поддерживается не всеми системами. В оболочке bash для запрета перехода на новую строку допускается команда echo -n, поэтому, если вы уверены, что вашему сценарию придется трудиться только в оболочке bash, предлагаем вам использовать следующий синтаксис:
echo -n "Is it morning? Please answer yes or no: "
Помните о том, что нужно оставлять дополнительный пробел перед закрывающими кавычками, таким образом формируется зазор перед вводимым пользователем ответом, который в этом случае выглядит четче.
Как это работаетПримечание
Что произойдет, если вы измените первую строку с for foo in bar fud 43 на for foo in "bar fud 43"? Напоминаем, что вставка кавычек заставляет командную оболочку считать все, что находится между ними, единой строкой. Это один из способов сохранения пробелов в переменной.
Примечание
Помните о том, что все подстановки переменных в сценариях командной оболочки делаются во время выполнения сценария, а не в процессе их написания, поэтому все синтаксические ошибки в объявлениях переменных обнаруживаются только на этапе выполнения, как было показано ранее, когда мы заключали в кавычки пустые переменные.
Как пример цикла until можно установить звуковой сигнал предупреждения, инициируемый во время регистрации нового пользователя, регистрационное имя которого передается в командную строку.Примечание
Как правило, если нужно выполнить цикл хотя бы один раз, применяют цикл while; если такой необходимости нет, используют цикл until.
Возможность сопоставлять многочисленные образцы и затем выполнять множественные связанные с образцом операторы делают конструкцию case очень удобной для обработки пользовательского ввода. Лучше всего увидеть, как работает конструкция case на примерах. Мы будем применять ее в упражнениях 2.6–2.8, каждый раз совершенствуя сопоставление с образцами.Примечание
Обратите внимание на то, что каждая ветвь с образцами завершается удвоенным символом "точка с запятой" (;;). В каждой ветви оператора case можно поместить несколько операторов, поэтому сдвоенная точка с запятой необходима для отметки завершения очередного оператора и начала следующей ветви с новым образцом в операторе case.
Примечание
Применяя конструкцию case с метасимволами в образцах, такими как *, будьте особенно внимательны. Проблема заключается в том, что принимается во внимание первое найденное соответствие образцу, несмотря на то, что в последующих ветвях могут быть образцы с более точным соответствием.
Для того чтобы сделать средства установления соответствия образцам более мощными, можно применять следующие строки-образцы:Примечание
Учтите, что сдвоенная точка с запятой ;; перед служебным словом esac необязательна. В отличие от программирования на языке С, в котором пропуск маркера завершения считается плохим стилем программирования, пропуск ;; не создает проблем, если последняя ветвь оператора case — это вариант, принятый по умолчанию, поскольку другие образцы уже не будут анализироваться.
Для определения функции в командной оболочке просто введите ее имя и следом за ним пустые круглые скобки, а операторы тела функции заключите в фигурные скобки.Примечание
Как альтернативу можно использовать разбиение большого сценария на много маленьких, каждый из которых выполняет небольшую задачу. У этого подхода есть несколько недостатков: выполнение вложенного в сценарий другого сценария будет гораздо медленнее, чем выполнение функции. Значительно труднее возвращать результаты, и может появиться большое количество маленьких сценариев. Следует рассмотреть наименьшую практически самостоятельную часть вашего сценария и использовать ее как эталон для того, чтобы определить, когда возникает необходимость разбиения большого сценария на коллекцию меньших по размеру сценариев.
Вы можете заставить функцию возвращать числовые значения с помощью команды return. Обычный способ возврата функцией строковых значений — сохранение строки в переменной, которую можно использовать после завершения функции. Другой способ — вывести строку с помощью команды echo и перехватить результат, как показано далее.Примечание
Некоторые более ранние командные оболочки не могут восстанавливать значения позиционных параметров после выполнения функций. Не стоит полагаться на описанное в предыдущем абзаце поведение, если вы хотите, чтобы ваши сценарии были переносимыми.
#!/bin/shПримечание
В некоторых более старых версиях сценариев командной оболочки можно встретить двоеточие, применяемое в начале строки для обозначения комментариев, однако в современных сценариях следует всегда применять для обозначения начала комментариев знак #, поскольку этот вариант действует эффективнее.
Примечание
Если вам нужен легко переносимый способ удаления завершающей новой строки, для избавления от нее можно воспользоваться внешней командой tr, но она будет выполняться немного медленнее. Если вашим системам UNIX нужна переносимость и нужно избавиться от завершающей новой строки, как правило, лучше придерживаться команды printf. Если ваши сценарии предназначены для работы только в ОС Linux и bash, вполне подойдет echo -n, хотя, возможно, придется начинать файл со строки #!/bin/bash для того, чтобы в явной форме показать, что вы рассчитываете на поведение в стиле bash.
Код завершения | Описание |
---|---|
126 | Файл не является исполняемым |
127 | Команда не найдена |
128 и выше | Появившийся сигнал |
Примечание
Команды set -а или set -allexport экспортируют все переменные соответственно.
Вычисление выражения | Описания |
---|---|
Выражение1 | Выражение2 | Выражение1, еслиВыражение1 не равно нулю, в противном случаеВыражение2 |
Выражение1 & Выражение2 | Нуль, если оба выражения равны нулю, в противном случаеВыражение1 |
Выражение1 = Выражение2 | Равенство |
Выражение1 > Выражение2 | Больше чем |
Выражение1 >= Выражение2 | Больше или равно |
Выражение1 < Выражение2 | Меньше чем |
Выражение1 <= Выражение2 | Меньше или равно |
Выражение1 != Выражение2 | Неравенство |
Выражение1 + Выражение2 | Сложение |
Выражение1 — Выражение2 | Вычитание |
Выражение1 * Выражение2 | Умножение |
Выражение1 / Выражение2 | Деление нацело |
Выражение1 % Выражение2 | Остаток от деления нацело |
Escape-последовательность | Описание |
---|---|
\" | Двойная кавычка |
\\ | Символ обратный слэш |
\a | Звуковой сигнал тревоги (звонок колокольчика или прерывистый звуковой сигнал) |
\b | Символ Backspace (стирание слева) |
\c | Отбрасывание последующего вывода |
\f | Символ Form feed (подача бумаги) |
\n | Символ перехода на новую строку |
\r | Возврат каретки |
\t | Символ табуляции |
\v | Символ вертикальной табуляции |
\ooo | Один символ с восьмеричным значением ooo |
\xHH | Один символ с шестнадцатеричным значением HH |
Символ преобразования | Описание |
---|---|
D | Вывод десятичного числа |
С | Вывод символа |
S | Вывод строки |
% | Вывод знака % |
С помощью команды trap передается предпринимаемое действие, за которым следует имя (имена) сигнала для перехвата:Примечание
Для тех, кто не знаком с сигналами, это события, асинхронно посылаемые программе. Стандартно они обычно вызывают прекращение выполнения программы.
Сигнал | Описание |
---|---|
HUP (1) | Неожиданный останов; обычно посылается, когда отключается терминал или пользователь выходит из системы |
INT (2) | Прерывание; обычно посылается нажатием комбинации клавиш <Ctrl>+<C> |
QUIT (3) | Завершение выполнения; обычно посылается нажатием комбинации клавиш <Ctrl>+<\> |
ABRT (6) | Аварийное завершение; обычно посылается при возникновении серьезной ошибки выполнения |
ALRM (14) | Аварийный сигнал; обычно посылается для обработки превышений лимита времени |
TERM (15) | Завершение; обычно посылается системой, когда она завершает работу |
Примечание
Написание foo= подобно, но не идентично применению команды unset в только что приведенной программе. Оператор foo= задает для переменной foo значение null, но при этом переменная foo все еще существует. Команда unset foo удаляет из окружения переменную foo.
Опция | Описание |
---|---|
-depth | Поиск в подкаталогах перед поиском в самом каталоге |
-follow | Следовать по символическим ссылкам |
-maxdepths N | При поиске проверять не болееN вложенных уровней каталога |
-mount (или -xdev) | Не искать в каталогах других файловых систем |
Критерий | Описание |
---|---|
-atime N | К файлу обращались последний раз N дней назад |
-mtime N | Файл последний раз изменялся N дней назад |
-name шаблон | Имя файла без указания пути соответствует заданному шаблону. Для гарантии того, что шаблон будет передан в команду find и не будет немедленно обработан командной оболочкой, его следует всегда заключать в кавычки |
-newer другой файл | Текущий файл, измененный позже, чем другой файл |
-type С | Файл типа C, где C может принимать определенные значения; наиболее широко используемые "d" для каталогов и "f" для обычных файлов. Остальные обозначения типов можно посмотреть на страницах интерактивного справочного руководства |
-user имя пользователя | Файл принадлежит пользователю с заданным именем |
Оператор, короткая форма | Оператор, длинная форма | Описание |
---|---|---|
! | -not | Инвертирование критерия |
-а | -and | Оба критерия должны быть истинны |
-о | -or | Один из критериев должен быть истинным |
Действие | Описание |
---|---|
-exec команда | Выполняеткоманду. Наиболее широко используемое действие. После табл. 2.13 приведено объяснение способа передачи параметров в команду. Это действие следует завершать символьной парой \; |
-ok команда | Подобно действию exec, за исключением того, что перед обработкой файловкомандой выводится подсказка для получения подтверждения пользователя на обработку каждого файла. Это действие следует завершать символьной парой \; |
Вывод на экран имени файла | |
-ls | Применение команды ls -dils к текущему файлу |
Опция | Описание |
---|---|
-с | Вместо вывода на экран совпавших с шаблоном строк выводит их количество |
-E | Включает расширенные регулярные выражения |
-h | Ужимает обычное начало каждой строки вывода за счет удаления имени файла, в котором строка найдена |
-i | Не учитывает регистр букв |
-l | Перечисляет имена файлов со строками, совпадающими с шаблоном; не выводит сами найденные строки |
-v | Меняет шаблон соответствия для выбора вместо строк, соответствующих шаблону, несовпадающих с ним строк |
Символ | Описание |
---|---|
^ | Привязка к началу строки |
$ | Привязка к концу строки |
. | Любой одиночный символ |
[] | В квадратных скобках содержится диапазон символов, с любым из них возможно совпадение, например, диапазон символов a-e или инвертированный диапазон, перед которым стоит символ ^ |
Проверочный шаблон | Описание |
---|---|
[:alnum:] | Буквенно-цифровые символы |
[:alpha:] | Буквы |
[:ascii:] | Символы таблицы ASCII |
[:blank:] | Пробел или табуляция |
[:cntrl:] | Управляющие символы ASCII |
[:digit:] | Цифры |
[:graph:] | Неуправляющие и непробельные символы |
[:lower:] | Строчные буквы |
[:print:] | Печатные символы |
[:punct:] | Знаки пунктуации |
[:space:] | Пробельные символы, включая вертикальную табуляцию |
[:upper:] | Прописные буквы |
[:xdigit:] | Шестнадцатиричные цифры |
Опция | Описание |
---|---|
? | Совпадение не обязательно, но возможно не более одного раза |
* | Совпадения может не быть, оно может быть однократным или многократным |
+ | Совпадение должно быть однократным или многократным |
{n} | Совпадение должно быть n раз |
{n, } | Совпадение должно быть nраз и больше |
{n, m} | Совпадение должно быть от n до mраз включительно |
Во всех современных сценариях следует применять конструкцию выполнения или подстановки команды $(команда), которая введена для того, чтобы избавиться от довольно сложных правил использования символов $, ' и \ внутри команды, заключенной в обратные апострофы. Если применяется обратный апостроф внутри конструкции `...` , его необходимо экранировать символом \. Эти непонятные знаки часто заставляют программистов путаться, и иногда даже опытные специалисты в программировании средствами командной оболочки вынуждены ставить опыты для того, чтобы добиться правильного использования кавычек и апострофов в командах, заключенных в обратные апострофы.Примечание
В более раннем варианте конструкции применяется обратный апостроф или обратная кавычка (`), а не обычный апостроф ('), который мы использовали раньше в командной оболочке для экранирования (защиты от подстановки переменных). В сценариях оболочки применяйте этот вариант, только если вы хотите добиться высокой степени переносимости сценариев.
Примечание
Обратите внимание на тонкое отличие приведенной подстановки от команды х=$(...). Двойные скобки применяются для подстановки значений в арифметические выражения. Вариант с одиночными скобками, показанный ранее, используется для выполнения команд и перехвата их вывода.
Шаблон подстановки параметра | Описание |
---|---|
${парам:-значение по умолчанию} | Если упарам нет значения, ему присваивается значение по умолчанию |
${#парам} | Задается длинапарам |
${парам%строка} | От конца значенияпарам отбрасывается наименьшая порция, совпадающая сострокой, и возвращается остальная часть значения |
${парам%%строка} | От конца значенияпарам отбрасывается наибольшая порция, совпадающая сострокой, и возвращается остальная часть значения |
${парам#строка} | От начала значенияпарам отбрасывается наименьшая порция, совпадающая сострокой, и возвращается остальная часть значения |
${парам##строка} | От начала значенияпарам отбрасывается наибольшая порция, совпадающая сострокой, и возвращается остальная часть значения |
Шаблон {foo#*/} задает поиск и удаление только левого символа / (символ * соответствует любой строке, в том числе и пустой). Шаблон {foo##*/} задает поиск максимальной подстроки, совпадающей с ним, и, таким образом, удаляет самый правый символ / и все предшествующие ему символы.Примечание
Подстановка ${foo:=bar} установила бы значение переменной $foo. Этот строковый шаблон устанавливает, что переменная foo существует и не равна null. Если значение переменной не равно null, оператор возвращает ее значение, в противном случае вместо этого переменной foo присваивается значение bar.
Подстановка ${foo:?bar} выведет на экран foo: bar и аварийно завершит команду, если переменной foo не существует или ее значение не определено. И наконец, ${foo:+bar} вернет bar, если foo существует и не равна null. Какое разнообразие вариантов!
Примечание
Обратите внимание на знак \ внутри встроенного документа, применяемый для защиты от подстановки, выполняемой командной оболочкой. Символ \ экранирует знак $, поэтому оболочка знает, что не следует пытаться подставить вместо строки \$s/is/was/ ее значение, которого у нее конечно же нет. Оболочка просто передает текст \$ как $, который затем сможет интерпретировать редактор e
Опция командной строки | Опция команды set | Описание |
---|---|---|
sh -n <сценарий> | set -о noexec set -n | Только проверяет синтаксические ошибки; не выполняет команды |
sh -v <сценарий> | set -о verbose set -v | Выводит на экран команды перед их выполнением |
sh -х <сценарий> | set -о xtrace set -x | Выводит на экран команды после обработки командной строки |
sh -u <сценарий> | set -o nounset set -u | Выдает сообщение об ошибке при использовании неопределенной переменной |
Общая концепция утилиты dialog проста — одна программа с множеством параметров и опций, позволяющих отображать различные типы графических окон, начиная с простых окон с кнопками типа Yes/No (Да/Нет) и заканчивая окнами ввода и даже выбором пункта меню. Утилита обычно возвращает результат, когда пользователь выполнил какой-либо ввод, и результат может быть получен или из статуса завершения, или, если вводился текст, извлечением стандартного потока ошибок.Примечание
В некоторых дистрибутивах команда dialog по умолчанию не устанавливается; например, в Ubuntu вам, возможно, придется добавить совместно поддерживаемые репозитарии для поиска готовой версии. В других дистрибутивах вы можете найти уже установленный альтернативный вариант, gdialog. Он очень похож, но рассчитан на пользовательский интерфейс GNOME, применяемый для отображения диалоговых окон команды. В этом случае вы получите настоящий графический интерфейс. Как правило, в любой программе, использующей команду dialog, можно заменить все вызовы этой команды на gdialog, и вы получите графическую версию вашей программы. В конце этого раздела мы покажем пример программы, использующей команду gdialog.
Тип диалогового окна | Опция, применяемая для создания окна этого типа | Назначение окна |
---|---|---|
Окна с флажками (Check boxes) | --checklist | Позволяет отображать список флажков, каждый из которых можно установить или сбросить |
Информационные окна (Info boxes) | --infobox | Простое немедленное отображение в окне, без очистки экрана, возвращаемых данных |
Окна ввода (Input boxes) | --inputbox | Позволяет пользователю вводить в окно текст |
Окна меню (Menu boxes) | --menu | Позволяет пользователю выбрать один пункт из списка |
Окна сообщений (Message boxes) | --msgbox | Отображает сообщения для пользователей и снабжено кнопкой OK, которую они должны нажать для продолжения |
Окна с переключателями (Radio selection boxes) | --radiolist | Позволяет пользователю выбрать один переключатель из списка |
Текстовые окна (Text boxes) | --textbox | Позволяют отображать содержимое файла в окне с прокруткой |
Диалоговые окна Да/Нет (Yes/No boxes) | --yesno | Позволяют задать вопрос, на который пользователь может ответить "Да" или "Нет" |
Тип диалогового окна | Параметры |
---|---|
--checklist | text height width list-height [tag text status] ... |
--infobox | text height width |
--inputbox | text height width [initial string] |
--menu | text height width menu-height [tag item ] ... |
--msgbox | text height width |
--radiolist | text height width list-height [tag text status] ... |
--textbox | filename height width |
--yesno | text height width |
Catalog | Title | Type | Composer |
---|---|---|---|
CD123 | Cool sax | Jazz | Bix |
CD234 | Classic violin | Classical | Bach |
CD345 | Hits99 | Pop | Various |
Catalog | Track No. | Title |
---|---|---|
CD123 | 1 | Some jazz |
CD123 | 2 | More jazz |
CD234 | 1 | Sonata in D minor |
CD345 | 1 | Dizzy |
5. Далее идут две очень короткие функции, insert_title и insert_track, для пополнения файлов базы данных. Несмотря на то, что некоторые программисты ненавидят однострочные функции вроде этих, они помогают сделать понятнее другие функции.Примечание
Имейте в виду, что команда echo -е не переносится в некоторые командные оболочки.
Каталог /home в свою очередь является подкаталогом корневого каталога /, расположенного на верхнем уровне иерархии и содержащего все системные файлы и подкаталоги. В корневой каталог обычно включен каталог /bin для хранения системных программ (бинарных файлов), каталог /etc, предназначенный для хранения системных файлов конфигурации, и каталог /lib для хранения системных библиотек. Файлы, представляющие физические устройства и предоставляющие интерфейс для этих устройств, принято помещать в каталог /dev. На рис. 3.1 показана в качестве примера часть типичной файловой системы Linux. Мы рассмотрим структуру файловой системы Linux более подробно в главе 18, когда будем обсуждать стандарт файловой системы Linux (Linux File System Standard).Примечание
К сожалению, функции стандартной библиотеки при указании имени файла как параметра не понимают сокращенного обозначения с помощью тильды, поэтому в ваших программах следует всегда явно задавать полное имя файла.
В каталоге /dev можно найти и другие устройства, такие как дисководы жестких дисков и флоппи-дисководы, коммуникационные порты, ленточные накопители, дисководы CD-ROM, звуковые карты и некоторые устройства, представляющие внутреннюю структуру системы. Есть даже устройство /dev/zero, действующее как источник нулевых байтов для создания файлов, заполненных нулями. Для доступа к некоторым из этих устройств вам понадобятся права супер пользователя; обычные пользователи не могут писать программы, непосредственно обращающиеся к низкоуровневым устройствам, таким как накопители жестких дисков. Имена файлов устройств могут быть в разных системах различными. В дистрибутивах ОС Linux обычно есть приложения, выполняемые от имени суперпользователя и управляющие устройствами, которые иначе будут недоступны, например, mount для монтируемых пользователями файловых систем.Примечание
Другой способ создания пустых файлов — применение команды touch <имя файла>, изменяющей время модификации файла или создающей новый файл при отсутствии файла с заданным именем. Хотя она и не очищает содержимое обрабатываемого файла.
Примечание
Обратите внимание на то, что знак подсказки или приглашения командной оболочки появляется в конце последней строки вывода, поскольку в этом примере 128 байтов не формируют целое число строк.
Не вдаваясь в подробности, скажем, что вызов open устанавливает путь к файлу или устройству. Если установка прошла успешно, он возвращает дескриптор файла, который может применяться в системных вызовах read, write и др. Дескриптор файла уникален и не используется совместно другими процессами, которые могут в данный момент выполняться. Если файл открыт одновременно в двух программах, они поддерживают отдельные дескрипторы файла. Если они обе пишут в файл, то продолжат запись с того места, где остановились. Их данные не чередуются, но данные одной программы могут быть записаны поверх данных другой. У каждой программы свое представление о том, какая порция файла (каково смещение текущей позиции в файле) прочитана или записана. Вы можете помешать нежелательным накладкам такого сорта с помощью блокировки файла, которая будет обсуждаться в главе 7.Примечание
Строго говоря, для использования вызова open вы не должны включать файлы sys/types.h и sys/stat.h в системах, удовлетворяющих стандартам POSIX, но они могут понадобиться в некоторых системах UNIX.
Режим | Описание |
---|---|
О_RDONLY | Открытие только для чтения |
О_WRONLY | Открытие только для записи |
O_RDWR | Открытие для чтения и записи |
Цифра | Значение | Смысл |
---|---|---|
1 | 0 | Никакие права пользователя не отвергнуты |
4 | Право пользователя на чтение отвергается | |
2 | Право пользователя на запись отвергается | |
1 | Право пользователя на выполнение отвергается | |
2 | 0 | Никакие права группы не отвергнуты |
4 | Право группы на чтение отвергается | |
2 | Право группы на запись отвергается | |
1 | Право группы на выполнение отвергается | |
3 | 0 | Никакие права остальных не отвергнуты |
4 | Право остальных на чтение отвергается | |
2 | Право остальных на запись отвергается | |
1 | Право остальных на выполнение отвергается |
Цифра | Значение |
---|---|
1 | 0 |
2 | 2 |
1 | |
3 | 2 |
Примечание
В некоторых случаях проверка возвращаемого значения вызова close бывает очень важна. Некоторые файловые системы, особенно с сетевой структурой, могут не сообщать об ошибке записи в файл до тех пор, пока файл не будет закрыт, потому что при выполнении записи могло отсутствовать подтверждение действительной записи данных.
3. Выполнение программы даст результат, похожий на следующий:Примечание
Имейте в виду, что строка #include <unistd.h> должна быть первой, поскольку она определяет флаги, касающиеся соответствия стандарту POSIX и способные повлиять на другие включенные в #include файлы.
Элементы вызываемой структуры stat могут меняться в разных UNIX-подобных системах, но обязательно включают перечисленные в табл. 3.4 элементы.Примечание
Учтите, что включение файла sys/types.h не обязательное, но мы рекомендуем включать его при использовании системных вызовов, поскольку некоторые из их определений применяют для стандартных типов псевдонимы, которые могут измениться когда-нибудь.
Родственные функции stat и lstat возвращают информацию о состоянии названного файла. Они возвращают те же результаты за исключением того, что файл является символической ссылкой. Вызов lstat возвращает данные о самой ссылке, а вызов stat — о файле, на который ссылка указывает.
Элемент структуры stat | Описание |
---|---|
st_mode | Права доступа к файлу и сведения о типе файла |
st_ino | Индекс, ассоциированный с файлом |
st_dev | Устройство, на котором размещен файл |
st_uid | Идентификатор (user identity) владельца файла |
st_gid | Идентификатор группы (group identity) владельца файла |
st_atime | Время последнего обращения |
st_ctime | Время последнего изменения прав доступа, владельца, группы или объема |
st_mtime | Время последней модификации содержимого |
st_nlink | Количество жестких ссылок на файл |
Три файловых потока открываются автоматически при старте программы. К ним относятся stdin, stdout и stderr. Эти потоки объявлены в файле stdio.h и представляют вывод, ввод и стандартный поток ошибок, которым соответствуют низкоуровневые файловые дескрипторы 0, 1 и 2.Примечание
Не путайте эти потоки файлов с потоками ввода/вывода в языке С++ и механизмом STREAMS, описывающим взаимодействие процессов и введенным в системе AT&T UNIX System V Release 3, который не рассматривается в данной книге. Для получения дополнительной информации о средствах STREAMS обратитесь к спецификации X/Open (по адресу http://www.opengroup.org) и руководству по программированию AT&T STREAMS Programming Guide, поставляемому с системой System V.
В случае успешного завершения функция fopen возвращает ненулевой указатель на структуру FILE*. В случае сбоя она вернет значение NULL, определенное в файле stdio.h.Примечание
В отличие от MS-DOS, системы UNIX и Linux не делают различий между текстовыми и бинарными файлами. UNIX и Linux обрабатывают их одинаково с эффективностью обработки бинарных файлов. Важно также учесть, что параметр mode должен быть строкой, а не символом. Всегда применяйте двойные кавычки, а не апострофы.
Примечание
Имейте в виду, что функции fread и fwrite не рекомендуется применять со структурированными данными. Частично проблема заключается в том, что файлы, записанные функцией fwrite, могут быть непереносимыми между машинами с разной архитектурой.
Примечание
Учтите, что функция gets не ограничивает количество символов, которые могут передаваться, поэтому она может переполнить свой пересылочный буфер. По этой причине вам следует избегать применения этой функции и заменять ее функцией fgets. Многие проблемы безопасности порождены функциями в программах, сделанных для переполнения буфера тем или иным способом. Это одна из таких функций, поэтому будьте осторожны!
Формат | Аргумент | Вывод |
---|---|---|
%10s | "Hello" | | Hello| |
%-10s | "Hello" | |Hello | |
%10d | 1234 | | 1234| |
%-10d | 1234 | |1234 | |
%010d | 1234 | |0000001234| |
%10.4f | 12.34 | | 12.3400| |
%*s | 10, "Hello" | | Hello| |
Формат | Аргумент | Вывод |
---|---|---|
%10s | "HelloTherePeeps" | |HelloTherePeeps| |
К другим спецификаторам преобразований относятся следующие:Примечание
Если не соблюдать осторожность, могут возникнуть проблемы. В вашей программе может появиться бесконечный цикл, если во вводе оставить нецифровой символ при считывании целых чисел.
Вы можете также запросить состояние файлового потока, чтобы выяснить, возникла ли ошибка или достигнут конец файла.Примечание
Имейте в виду, что многие функции могут изменять значение errno. Оно достоверно, только когда функция закончилась неудачно. Вам следует проверять это значение сразу же, как функция сообщила о сбое. Прежде чем использовать его, скопируйте это значение в другую переменную, поскольку функции вывода, такие как fprintf, могут сами изменять errno.
Примечание
Стандарт POSIX в действительности допускает существование систем, в которых несуперпользователи могут изменять права владения файлом. Все "правильные" с точки зрения POSIX системы не допускают этого, но строго говоря, это расширение стандарта (в FIPS 151-2). Все виды систем, с которыми мы имеем дело в этой книге, подчиняются спецификации XSI (X/Open System Interface) и соблюдают на деле правила владения.
Системный вызов link создает новую ссылку на существующий файл path1. Новый элемент каталога задается в path2. Символические ссылки можно создавать аналогичным образом с помощью системного вызова symlink. Имейте в виду, что символические ссылки на файл не увеличивают значение счетчика ссылок и таким образом, в отличие от обычных (жестких) ссылок, не мешают удалению файла.Примечание
Создание файла с помощью вызова open и последующее обращение к unlink для этого файла — трюк, применяемый некоторыми программистами для создания временных или транзитных файлов. Эти файлы доступны программе, только пока они открыты; и будут удалены автоматически, когда программа завершится, и файлы будут закрыты.
Для увеличения предельного значения одновременно обрабатываемых в системе файлов до 80000 вы можете просто записать новое предельное значение в файл file-max.Примечание
Для записи в файлы /proc требуются права доступа суперпользователя. При записи в эти файлы нужно быть предельно внимательным; при записи неподходящих данных возможно возникновение серьезных проблем, включая крах системы и потерю данных.
Константа | Описание |
---|---|
MAP_PRIVATE | Сегмент частный, изменения локальные |
MAP_SHARED | Изменения сегмента переносятся в файл |
MAP_FIXED | Сегмент должен располагаться по заданному адресу addr |
Константа | Описание |
---|---|
MS_ASYNC | Выполнять запись асинхронно |
MS_SYNC | Выполнять запись синхронно |
MS_INVALIDATE | Обновить другие отражения этого файла так, чтобы они содержали изменения, внесенные этим вызовом |
Параметр опции | Описание |
---|---|
name | Название длинной опции. Сокращения будут приниматься до тех пор, пока они не создадут путаницы при определении названий других опций |
has_arg | Принимает ли эта опция аргумент. Задайте 0 для опций без аргументов, 1 для опций, у которых должно быть значение, и 2 для опций с необязательным аргументом |
flag | Задайте NULL, чтобы getopt_long вернула при обнаружении данной опции значение, заданное в val. В противном случае getopt_long возвращает 0 и записывает значение val в переменную, на которую указывает flag |
val | Значение getopt_long для данной опции, предназначенное для возврата |
Примечание
Переменные окружения — противоречивое благо, и их следует применять с осторожностью. Эти переменные более "закрыты" от пользователя, чем опции командной строки, и это может затруднить отладку. По смыслу переменные окружения подобны глобальным переменным, поэтому они могут изменять поведение программы, что порой приводит к неожиданным результатам.
Время задается с помощью типа time_t. Это целочисленный тип, достаточный для хранения дат и времени в секундах. В Linux-подобных системах это тип long integer (длинное целое), определенный вместе с функциями, предназначенными для обработки значений времени, в заголовочном файле time.h.Примечание
Во всех системах UNIX применяется одна и та же точка отсчета времени и дат: полночь по Гринвичу (GMT) на 1 января 1970 г. Это "начало эпохи UNIX", и ОС Linux — не исключение. Время в системе Linux измеряется в секундах, начиная с этого момента времени. Такой способ обработки аналогичен принятому в системе MS-DOS за исключением того, что эпоха MS-DOS началась в 1980 г. В других системах применяют точки отсчета иных эпох.
#include <time.h>Примечание
Не думайте, что для хранения времени достаточно 32 битов. В системах UNIX и Linux, использующих 32-разрядный тип time_t, временное значение "будет превышено" в 2038 г. Мы надеемся, что к тому времени системы перейдут на тип time_t, содержащий более 32 битов. Недавнее широкое внедрение 64-разрядных процессоров превращает это практически в неизбежность.
Элемент tm | Описание |
---|---|
int tm_sec | Секунды, 0–61 |
int tm_min | Минуты, 0–59 |
int tm_hour | Часы, 0–23 |
int tm_mday | День в месяце, 1–31 |
int tm_mon | Месяц в году, 0–11 (January (январь) соответствует 0) |
int tm_year | Годы, начиная с 1900 г. |
int tm_wday | День недели, 0–6 (Sunday (воскресенье) соответствует 0) |
int tm_yday | День в году, 0–365 |
int tm_isdst | Действующее летнее время |
Спецификатор преобразования | Описание |
---|---|
%a | Сокращенное название дня недели |
%А | Полное название дня недели |
%b | Сокращенное название месяца |
%B | Полное название месяца |
%c | Дата и время |
%d | День месяца, 01–31 |
%H | Час, 00–23 |
%I | Час по 12-часовой шкале, 01–12 |
%j | День в году, 001–366 |
%m | Номер месяца в году, 01–12 |
%M | Минуты, 00–59 |
%p | a.m. (до полудня) или p.m. (после полудня) |
%S | Секунды, 00–59 |
%u | Номер дня недели, 1–7 (1 соответствует понедельнику) |
%U | Номер недели в году, 01–53 (воскресенье — первый день недели) |
%V | Номер недели в году, 01–53 (понедельник — первый день недели) |
%w | Номер дня недели, 0–6 (0 соответствует воскресенью) |
%x | Дата в региональном формате |
%X | Время в региональном формате |
%y | Номер года, меньший 1900 |
%Y | Год |
%Z | Название часового пояса |
%% | Символ % |
Примечание
В ваших собственных программах следует всегда применять функции "создать и открыть" tmpfile и mkstemp вместо функций tmpnam и mktemp.
Элемент passwd | Описание |
---|---|
char *pw_name | Регистрационное имя пользователя |
uid_t pw_uid | Номер UID |
gid_t pw_gid | Номер GID |
char *pw_dir | Исходный каталог пользователя |
char *pw_gecos | Полное имя пользователя |
char *pw_shell | Командная оболочка пользователя, запускаемая по умолчанию |
Примечание
Только суперпользователь может вызывать функции setuid и setgid.
Элемент структуры utsname | Описание |
---|---|
char sysname[] | Имя операционной системы |
char nodename[] | Имя компьютера |
char release[] | Номер выпуска (релиза) системы |
char version[] | Номер версии системы |
char machine[] | Аппаратный тип |
Уникальный идентификатор каждого рабочего компьютера можно получить с помощью функции gethostid.Примечание
Другой пример применения функции uname вы можете найти в исходном коде Linux для команды uname, которая использует эту функцию.
Некоторые системы UNIX не предоставляют файлов с удобными для чтения сообщениями, но они снабжают администраторов средствами для чтения базы данных системных событий. См. подробности в системной документации.Примечание
Для просмотра регистрируемых сообщений вы можете запросить права суперпользователя.
Приоритет | Описание |
---|---|
LOG_EMERG | Кризисная ситуация |
LOG_ALERT | Проблема с высоким приоритетом, например, повреждение базы данных |
LOG_CRIT | Критическая ошибка, например, повреждение оборудования |
LOG_ERR | Ошибки |
LOG_WARNING | Предупреждение |
LOG_NOTICE | Особые обстоятельства, требующие повышенного внимания |
LOG_INFO | Информационные сообщения |
LOG_DEBUG | Отладочные сообщения |
Параметр logopt | Описание |
---|---|
LOG_PID | Включает в сообщения идентификатор процесса, уникальный номер, выделяемый системой каждому процессу |
LOG_CONS | Посылает сообщения на консоль, если они не могут быть записаны |
LOG_ODELAY | Открывает средство регистрации сообщений при первом вызове функции syslog |
LOG_NDELAY | Открывает средство регистрации сообщений немедленно, не дожидаясь первого регистрируемого сообщения |
Ограничительная константа | Назначение |
---|---|
NAME_MAX | Максимальное число символов в имени файла |
CHAR_BIT | Количество разрядов в значении типа char |
CHAR_MAX | Максимальное значение типа char |
INT_MAX | Максимальное значение типа int |
В заголовочном файле sys/resource.h представлены определения операций над ресурсами. К ним относятся функции для считывания и установки предельных значений для разрешенного размера программы, приоритета выполнения и файловых ресурсов.Примечание
Имейте в виду, что константа NAME_MAX зависит от файловой системы. Для разработки легко переносимого кода следует применять функцию pathconf. Дополнительную информацию о ней см. на страницах интерактивного справочного руководства.
Элемент структуры rusage | Описание |
---|---|
struct timeval ru_utime | Время, использованное пользователем |
struct timeval ru_stime | Время, использованное системой |
Константа who | Описание |
---|---|
RUSAGE_SELF | Возвращает данные о потреблении только для текущей программы |
RUSAGE_CHILDREN | Возвращает данные о потреблении и для дочерних процессов |
Приложения могут определять и изменять свои (и чужие) приоритеты с помощью функций getpriority и setpriority. Процесс, исследуемый или изменяемый с помощью этих функций, может быть задан идентификатором процесса, группы или пользователя. Параметр which описывает, как следует интерпретировать параметр who (табл. 4.11).Примечание
Обычные пользователи могут только снижать приоритеты своих программ, а не повышать их.
Параметр which | Описание |
---|---|
PRIO_PROCESS | who — идентификатор процесса |
PRIO_PGRP | who — идентификатор группы |
PRIO_USER | who — идентификатор пользователя |
Элемент rlimit | Описание |
---|---|
rlim_t rlim_cur | Текущее, мягкое ограничение |
rlim_t rlim_max | Жесткое ограничение |
Параметр resource | Описание |
---|---|
RLIMIT_CORE | Ограничение размера файла дампа ядра, в байтах |
RLIMIT_CPU | Ограничение времени ЦП, в секундах |
RLIMIT_DATA | Ограничение размера сегмента data(), в байтах |
RLIMIT_FSIZE | Ограничение размера файла, в байтах |
RLIMIT_NOFILE | Ограничение количества открытых файлов |
RLIMIT_STACK | Ограничение размера стека, в байтах |
RLIMIT_AS | Ограничение доступного адресного пространства (стек и данные), в байтах |
В приведенном примере сообщение об ошибке "Error writing to temporary file" ("Ошибка записи во временный файл") не выводится. Это происходит потому, что некоторые системы (например, Linux 2.2 и более поздние версии) завершают выполнение программы при превышении ограничения ресурса. Делается это с помощью отправки сигнала SIGXFSZ. В главе 11 вы узнаете больше о сигналах и способах их применения. Другие системы, соответствующие стандарту POSIX, заставляют функцию, превысившую ограничение, вернуть ошибку.Примечание
Ограничения можно также наложить на программу, выполняющуюся в отдельной командной оболочке с помощью команды ulimit оболочки bash.
Значения, которые можно изменять для управления терминалом, разделены на группы, относящиеся к следующим режимам:Примечание
Программы, применяющие вызовы функций, определенных в файле termios.h, нуждаются в компоновке с соответствующей библиотекой функций. Ею может быть в зависимости от установленной у вас системы просто стандартная библиотека С или библиотека curses. При необходимости во время компиляции примеров этой главы добавьте аргумент -lcurses в конец строки команды компиляции. В некоторых более старых системах Linux библиотека curses представлена в версии, известной под названием "new curses". В этих случаях имя библиотеки и аргумент компоновки становятся ncurses и -lncurses соответственно.
Теперь рассмотрим более подробно режимы и связанные с ними вызовы функций. Некоторые характеристики режимов довольно специализированные и редко применяются, поэтому мы остановимся только на основных. Если вы хотите знать больше, просмотрите страницы интерактивного справочного руководства вашей системы либо скопируйте стандарт POSIX или X/Open.Примечание
Учтите, что для программ очень важно восстановить настройки терминала, действующие до начала выполнения программы. За первоначальное сохранение значений и их восстановление после завершения выполнения всегда отвечает программа.
Вам не придется часто изменять режимы ввода, поскольку обычно стандартные значения — наиболее подходящие, и поэтому мы больше не будем их обсуждать.Примечание
Если флаги BRKINT и IGNBRK не установлены, сбой на линии связи считывается как символ NULL (0x00).
Режимы вывода тоже обычно не используются, поэтому мы не будем их обсуждать в дальнейшем.Примечание
Если флаг OPOST не установлен, все остальные флаги игнорируются.
Режимы управления применяются в основном при подключении к модему последовательной линии связи, хотя их можно использовать и при диалоге с терминалом. Обычно легче изменить настройку терминала, чем изменять стандартное поведение линий связи с помощью режимов управления структуры termios.Примечание
Если драйвер терминала обнаруживает, что последний дескриптор файла, ссылающийся на терминал, закрыт и при этом флаг HUPCL установлен, он устанавливает линии управления модема в состояние останова (hang-up).
Символ | Описание |
---|---|
INTR | Заставляет драйвер терминала отправить сигнал SIGINT процессам, подключенным к терминалу. Мы обсудим сигналы более подробно в главе 11 |
QUIT | Заставляет драйвер терминала отправить сигнал SIGQUIT процессам, подключенным к терминалу |
ERASE | Заставляет драйвер терминала удалить последний символ в строке |
KILL | Заставляет драйвер терминала удалить всю строку |
EOF | Заставляет драйвер терминала передать все символы строки во ввод, считываемый приложением. Если строка пустая, вызов read вернет ноль символов, как будто он встретил на конец файла |
EOL | Действует как ограничитель строки в дополнение к более привычному символу перехода на новую строку |
SUSP | Заставляет драйвер терминала послать сигнал SIGSUSP процессам, подключенным к терминалу. Если ваша система UNIX поддерживает управление заданиями, текущее приложение будет приостановлено |
STOP | Действует как "прерыватель потока", т. е. прекращает дальнейший вывод на терминал. Применяется для поддержки управления потоком XON/XOFF и обычно задается как ASCII-символ XOFF (<Ctrl>+<S>) |
START | Возобновляет вывод после символа STOP, часто ASCII-символ XON |
Примечание
Не забудьте применить команду stty echo для возврата отображения после ваших экспериментов!
Примечание
В некоторых системах, включая Linux, для выбора более высоких скоростей определены константы В57600, B115200 и В230400. Если вы пользуетесь более старой версией ОС Linux и эти константы недоступны, можно применить команду setserial для получения нестандартных скоростей 57 600 и 115 200. В этом случае указанные скорости будут использоваться при выборе константы B38400. Оба эти метода непереносимы, поэтому применяйте их с осторожностью.
Такое разнообразие аппаратных моделей терминалов было бы огромной проблемой для программистов, пытающихся написать программы управления экраном, выполняющиеся на терминалах разных типов. Например, терминал ANSI применяет последовательность символов Escape, [, A для перемещения курсора вверх на одну строку. Терминал ADM-За (очень распространенный несколько лет назад) использует один управляющий символ от комбинации клавиш <Ctrl>+<K>.Примечание
Существует стандарт ANSI для набора escape-последовательностей (в основном базирующихся на последовательностях, применяемых в серии VT-терминалов компании Digital Equipment Corporation, но не идентичных им). Многие терминальные программы обеспечивают эмуляцию стандартного аппаратного терминала, часто VT100, VT220 или ANSI, а иногда и других типов.
Примечание
Мы могли бы описывать огромное множество характеристик, но, к счастью, в основном системы UNIX и Linux приходят с большинством предопределенных терминалов. Если нужно добавить новую модель терминала, вы можете найти полный список характеристик на странице интерактивного справочного руководства, посвященной terminfo. Лучше всего начать с поиска включенного в базу данных терминала, похожего на ваш новый, и затем создания описания новой модели как вариации существующего, т. е. осуществить последовательный просмотр характеристик, одну за другой, и исправление нуждающихся в корректировке.
Вы почти готовы добавить обработку экрана в вашу функцию выбора пункта меню. Единственно, что осталось, — очистить экран просто с помощью свойства clear. Некоторые терминалы не поддерживают характеристику clear, которая помещает курсор в левый верхний угол экрана. В этом случае вы можете поместить курсор в левый верхний угол и применить команду ed — удалить до конца экрана.Примечание
Если вы обратитесь к страницам интерактивного справочного руководства за информацией о функции tparm и характеристиках терминалов, то можете встретить функцию tgoto. Причина, по которой мы не используем эту функцию, хотя она, очевидно, предлагает более легкий способ перемещения курсора, заключается в том, что она не включена в стандарт X/Open (Single UNIX Specification Version 2) по данным издания 1997 г. Следовательно, мы не рекомендуем применять любую из этих функций в ваших новых программах.
При компиляции программ, использующих curses, следует подключить заголовочный файл curses.h и на этапе редактирования связей саму библиотеку с помощью аргумента -lcurses. Во многих системах Linux вы можете применять просто библиотеку curses, а потом обнаружить, что на самом деле вы пользуетесь усовершенствованной, более новой реализацией ncurses.Примечание
В стандарте X/Open определены два варианта curses: базовый и расширенный. Расширенный вариант библиотеки curses содержит разнородную кучу дополнительных функций, включая ряд функций для обработки многостолбцовых символов и подпрограммы управления цветом. Кроме приведенного далее в этой главе описания способов управления цветом, мы будем в основном привязаны к функциям базовой версии библиотеки.
Если вы точно не знаете, как установлена библиотека curses в вашей системе, обратитесь к страницам интерактивного справочного руководства, посвященным ncurses, или просмотрите другую интерактивную документацию; обычное место ее хранения — каталог /usr/share/doc/, в котором вы найдете каталог curses или ncurses часто с присоединенным в конце номером версии.Примечание
В загружаемом коде сценария Makefile предполагается, что в установленной у вас системе по умолчанию применяется библиотека curses, поэтому вы должны заменить его или откомпилировать вручную, если в вашей системе это не так.
Функция insch вставляет символ, сдвигая имеющиеся символы вправо. При этом не определено, что произойдет в конце строки, результат зависит от используемого терминала. Функция insertln вставляет пустую строку, перемещая имеющиеся строки на одну вниз. Функции delch и deleteln аналогичны функциям insert.Примечание
В стандартной библиотеке curses вы можете применять только "обычные" символы для рисования горизонтальных и вертикальных линий. В расширенной версии библиотеки можно использовать два определения, ASC_VLINE и ACS_HLINE, для вывода символов вертикальных и горизонтальных линий соответственно, которые позволят нарисовать внешне более привлекательную рамку. Для этого ваш терминал должен поддерживать символы псевдографики. Обычно они лучше отображаются в окне эмулятора xterm, чем на стандартной консоли, но их поддержка полна корректировок или "заплат", поэтому мы полагаем, что вы откажетесь от их применения, если важна переносимость вашей программы.
Примечание
Если вы пользуетесь очень старой версией библиотеки curses, вам, возможно, понадобится выполнить дополнительный вызов функции refresh перед вызовом функции getstr. В библиотеке ncurses вызов getstr обновляет экран автоматически.
Когда новое окно создано, как записать в него информацию? У всех уже рассмотренных функций есть универсальные версии, действующие в заданных окнах, и для удобства в них также включено перемещение курсора.Примечание
Следите за тем, чтобы никогда не было попыток удалить собственные окна библиотеки curses: stdscr и curscr!
Примечание
Для того чтобы библиотека curses отображала окна в нужном порядке, их следует обновлять в этом порядке. Один из способов добиться этого — сохранять все указатели ваших окон в массиве или списке, в которых поддерживается порядок их размещения, соответствующий порядку их появления на экране.
Выполните упражнение 6.5.Примечание
Одно ограничение, накладываемое на применение вложенных окон, заключается в необходимости перед обновлением экрана вызвать в приложении функцию touchwin для родительского окна.
Мы разбили программный код этого приложения на несколько отдельных секций, которые обозначены заголовками последующих разделов. Соглашения, принятые для оформления этого программного кода, немного отличаются от оформления большинства программ в этой книге; здесь выделение цветом применяется только для обозначения вызовов других функций приложения.Примечание
Мы написали эту версию приложения для работы с базой данных компакт-дисков, используя информацию из предыдущих глав. Данное приложение — потомок оригинального сценария командной оболочки, приведенного в главе 2. Оно не перепроектировалось для написания на языке С, поэтому вы увидите в этой версии многие подходы, заимствованные из сценария. Учтите, что в этой реализации есть существенные ограничения, которые мы устраним в последующих модификациях.
box_window_ptr = subwin(stdscr, BOXED_LINES + 2, BOXED_ROWS + 2,Примечание
Листинг будет продолжен через минуту; мы хотим сделать краткую паузу, чтобы обратить ваше внимание на ввод данных в обрамленное окно с прокруткой. Хитрость заключается в формировании вложенного окна, рисовании рамки по его краю и создании внутри этого окна нового вложенного окна с прокруткой.
В большинстве систем Linux вы можете выделять большой объем памяти. Давайте начнем с очень простой программы из упражнения 7.1, которая, тем не менее, выигрывает соревнование со старыми программами ОС MS-DOS, поскольку они не могут обращаться к памяти за пределами базовой карты памяти ПК объемом 640 Кбайт.Примечание
Имейте в виду, что ОС Linux (следующая требованиям стандарта X/Open) отличается от некоторых реализаций UNIX тем, что не требует включения специального заголовочного файла malloc.h. Кроме того, параметр size, задающий количество выделяемых байтов, — это не простой тип int, хотя обычно он задается типом беззнаковое целое (unsigned integer).
Но что это означает для прикладного программиста? В основном благую весть. Система Linux очень умело управляет памятью и позволяет приложениям использовать большие области памяти и даже очень большие единые блоки памяти. Но вы должны помнить о том, что выделение двух блоков памяти в результате не приведет к формированию одного непрерывно адресуемого блока памяти. Вы получите то, что просили: два отдельных блока памяти.Примечание
Это поведение, сопровождающееся уничтожением процесса, отличается от поведения более старых версий Linux и множества других вариантов UNIX, в которых просто аварийно завершалась функция malloc. Называется оно уничтожением из-за нехватки памяти (out of memory (OOM) killer), и хотя может показаться чересчур радикальным, на самом деле служит разумным компромиссом между возможностью быстрого и эффективного выделения памяти процессам и необходимостью собственной защиты ядра от полного исчерпания ресурсов, что является серьезной проблемой.
Примечание
Помните о том, что после вызова free для освобождения блока памяти этот блок больше не принадлежит процессу. Он больше не управляется библиотекой malloc. Никогда не пытайтесь читать из области памяти или писать в область памяти, для которой была вызвана функция free.
Значение | Описание |
---|---|
F_RDLCK | Разделяемая или совместная блокировка (блокировка на чтение). У разных процессов может быть разделяемая блокировка одних и тех же (или перекрывающихся) участков файла. Если у какого-либо процесса есть разделяемая блокировка, ни один процесс не сможет установить исключительную блокировку этого участка. Для получения совместной блокировки файл должен быть открыт с правом на чтение или на чтение/запись |
F_UNLCK | Разблокировать. Применяется для снятия блокировок |
F_WRLCK | Исключительная блокировка (или блокировка на запись). Только один процесс может установить исключительную блокировку на любой конкретный участок файла. После того как процесс установил такую блокировку, никакой другой процесс не сможет установить блокировку любого типа на этот участок файла. Для установки исключительной блокировки файл должен быть открыт с правом на запись или на чтение/запись |
Значение | Описание |
---|---|
l_type | Или F_RDLCK для разделяемой (только чтение) блокировки, или F_WRLCK для исключительной (на запись) блокировки |
l_whence | Одно из значений: SEEK_SET, SEEK_CUR или SEEK_END LCK |
l_start | Начальный байт интересующего вас участка файла |
l_len | Количество байтов в интересующем вас участке файла |
l_pid | Идентификатор процесса, удерживающего блокировку |
Значение | Описание |
---|---|
l_type | Одно из следующих: • F_RDLCK — для разделяемой или допускающей только чтение блокировки; • F_WRLCK — для исключительной или блокировки записи; • F_UNLCK — для разблокирования участка |
l_pid | Не используется |
Примечание
В этой книге из-за ограниченности объема у нас нет возможности рассматривать трудности действующих одновременно программ. Если вы хотите почитать побольше об этом, попробуйте найти книгу: Ben-Ari М. Principles of Concurrent and Distributed Programming. — Prentice Hall, 1990 (Бен-Ари M. Принципы параллельного и распределенного программирования).
Если вы знакомы с базами данных SQL, то заметите, что в случае базы данных dbm не существует структур таблиц или столбцов. Эти структуры не нужны, т.к. dbm не задает фиксированного размера элементов сохраняемых данных и не требует описания внутренней структуры для них. Библиотека dbm работает с блоками неструктурированных двоичных данных.Примечание
В некоторых реализациях эти два файла объединены, и создается один новый файл.
Примечание
Важно помнить, что функция dbm_fetch возвращает только параметр типа datum, содержащий указатель на данные. Реальные данные могут находиться в локальной области памяти внутри библиотеки dbm и должны быть скопированы в переменные программы перед дальнейшими вызовами функций dbm.
Примечание
В последующих главах вы не раз встретитесь с заголовочным файлом базы данных cd_data.h и функциями из файла cd_access.c. Помните о том, что некоторые дистрибутивы Linux требуют немного отличающихся формирующих опций, например, применения в вашем файле на языке С заголовочного файла gdbm-ndbm.h вместо файла ndbm.h и опций -lgdbm_compat -lgdbm вместо просто опции -lgdbm. Если в вашем дистрибутиве Linux дело обстоит именно так, вы должны внести соответствующие изменения в файлы access.с и Makefile.
/* Функции инициализации и завершения */Примечание
Учтите, что некоторые функции возвращают структуры данных. Вы можете указать на аварийное завершение таких функций, сделав содержимое структур пустым.
8. В программе есть несколько участков, в которых хотелось бы спросить пользователя о том, уверен ли он в своем запросе. Вместо того чтобы вставлять в эти места программный код, задающий вопрос, поместим его в отдельную функцию get_confirm:Примечание
Учтите, что для выбора пунктов меню теперь используются номера, а не начальные буквы, применявшиеся в двух предыдущих примерах.
10. Теперь вы переходите к функции enter_new_track_entries для ввода информации о дорожке. Эта функция немного сложнее функции ввода элемента каталога, поскольку вы разрешаете существующему элементу-дорожке оставаться неизменным:Примечание
Обратите внимание на то, что вы не применяете функцию gets, поскольку нет способа проверить переполнение буфера. Всегда избегайте применения функции gets!
В этой главе обсуждаются следующие темы:Примечание
Более подробную информацию о PostgreSQL вы можете найти в нашей книге: Neil Matthew. Beginning Databases with PostgreSQL: From Novice to Professional. Second Edition. — Apress, 2005. (Мэттью H. Базы данных на примере PostgreSQL: от новичка до профессионала. Второе издание).
Для разработки приложений на базе MySQL вам придется установить не только сервер, но и библиотеки разработки. Как правило, в вашем диспетчере пакетов (package manager) есть вариант MySQL, нужно только убедиться в том, что установлены и библиотеки средств разработки. На рис. 8.1 показан диспетчер пакетов, готовый установить MySQL с дополнительным пакетом средств разработки, выделенным и готовым к установке.Примечание
Не используйте версии Debug при эксплуатации; производительность снижается из-за дополнительной поддержки отладочных средств.
Помните об имеющейся бреши в системе безопасности, упоминавшейся несколько разделов назад и позволяющей любому подключиться без пароля как пользователь root? Сейчас самое время усовершенствовать защиту. Не дайте сбить себя с толку имени пользователя root, применяемому во время установки MySQL. Между пользователем root СУРБД MySQL и пользователем root операционной системы нет никакой связи; MySQL просто регистрирует пользователя с именем "root" как администратора, что делает и ОС Linux. Пользователи базы данных MySQL и идентификаторы пользователей ОС Linux никак не связаны; у MySQL есть собственная встроенная система управления пользователями и правами доступа. По умолчанию пользователь с учетной записью в. вашей установленной системе Linux может зарегистрироваться на вашем сервере MySQL как администратор этой СУРБД. После того как вы ограничите права пользователя root СУРБД MySQL, например, разрешив только локальному пользователю регистрироваться с именем root и установив пароль для такого доступа, вы можете добавить только тех пользователей и только те права доступа, которые абсолютно необходимы для функционирования вашего приложения.Примечание
Если сервер не запускается или вы не можете подключиться к базе данных после запуска сервера, см. следующий раздел, посвященный неполадкам после вашей установки сервера.
Теперь рассмотрим таблицу прав доступа, чтобы убедиться в том, что пароль установлен. Сначала с помощью команды use переключитесь на базу данных mysql и затем запросите внутренние таблицы:Примечание
Обратите внимание на то, что мы завершаем команды на языке SQL точкой с запятой (;). Строго говоря; она не является частью команды SQL, а применяется для того, чтобы сообщить программе-клиенту MySQL о том, что наша команда SQL готова к выполнению. Мы также пользуемся прописными буквами для ввода ключевых слов языка SQL, например, SET. Это не обязательно, потому что действительный синтаксис MySQL допускает ввод ключевых слов как прописными, так и строчными буквами, но мы применяем первый вариант как принятое соглашение в данной книге и в нашей повседневной работе, т.к. считаем, что это облегчает чтение команд SQL.
Опция команды | Параметр | Описание |
---|---|---|
-u | username | По умолчанию утилиты mysql будут пытаться использовать то же username MySQL, что и текущее имя пользователя Linux. Применяйте параметр -u для задания другого имени пользователя |
-р | [password] | Если параметр -р задан, а пароль пропущен, он запрашивается. Если параметра -p нет в командной строке, команды MySQL полагают, что пароль не нужен |
-h | host | Применяется для подключения к серверу на другой машине (для локальных серверов всегда можно опускать) |
Примечание
И снова не советуем вам помещать пароль в командную строку, поскольку его можно увидеть с помощью команды ps.
Опция команды | Описание |
---|---|
-с | Ищет ошибки в таблицах |
-e | Выполняет расширенную проверку |
-r | Исправляет найденные ошибки |
Команда | Краткая форма | Описание |
---|---|---|
help или ? | \h или \? | Отображает список команд |
edit | \е | Редактирует команду. Применяемый редактор задается переменной окружения $EDITOR |
exit или quit | \q | Завершает программу-клиент MySQL |
go | \g | Выполняет команду |
source <имя_файла> | \. | Выполняет команды SQL из заданного файла |
status | \s | Отображает информацию о состоянии сервера |
system <команда> | \! | Выполняет системную команду |
tee <имя_файла> | \T | Добавляет в конец заданного файла копию всего вывода |
use <база_данных> | \u | Использует заданную базу данных |
Примечание
SQL92 — наиболее часто применяемая версия стандарта ANSI языка SQL. Ее назначение — формирование единообразия способов управления базами данных с применением SQL, обеспечивающего взаимодействие и взаимосвязь баз данных разных производителей.
Команда | Описание |
---|---|
create <база_данных> | Создает новую базу данных |
drop <база_данных> | Удаляет базу данных |
password <новый_пароль> | Изменяет пароль (как вы уже видели) |
ping | Проверяет, работает ли сервер |
reload | Повторно загружает таблицы полномочий, управляющие правами доступа |
status | Предоставляет сведения о состоянии сервера |
shutdown | Выключает сервер |
variables | Отображает переменные, управляющие работой MySQL, и их текущие значения |
version | Выводит номер версии сервера и время его работы |
Команда | Описание |
---|---|
--add-drop-table | Вставляет в файл вывода операторы SQL для удаления любых таблиц перед командой их создания |
-e | Применяет расширенный синтаксис вставки. Это нестандартный язык SQL, но если вы получаете дамп больших объемов информации, это поможет гораздо быстрее повторно загрузить дамп вашей базы в СУРБД MySQL |
-t | Получает дамп только данных из таблиц, а не информации, необходимой для создания таблиц |
-d | Получает дамп только структуры таблиц, а не реальных данных |
Значение | Описание |
---|---|
alter | Изменять таблицы и индексы |
create | Создавать базы данных и таблицы |
delete | Удалять данные из базы данных. |
drop | Удалять базы данных и таблицы |
index | Управлять индексами |
insert | Вставлять данные в базу данных |
lock tables | Разрешает блокировать таблицы |
select | Извлекать данные |
update | Изменять данные |
all | Все вышеперечисленные |
Примечание
Имейте в виду, что команда delete не относится к группе команд grant и revoke. Синтаксис SQL делает ее применение необходимым из-за способа обработки прав доступа в MySQL. Вы напрямую обновляете таблицы прав доступа MySQL (поэтому первой применяется команда use mysql) для внесения нужных вам изменений эффективным способом.
После обновления таблиц, как показано в примерах, вы должны применить команду FLUSH PRIVILEGES, чтобы сообщить серверу MySQL о необходимости перезагрузки таблиц с правами доступа.
Определение | Описание |
---|---|
CHAR | Одиночный символ |
CHAR(N) | Символьная строка длиной точно N символов, которая будет при необходимости заполняться пробелами. Максимальная длина 255 символов |
VARCHAR(N) | Массив переменной длины из N символов. Максимальная длина 255 символов |
TINYTEXT | Аналогичен VARCHAR(N) |
MEDIUMTEXT | Текстовая строка длиной до 65 535 символов |
LONGTEXT | Текстовая строка длиной до 2³²–1 символов |
Определение | Тип | Описание |
---|---|---|
TINYINT | Целочисленный | 8-битный тип данных |
SMALLINT | Целочисленный | 16-битный тип данных |
MEDIUMINT | 24-битный тип данных | |
INT | Целочисленный | 32-битный тип данных. Это стандартный тип и хороший выбор для данных общего назначения |
BIGINT | Целочисленный | 64-битный знаковый тип данных |
FLOAT(P) | С плавающей точкой | Числа с плавающей точкой с точностью как минимум P знаков |
DOUBLE(D, N) | С плавающей точкой | Числа с плавающей точкой и двойной точностью из D цифр и N десятичных знаков |
NUMERIC(P, S) | С плавающей точкой | Действительные числа длиной P разрядов всего с S десятичными разрядами из них. В отличие от DOUBLE это точно заданное число (exact number), поэтому оно больше подходит для хранения денежных сумм, но обрабатывается менее эффективно |
DECIMAL(Р, S) | С плавающей точкой | Синоним NUMERIC |
Определение | Описание |
---|---|
DATE | Хранит даты с 1 января 1000 г. по 31 декабря 9999 г. |
TIME | Хранит время с -838:59:59 до 838:59:59 |
TIMESTAMP | Хранит метку времени, начиная с 1 января 1970 г. и по 2037 г. |
DATETIME | Хранит даты с 1 января 1000 г. по последнюю секунду 31 декабря 9999 г. |
YEAR | Хранит номер года. Будьте осторожны с двузначными величинами, поскольку они неоднозначны и автоматически преобразуются в четырехзначные числа. |
Ключевое слово | Описание |
---|---|
AUTO INCREMENT | Это специальное ключевое слово сообщает MySQL о том, что, когда вы пишете в данный столбец NULL, следует автоматически заполнить столбец данными с помощью автоматически формируемого числа с наращением. Это чрезвычайно полезное средство; оно позволяет применять MySQL для автоматического назначения уникальных номеров строкам ваших таблиц, хотя оно может применяться только в столбцах, являющихся также первичными ключами. В других системах управления базами данных оно часто реализуется порядковым типом или управляется более явно с помощью последовательности |
NULL | Специальное значение в базе данных, обычно применяемое для обозначения "неизвестной" величины, но может также использоваться для обозначения "неподходящего" значения. Например, если вы заполняете таблицу подробными данными о сотрудниках, у вас может быть столбец с адресом электронной почты. В этом случае вы будете хранить NULL вместо адреса данного сотрудника, чтобы показать, что для конкретного человека эта информация не известна. Запись NOT NULL означает, что в этом столбце нельзя хранить значения NULL и может оказаться полезной для того, чтобы помешать вводу в такие столбцы значений NULL, если, например, значение всегда должно быть известно, как в случае фамилии сотрудника |
PRIMARY KEY | Указывает на то, что данные в этом столбце будут уникальными и разными во всех строках данной таблицы. У каждой таблицы может быть только один первичный ключ |
2. Вы также можете определить первичный ключ отдельно в определении столбца. Далее приведен пример интерактивного сеанса, в котором показан альтернативный синтаксис:Примечание
Обратите внимание на то, что в отличие от большинства языков программирования имя столбца (childno) указывается перед типом столбца (INTEGER).
После запуска MySQL Administrator вы сможете провести наблюдения при разной настройке и отслеживаемых параметрах. Это очень легкое в использовании средство, но у нас нет возможности в этой единственной главе вдаваться в подробности.Примечание
Напоминаем, что если вы до сих пор следовали инструкциям, то защитили свой сервер MySQL так, что пользователь root может подключиться к нему только с локальной машины и ни с какой другой машины в сети.
Enum-параметр | Действительный тип аргумента | Описание |
---|---|---|
MYSQL_ОРТ_CONNECT_TIMEOUT | const unsigned int* | Количество секунд ожидания перед закрытием подключения из-за простоя |
MYSQL_ОРТ_COMPRESS | Нет, используйте NULL | Применять сжатие при сетевом подключении |
MYSQL_INIT_COMMAND | const char* | Команда, отправляемая при каждом установлении подключения |
Получение данных в вашем приложении на языке С обычно будет включать четыре шага:Примечание
MySQL также поддерживает SQL-операторы SHOW, DESCRIBE и EXPLAIN, предназначенные для возврата результатов, но мы не собираемся рассматривать их в данной книге. Как обычно, в руководстве можно найти описание этих операторов.
После того как вы сделаете с вашими данными все, что нужно, вы должны явно применить функцию mysql_free_result, позволяющую библиотеке MySQL навести после себя порядок.Примечание
Эта пара функций очень полезна для перемещения между известными записями в результирующем наборе. Будьте внимательны и не путайте величину смещения, используемую функциями row_tell и row_seek со значением смещения, применяемым в функции data_seek. Иначе ваши результаты будут непредсказуемыми.
В чем же выигрыш от вызова функции mysql_use_result по сравнению с вызовом функции mysql_store_result? У первой из названных функций есть ряд существенных преимуществ, касающихся управления ресурсами; но ее нельзя применять с функциями mysql_data_seek, mysql_row_seek или mysql_row_tell и польза от применения mysql_num_rows ограничена, поскольку она не может нормально функционировать до тех пор, пока не будут извлечены все данные.Примечание
Для того чтобы действительно получить данные, следует многократно применять функцию mysql_fetch_row до тех пор, пока все данные не будут извлечены. Если вы не получите все данные от функции mysql_use_result, последующие операции в вашей программе, направленные на извлечение данных, могут вернуть поврежденную информацию.
Если оставить в стороне заботы о форматировании, вы уже знаете, как немедленно вывести данные. Добавьте простую функцию display_row в программу select2.c.Примечание
В программах, написанных для более ранних версий MySQL, вы можете встретить функцию mysql_num_fields. Она может принимать в качестве параметра указатель на структуру дескриптора подключения или структуру результата запроса и возвращает количество столбцов.
1. Далее приведена очень простая подпрограмма для вывода данных:Примечание
Обратите внимание на то, что для упрощения примера данные о подключении, результате и строке, полученные из функции mysql_fetch_row, все сделаны глобальными. В рабочей программе мы не рекомендуем делать это.
Поле в структуре типа MYSQL_FIELD | Описание |
---|---|
char *name; | Имя столбца в виде строки |
char *table; | Имя таблицы, из которой получен столбец. Оно особенно полезно в запросе с использованием нескольких таблиц. Имейте в виду, что вычисляемое значение в результате, такое как MAX, будет иметь пустую строку для имени таблицы |
char *def; | При вызове функции mysql_list_fields (которую мы не обсуждаем) это поле содержит значение в столбце по умолчанию |
enum enum_field_types type; | Тип столбца. См. пояснения сразу после таблицы |
unsigned int length; | Ширина столбца, заданная при определении таблицы |
unsigned int max_length; | Если применяется функция mysql_store_result, это поле содержит длину в байтах самого длинного извлеченного значения столбца. Если применяется функция mysql_use_result, поле не задается |
unsigned int flags; | Флаги содержат информацию об определении столбца, а не о найденных данных. у распространенных флагов очевидные значения: NOT_NULL_FLAG, PRI_KEY_FLAG, UNSIGNED_FLAG, AUTO_INCREMENT_FLAG и BINARY_FLAG. Полный список флагов можно найти в документации MySQL |
unsigned int decimals; | Количество знаков после десятичной точки. Справедливо только для числовых полей |
Пример API-вызова | Описание |
---|---|
char *mysql_get_client_info(void); | Возвращает данные о версии библиотеки, используемой клиентской программой |
char *mysql_get_host_info(MYSQL *connection); | Возвращает информацию о подключении к серверу |
char *mysql_get_server_info(MYSQL *connection); | Возвращает информацию о сервере, к которому вы в данный момент подключены |
char *mysql_info(MYSQL* connection); | Возвращает информацию о самом последнем выполненном запросе, но работает только с запросами нескольких типов — обычно с операторами INSERT и UPDATE. В противном случае возвращает NULL |
int mysql_select_db(MYSQL *connection, const char *dbname); | Заменяет базу данных, применяемую по умолчанию, на заданную в качестве параметра, при условии, что у пользователя есть соответствующие права доступа. В случае успеха возвращает ноль |
int mysql_shutdown(MYSQL* connection, enum mysql_enum_shutdown level); | Если у вас есть соответствующие права, завершает работу сервера базы данных, к которому вы подключены. В этот момент уровень останова следует задать равным SHUTDOWN_DEFAULT. В случае успеха возвращает ноль |
Теперь самое время убедиться в том, что ваши данные выглядят осмысленно. Для этого можно применить программу-клиент mysql в режиме командной строки и SQL-операторы. Начните с выбора двух первых дорожек из каждого альбома в вашей базе данных.Примечание
Обратите внимание на то, что в cd_id=5 ("I Giorni") с track=3 название In un'altra vita содержит апостроф. Для вставки его в базу данных вы должны использовать обратный слэш (\).
Примечание
Команда make применяется не только для компиляции программ. Ее можно использовать, когда формируются выходные файлы из нескольких входных файлов. Ещё одно ее применение включает обработку документов (такую же, как с помощью программ troff или ТеХ).
А теперь выполните упражнение 9.1.Примечание
В данный момент мы должны информировать вас об очень странной и неудачной синтаксической записи, применяемой в make-файлах: разнице между пробелом и табуляцией. Все правила должны представлять собой строки, начинающиеся со знака табуляции; пробел не годится. Так как несколько пробелов и табуляция выглядят почти одинаково и поскольку почти во всех других случаях, касающихся программирования в системе Linux, нет большой разницы между пробелами и табуляциями, это может вызвать проблемы. Кроме того, пробел в конце строки в make-файле может вызвать сбой при выполнении команды make. Тем не менее, это исторический факт и в наше время слишком много make-файлов находится в обращении, чтобы можно было рассчитывать на изменение положения вещей, поэтому будьте внимательны! К счастью, если команда make не работает из-за пропущенной табуляции, это обычно довольно понятно.
Макрос | Определение |
---|---|
$? | Список необходимых условий (файлов, от которых зависит выходной файл), измененных позже, чем текущий выходной файл |
$@ | Имя текущего задания |
$< | Имя текущего файла, от которого зависит выходной |
$* | Имя без суффикса текущего файла, от которого зависит выходной |
Примечание
Если вы предпочитаете сохранять RCS-файлы в отдельном каталоге, просто создайте подкаталог с именем RCS перед первым применением команды rcs. Все команды rcs будут автоматически использовать подкаталог RCS для RCS-файлов.
Вы сохранили обновленную версию файла. Если сейчас заглянуть в каталог, можно увидеть, что файл important.c снова удален.Примечание
Для записи изменений и сохранения блокировки, разрешающей пользователю продолжить работу с файлом, следует вызвать команду ci с опцией -l. Файл будет автоматически снова извлечен в каталог для того же самого пользователя.
Теперь, если вы хотите вернуть первую версию файла, можно запросить команду со, указав нужную версию.Примечание
Учтите, что время модификации файла записывается без учета летнего времени, чтобы избежать проблем при переводе часов.
RCS | SCCS |
---|---|
rcs | admin |
ci | delta |
со | get |
rcsdiff | sccsdiff |
ident | what |
CVS | Subversion |
---|---|
cvs -d /usr/local/repository init | svnadmin create /usr/local/repository |
cvs import wrox/chap9-cvs | svn import cvs-sp file:///usr/local/repository/trunk |
cvs checkout wrox/chap9-cvs | svn checkout file:///usr/local/repository/trunk cvs-sp |
cvs diff | svn diff |
cvs rdiff | svn diff tag1 tag2 |
cvs update | svn status -u |
cvs commit | svn commit |
Примечание
Если вы нашли и исправили ошибку в программе, легче, точнее и вежливее отправить автору исправленный файл, а не просто описание исправления.
RPM-каталог | Описание |
---|---|
BUILD | Команда rpmbuild создает программное обеспечение в этом каталоге |
RPMS | Команда rpmbuild хранит в этом каталоге созданные ею двоичные файлы |
SOURCES | В этот каталог следует поместить исходные файлы для вашего приложения |
SPECS | В этот каталог следует помещать файлы spec для всех RPM-пакетов, которые вы планируете создать, хотя это и не обязательно |
SRPMS | Команда rpmbuild помещает в этот каталог RPM-пакеты из исходных файлов |
После того как исходные файлы для вашего RPM-пакета будут собраны вместе, нужно создать файл spec, описывающий, как именно команда rpmbuild должна создать ваш пакет.Примечание
Этот каталог специфичен для системы Red Hat Linux. В других дистрибутивах Linux используются иные каталоги, например каталог /usr/src/packages.
Кроме того, разработчики RPM-системы мудро решили не пытаться заменить популярные средства построения программ, такие как make или configure. RPM-система содержит много средств быстрого доступа, позволяющих воспользоваться make-файлами и сценариями configure.Примечание
Хорошими источниками примеров файлов spec служат другие RPM-пакеты. Посмотрите RPM-пакеты исходных файлов, хранящиеся в файлах с окончанием .src.rpm. Установите эти RPM-пакеты и просмотрите их файлы spec. Вы найдете гораздо более сложные примеры, чем те, которые вам когда-либо понадобятся. Интересные примеры можно найти среди файлов spec, предназначенных для пакетов anonftp, telnet, vnc и sendmail.
Задание %clean удаляет файлы, созданные командой rpmbuild. Например:Примечание
Если вы пользуетесь сценарием configure для создания make-файла, все разнообразные каталоги в нем будут заданы должным образом. В большинстве случаев вам не придется задать все команды установки вручную, как. показано в предыдущем примере.
Опция | Описание |
---|---|
-ba | Создавать и двоичный, и исходный RPM-пакет |
-bb | Создавать двоичный RPM-пакет |
-bc | Компилировать программу, но не создавать полный RPM-пакет |
-bp | Подготовиться к созданию двоичного RPM-пакета |
-bi | Создать двоичный RPM-пакет и установить его |
-bl | Проверить список файлов RPM-пакета |
-bs | Создать только RPM-пакет исходных файлов |
Примечание
Пакеты должен устанавливать суперпользователь. Создавать пакеты от имени пользователя root нет необходимости, если у вас есть права на запись в каталоги RPM-системы, обычно это каталоги /usr/src/redhat. Как правило, не следует создавать RPM-пакеты как пользователь root, потому что в файле spec могут быть команды, способные повредить вашу систему.
Среда разработки | Тип | URL программного продукта |
---|---|---|
Eclipse | Платформа на базе языка Java и IDE | http://www.eclipse.org |
Anjuta | IDE для пользовательского графического интерфейса GNOME | http://anjuta.sourceforge.net/ |
QtEZ | IDE для пользовательского графического интерфейса KDE | http://projects.uid0.sk/qtez/ |
SlickEdit | Коммерческий редактор кода с поддержкой многих языков | http://www.slickedit.com/ |
□ Попытайтесь выполнить основную часть программы на бумаге, этот процесс называют формальным прогоном. Для наиболее важных подпрограмм запишите значения на входе и вычислите шаг за шагом выходные значения. Для отладки совсем не обязательно всегда применять компьютер, иногда именно компьютер создает проблемы. Даже разработчики, пишущие библиотеки, компиляторы и операционные системы, делают ошибки! С другой стороны, не спешите винить во всем используемые программные средства; гораздо вероятнее, что ошибка закралась в вашу новую программу, а не в компилятор.Примечание
Языки программирования с компиляторами, такие как С, обладают возможностью поймать синтаксические ошибки в процессе компиляции, в то время как интерпретируемые языки, например язык командной оболочки Linux, могут обнаружить синтаксические ошибки только тогда, когда вы попытаетесь выполнить программу. Если проблема в коде обработки ошибки, нелегко будет выявить ее в ходе тестирования.
Когда вы исследуете проблемы доступа к элементам массива, часто полезно увеличить размер этих элементов, поскольку это увеличит размер ошибки. Если вы читаете единственный байт за пределами массива байтов, это может вам сойти с рук, т.к. память, выделенная программе, будет округляться до величины, зависящей от операционной системы, возможно, равной 8 Кбайт.Примечание
Некоторые библиотечные функции, такие как printf, в определенных обстоятельствах также будут препятствовать некорректному доступу, например при использовании указателя null.
Существуют средства, которые могут помочь в анализе кода, одно из самых очевидных — компилятор. Он сообщит вам о любых имеющихся в вашей программе синтаксических ошибках.Примечание
Анализ кода — это термин, применяемый для обозначения более формального процесса, в ходе которого группа разработчиков тщательно просматривает несколько сотен строк программного кода, но масштаб не имеет значения, это все равно анализ кода, и он остается очень полезным методом поиска ошибок.
Чуть позже мы кратко обсудим и другие средства, lint и splint. Как и компилятор, они анализируют код и сообщают о фрагментах кода, которые могут быть некорректными.Примечание
У некоторых компиляторов есть опции, формирующие предупреждения в сомнительных случаях, таких как отсутствие инициализации переменных или применение присваиваний в условиях. Например, компилятор GNU можно запускать со следующими опциями:
gcc -Wall -pedantic -ansi
Они порождают много предупреждений и дополнительных проверок на соответствие стандартам языка С. Рекомендуем взять за правило использование этих опций, особенно Wall. Она генерирует полезную информацию при обнаружении ошибок в программе.
Макрос | Описание |
---|---|
__LINE__ | Десятичная константа, предоставляющая номер текущей строки |
__FILE__ | Строка, предоставляющая имя текущего файла |
__DATE__ | Строка в форме "ммм дд гггг", текущая дата |
__TIME__ | Строка в форме "чч:мм:сс", текущее время |
Примечание
Удалить отладочную информацию из исполняемого файла без повторной компиляции можно, выполнив команду strip <файл>.
Примечание
Эти утилиты и другие, упоминаемые в этой главе, могут не входить в состав вашего дистрибутива Linux. Если они пропущены, можно поискать их реализации в Интернете. Хорошая отправная точка (для дистрибутивов Linux, поддерживающих формат RPM-пакетов) — Web-сайты http://rpmfind.net и http://rpm.pbone.net. Можно попытаться поискать в нескольких репозитариях для конкретных дистрибутивов, включая http://ftp.gwdg.de/pub/opensuse/ для openSUSE, http://rpm.livna.org для Fedora и http://packages.slackware.it/ для Slackware.
Примечание
Точная синтаксическая запись команды ps и формат вывода могут немного отличаться в разных системах. Версия GNU команды ps, применяемая в Linux, поддерживает опции, взятые из нескольких предшествующих реализаций ps, включая варианты из UNIX-систем BSD и AT&T, и добавляет множество своих опций. См. интерактивное справочное руководство для получения подробных сведений о доступных опциях и форматах вывода команды ps.
Код STAT | Описание |
---|---|
S | Спящий. Обычно ждет появления события, такого как сигнал или активизация ввода |
R | Выполняющийся. Строго говоря "работоспособный", т.е. в очереди на выполнение, либо выполняющийся, либо готовый к выполнению |
D | Непрерывно спящий (ожидающий). Обычно ждущий завершения ввода или вывода |
T | Остановленный. Обычно остановленный системой управления заданиями командной оболочки или находящийся под контролем отладчика |
Z | Умерший или процесс-зомби |
N | Задача с низким приоритетом, "nice" |
W | Разбитый на страницы (не используется в Linux с ядром версии 2.6 и последующих версий) |
S | Ведущий процесс сеанса |
+ | Процесс в группе фоновых процессов |
l | Многопотоковый процесс |
< | Задача с высоким приоритетом |
Примечание
Вообще применение функции system — далеко не идеальный способ создания процессов, потому что запускаемая программа использует командную оболочку. Он неэффективен вдвойне: и потому что перед запуском программы запускается оболочка, и потому что сильно зависим от варианта установки командной оболочки и применяемого окружения. В следующем разделе вы увидите гораздо более удачный способ запуска программ, который почти всегда предпочтительней применения вызова system.
Макрос | Описание |
---|---|
WIFEXITED(stat_val) | Ненулевой, если дочерний процесс завершен нормально |
WEXITSTATUS(stat_val) | Если WIFEXITED ненулевой, возвращает код завершения дочернего процесса |
WIFSIGNALED(stat_val) | Ненулевой, если дочерний процесс завершается неперехватываемым сигналом |
WTERMSIG(stat_val) | Если WIFSIGNALED ненулевой, возвращает номер сигнала |
WIFSTOPPED(stat_val) | Ненулевой, если дочерний процесс остановился |
WSTOPSIG(stat_val) | Если WIFSTOPPED ненулевой, возвращает номер сигнала |
Имя сигнала | Описание |
---|---|
SIGABORT | *Процесс аварийно завершается |
SIGALRM | Сигнал тревоги |
SIGFPE | *Исключение операции с плавающей точкой |
SIGHUP | Неожиданный останов или разъединение |
SIGILL | *Некорректная команда |
SIGINT | Прерывание терминала |
SIGKILL | Уничтожение (не может быть перехвачен или игнорирован) |
SIGPIPE | Запись в канал без считывателя |
SIGQUIT | Завершение работы терминала |
SIGSEGV | *Некорректный доступ к сегменту памяти |
SIGTERM | Завершение, выход |
SIGUSR1 | Сигнал 1, определенный пользователем |
SIGUSR2 | Сигнал 2, определенный пользователем |
Имя сигнала | Описание |
---|---|
SIGCHLD | Дочерний процесс остановлен или завершился |
SIGCONT | Продолжить выполнение, если процесс был приостановлен |
SIGSTOP | Остановить выполнение (не может захватываться или игнорироваться) |
SIGTSTP | Сигнал останова, посылаемый с терминала |
SIGTTIN | Фоновый процесс пытается читать |
SIGTTOU | Фоновый процесс пытается писать |
Как это работаетПримечание
Вызывать из обработчика сигнала все функции, например, printf, небезопасно. Удобный метод — использовать флаг, устанавливаемый в обработчике сигнала, и затем проверять этот флаг в функции main и выводить сообщение, если нужно. В конце этой главы вы найдете список вызовов, которые можно безопасно применять в теле обработчиков сигналов.
Функция signal возвращает предыдущее значение обработчика для заданного типа сигнала, если таковой есть, или в противном случае SIG_ERR с установкой положительного значения в переменной errno. Если задан неверный сигнал или делается попытка обработать сигнал, который не может быть перехвачен или игнорироваться, например SIGKILL, переменной errno присваивается значение EINVAL.Примечание
Мы не рекомендуем вам пользоваться функцией signal для перехвата сигналов. Мы включили ее в книгу, потому что она будет часто встречаться в более старых программах. Позже вы увидите sigaction, более четко определенный и надежный интерфейс, который следует применять в новых программах.
Примечание
После выполнения программы вы можете обнаружить дамп ядра (в файле core). Его можно безбоязненно удалить.
Имя сигнала | Описание |
---|---|
SA_NOCLDSTOP | Не генерируется SIGCHLD, когда дочерние процессы остановлены |
SA_RESETHAND | Восстанавливает при получении действие, соответствующее значению SIG_DFL |
SA_RESTART | Перезапускает прерванные функции вместо ошибки EINTR |
SA_NODEFER | При перехвате сигнала не добавляет его а маску сигналов |
access | alarm | cfgetispeed | cfgetospeed |
cfsetispeed | cfsetospeed | chdir | chmod |
chown | close | creat | dup2 |
dup | execle | execve | exit |
fcntl | fork | fstat | getegid |
geteuid | getgid | getgroups | getpgrp |
getpid | getppid | getuid | kill |
link | lseek | mkdir | mkfifo |
open | pathconf | pause | pipe |
read | rename | rmdir | setgid |
setpgid | setsid | setuid | sigaction |
sigaddset | sigdelset | sigemptyset | sigfillset |
sigismember | signal | sigpending | sigprocmask |
sigsuspend | sleep | stat | sysconf |
tcdrain | tcflow | tcflush | tcgetattr |
tcgetpgrp | tcsendbreak | tcsetattr | tcsetpgrp |
time | times | umask | uname |
unlink | utime | wait | waitpid |
write |
Имя сигнала | Описание |
---|---|
SIGALRM | Генерируется таймером, установленным функцией alarm |
SIGHUP | Посылается управляющему процессу отключающимся терминалом или управляющим процессом во время завершения каждому процессу с высоким приоритетом |
SIGINT | Обычно возбуждается с терминала при нажатии комбинации клавиш <Ctrl>+<C> или сконфигурированного символа прерывания |
SIGKILL | Обычно используется из командной оболочки для принудительного завершения процесса с ошибкой, т.к. этот сигнал не может быть перехвачен или проигнорирован |
SIGPIPE | Генерируется при попытке записи в канал при отсутствии связанного с ним считывателя |
SIGTERM | Отправляется процессу как требование завершиться. Применяется UNIX при выключении для запроса остановки системных сервисов. Это сигнал, по умолчанию посылаемый командой kill |
SIGUSR1, SIGUSR2 | Может использоваться процессами для взаимодействия друг с другом, возможно, чтобы заставить их сообщить информацию о состоянии |
Имя сигнала | Описание |
---|---|
SIGFPE | Генерируется исключительной ситуацией во время операций с плавающей точкой |
SIGILL | Процессор выполнил недопустимую команду. Обычно возбуждается испорченной программой или некорректным модулем совместно используемой памяти |
SIGQUIT | Обычно возбуждается с терминала при нажатии комбинации клавиш <Ctrl>+<\> или сконфигурированного символа завершения (quit) |
SIGSEGV | Нарушение сегментации, обычно возбуждается при чтении из некорректного участка памяти или записи в него, а также выход за границы массива или разыменование неверного указателя. Перезапись локального массива и повреждение стека могут вызвать сигнал SIGSEGV при возврате функции по неверному адресу |
Имя сигнала | Описание |
---|---|
SIGSTOP | Останавливает выполнение (не может быть захвачен или проигнорирован) |
SIGTSTP | Сигнал останова терминала часто возбуждается нажатием комбинации клавиш <Ctrl>+<Z> |
SIGTTIN, SIGTTOU | Применяются командной оболочкой для обозначения того, что фоновые задания остановлены, т.к. им необходимо прочесть данные с терминала или выполнить вывод |
Имя сигнала | Описание |
---|---|
SIGCONT | Продолжает выполнение, если процесс остановлен |
SIGCHLD | Возбуждается, когда останавливается или завершается дочерний процесс |
Когда поток завершается, он вызывает функцию pthread_exit, во многом так же, как процесс во время завершения вызывает exit. Функция завершает вызванный поток, возвращая указатель на объект. Никогда не применяйте ее для возврата указателя на локальную переменную, потому что переменная перестает существовать, когда поток завершается, вызывая серьезную ошибку. Функция pthread_exit объявляется следующим образом:Примечание
pthread_create как большинство функций семейства pthread_ относится к тем немногим функциям Linux, которые не соблюдают соглашение об использовании значения -1 для обозначения ошибок. Если нет полной уверенности, всегда безопаснее всего дважды проверить справочное руководство перед проверкой кода возврата.
4. Когда вы выполните эту программу, то увидите следующие строки:Примечание
Если в вашей системе по умолчанию установлена NPTL (что очень вероятно), почти наверняка вам не нужны опции -I и -L, и можно применить более простой вариант:
$ cc -D_REENTRANT thread1.с -о thread1 -lpthread
В данной главе мы будем применять этот более простой вариант строки компиляции.
int run_now = 1;Примечание
Файлы с полными текстами примеров можно загрузить с Web-сайта книги.
Последняя функция семафоров — sem_destroy. Она очищает семафор, когда вы закончили работу с ним, и объявляется следующим образом:Примечание
Есть и другая функция семафора sem_trywait — это неблокирующий партнер sem_wait. Мы не будем ее обсуждать в книге в дальнейшем, дополнительную информацию см. в интерактивном справочном руководстве.
Параметр oldtype позволяет получить предыдущее состояние, если оно вас не интересует, можно передать NULL. По умолчанию потоки запускаются с состоянием отмены, равным PTHREAD_CANCEL_ENABLE, и типом отмены — PTHREAD_CANCEL_DEFERRED.Примечание
В соответствии со стандартом POSIX системные вызовы, способные задерживать выполнение, такие как read, wait и т.д., должны также быть точками отмены потока. Во время написания книги поддержка этого стандарта в ОС Linux представлялась незавершенной. Но кое-какая работа была проделана, скажем, некоторые задерживающие вызовы, такие как sleep, на самом деле допускают отмену. Для того чтобы обезопасить себя, добавляйте вызовы pthread_testcancel в программный код, который по вашим расчетам может быть отменен.
Примечание
На самом деле wc -l popen*.c легче и гораздо эффективнее ввести с клавиатуры, но пример иллюстрирует основные принципы использования каналов.
В упражнении 13.5 приведена программа pipe1.с, которая использует вызов pipe для создания канала.Примечание
Важно уяснить, что речь идет о файловых дескрипторах, а не о файловых потоках, поэтому для доступа к данным вы должны применять низкоуровневые системные вызовы read и write вместо библиотечных функций потоков fread и fwrite.
Итак, как же dup помогает в обмене данными между процессами? Хитрость кроется в знании того, что дескриптор стандартного файла ввода всегда 0 и что dup всегда возвращает новый файловый дескриптор, применяя наименьший доступный номер. Сначала закрыв дескриптор 0, а затем вызвав dup, вы получите новый файловый дескриптор с номером 0. Поскольку новый файловый дескриптор — это дубликат существующего, стандартный ввод изменится и получит доступ к файлу или каналу, файловый дескриптор которого вы передали в функцию dup. В результате вы создадите два файловых дескриптора, которые ссылаются на один и тот же файл или канал и один из них будет стандартным вводом.Примечание
Того же эффекта, что и применение вызовов dup и dup2 можно добиться, применяя более общий вызов fcntl с командой F_DUPFD. Как говорилось, вызов dup легче использовать, поскольку он разработан специально для создания дубликатов файловых дескрипторов. Он также очень широко применяется, поэтому вы встретите его гораздо чаще в существующих программах, чем вызов fcntl и команду F_DUPFD.
Номер файлового дескриптора | Первоначально | После закрытия файлового дескриптора 0 | После вызова dup |
---|---|---|---|
0 | Стандартный ввод | {closed} | Файловый дескриптор канала |
1 | Стандартный вывод | Стандартный вывод | Стандартный вывод |
2 | Стандартный поток ошибок | Стандартный поток ошибок | Стандартный поток ошибок |
3 | Файловый дескриптор канала | Файловый дескриптор канала | Файловый дескриптор канала |
Внутри программы можете применять два разных вызова:Примечание
У некоторых более старых версий UNIX была только команда mknod. В стандарте X/Open issue 4 Version 2 есть вызов функции mknod, но не программа командной строки. ОС Linux, как всегда настроенная дружелюбно, предлагает оба варианта: mknod и mkfifo.
Примечание
В отличие от канала, созданного вызовом pipe, FIFO существует как именованный файл, но не как открытый файловый дескриптор, и должен быть открыт перед тем, как можно будет из него читать данные или в него записывать их. Открывается и закрывается канал FIFO с помощью функций open и close, которые вы ранее применяли к файлам, но с дополнительными функциональными возможностями. Вызову open передается полное имя FIFO вместо полного имени обычного файла.
Выполните упражнение 13.11.Примечание
Обратите внимание на асимметрию в использовании O_NONBLOCK с O_RDONLY и O_WRONLY, заключающуюся в том, что неблокирующий вызов open для записи завершается аварийно, если ни один процесс не открыл канал для чтения, а неблокирующий вызов open для чтения не возвращает ошибку. На поведение вызова close флаг O_NONBLOCK влияния не оказывает.
Примечание
Когда процесс в ОС Linux заблокирован, он не потребляет ресурсы ЦП, поэтому этот метод синхронизации очень эффективен с точки зрения использования ЦП.
#include <unistd.h>Примечание
Поскольку пример иллюстративный, нас не интересуют конкретные данные, и мы не беспокоимся об инициализации буфера, В обоих листингах затененные строки содержат изменения, внесенные в программу fifo2.c помимо удаления кода со всеми аргументами командной строки.
Вывод команды time показывает, что читающему процессу потребовалось гораздо меньше одной десятой секунды для считывания 10 Мбайт данных в процесс. Это свидетельствует о том, что каналы, по крайней мере, их реализация в современных версиях Linux, могут быть эффективным средством обмена данными между программами.Примечание
ОС Linux так организует планирование двух процессов, что они оба выполняются, когда могут, и заблокированы в противном случае. Следовательно, пишущий процесс блокируется, когда канал полон, а читающий — когда канал пуст.
Выполнение команды server -i позволяет программе инициализировать новую базу данных компакт-дисков.Примечание
Как было показано ранее в главе 7, в различных дистрибутивах файлы dbm именуются и устанавливаются немного по-разному. Если предоставленные файлы не компилируются в вашем дистрибутиве, вернитесь к главе 7 и поищите сведения об именах и местонахождении файлов dbm.
Первый оператор typedef задает тип запроса, отправляемого на сервер; второй описывает тип серверного ответа клиенту.Примечание
Это хорошая возможность для компилятора выполнить дополнительную проверку типов и помочь в отладке приложения, т.к. многие отладчики могут показывать имена перечислимых констант, но не имена, определенные директивой #define.
typedef struct {Примечание
Поскольку на самом деле вам не нужно возвращать cdc_entry и cdt_entry в одном ответе, вы могли бы сделать их объединением (union). Но для простоты можно оставить их отдельными элементами, кроме того, в этом случае легче поддерживать программный код.
Примечание
Как вы видели в главе 10, может быть определено символическое имя DEBUG_TRACE для того, чтобы показать последовательность вызовов, в которых клиентский и серверный процессы передают друг другу сообщения.
Написать программный код общего назначения, который гарантирует одной программе монопольный доступ к конкретному ресурсу, на удивление сложно, несмотря на то, что существует решение, известное как алгоритм Деккера (Dekker's Algorithm). К сожалению, этот алгоритм полагается на состояние активного ожидания или спин-блокировки, в котором процесс выполняется непрерывно, ожидая изменения адреса памяти. В многозадачной среде, какой является ОС Linux, это нежелательные расходы ресурсов ЦПУ. Ситуация существенно облегчается, когда для обеспечения монопольного доступа есть аппаратная поддержка, обычно в виде специальных команд ЦПУ. Примером аппаратной поддержки могла бы быть команда обращения к ресурсу и приращения регистра атомарным образом, так чтобы никакая другая команда (даже прерывание) не могла появиться между операциями чтения/инкремента/записи.Примечание
Функции семафоров, применяемые в потоках и обсуждавшиеся в главе 12, не относятся к наиболее общим функциям, которые мы рассматриваем в этой главе, поэтому будьте внимательны и не путайте функции этих двух типов.
Операция | Описание |
---|---|
Р(sv) | Если sv больше нуля, она уменьшается на единицу. Если sv равна 0, выполнение данного процесса приостанавливается |
V(sv) | Если какой-то другой процесс был приостановлен в ожидании семафора sv, переменная заставляет его возобновить выполнение. Если ни один процесс не приостановлен в ожидании семафора sv, значение переменной увеличивается на единицу |
Обратите внимание на то, что параметр key действует во многом как имя файла, т.к. он тоже представляет ресурс, который программы могут использовать и кооперироваться при этом, если соблюдают соглашение об общем имени для него. Аналогичным образом идентификатор, возвращаемый функцией semget и применяемый другими функциями, совместно использующими память, очень похож на файловый поток FILE*, возвращаемый функцией fopen и представляющий собой значение, применяемое процессом для доступа к совместно используемому файлу. Как и в случае файлов, у разных процессов будут разные идентификаторы семафоров, несмотря на то, что они ссылаются на один и тот же семафор. Такое применение ключа и идентификаторов — общее для всех средств IPC, обсуждаемых здесь, несмотря на то, что каждое средство применяет независимые ключи и идентификаторы.Примечание
Обычно заголовочный файл sys/sem.h опирается на два других заголовочных файла: sys/types.h и sys/ipc.h. Как правило, они автоматически включаются в программу файлом sys/sem.h и вам не нужно задавать их явно в директивах #include.
Прорабатывая каждую функцию отдельно, помните о том, что все они спроектированы для использования массивов значений семафоров, что делает их работу существенно более сложной, чем та, что необходима для обработки одного семафора.
Значение | Описание |
---|---|
IPC_STAT | Задаёт данные в структуре shmid_ds, отображающие значения, связанные с совместно используемой памятью |
IPC_SET | Устанавливает значения, связанные с совместно используемой памятью в соответствии с данными из структуры типа shmid_ds, если у процесса есть право на это действие |
IPC_RMID | Удаляет сегмент совместно используемой памяти |
Значение | Описание |
---|---|
IPC_STAT | Задает данные в структуре msqid_ds, отображающие значения, связанные с очередью сообщений |
IPC_SET | Если у процесса есть на это право, это действие устанавливает значения, связанные с очередью сообщений, в соответствии с данными структуры msqid_ds |
IPC_RMID | Удаляет очередь сообщений |
Несмотря на то, что у машин в Интернете почти всегда есть имена, их преобразуют в IP-адреса. Пример IP-адреса — 192.168.1.99. Все IP-адреса представлены четырьмя числами, каждое из которых меньше 256, и образуют так называемые четверки с точками. Когда клиент подключается по сети с помощью сокетов, ему нужен IP- адрес компьютера сервера.Примечание
Для преодоления некоторых проблем стандартного протокола IP существенно ограниченного количества доступных адресов был разработан интернет-протокол нового поколения IPv6. Он использует другой домен сокетов AF_INET6 и иной формат адресов. Ожидается, что со временем IPv6 заменит IP, но для этого потребуется много лет. Несмотря на то, что уже есть реализации IPv6 для Linux, их обсуждение выходит за рамки этой книги.
Примечание
TCP/IP — сокращение для протоколов Transmission Control Protocol/Internet Protocol. Протокол IP — низкоуровневый протокол передачи пакетов, обеспечивающий выбор маршрута при пересылке данных в сети от одного компьютера к другому. Протокол TCP обеспечивает упорядочивание, управление потоком и ретрансляцию, гарантирующие полную и корректную передачу больших объемов данных или же сообщение о соответствующей ошибочной ситуации.
Домен | Описание |
---|---|
AF_UNIX | Внутренние для UNIX (сокеты файловой системы) |
AF_INET | Интернет-протоколы ARPA (Advanced Research Projects Agency, управление перспективных исследований и разработок) (сокеты сети UNIX) |
AF_ISO | Протоколы стандарта ISO (International Standards Organization, Международная организация по стандартизации) |
AF_NS | Протоколы сетевых систем Xerox |
AF_IPX | Novell-протокол IPX |
AF_APPLETALK | Appletalk DDS (Appletalk Digital Data Service) |
Значение errno | Описание |
---|---|
EBADF | Неверный файловый дескриптор |
ENOTSOCK | Файловый дескриптор не ссылается на сокет |
EINVAL | Файловый дескриптор ссылается на сокет, уже получивший имя |
EADDRNOTAVAIL | Недопустимый адрес |
EADDINUSE | У адреса уже есть связанный с ним сокет |
Для сокетов домена AF_UNIX есть несколько дополнительных значений | |
EACCESS | Невозможно создать имя в файловой системе из-за прав доступа |
ENOTDIR, ENAMETOOLONG | Означает недопустимое имя файла |
Значение errno | Описание |
---|---|
EBADF | В параметре socket задан неверный файловый дескриптор |
EALREADY | Для этого сокета соединение уже обрабатывается |
ETIMEDOUT | Допустимое время ожидания соединения превышено |
ECONNREFUSED | Запрос на соединение отвергнут сервером |
Вы будете выполнять ваши серверную и клиентскую программы в локальной сети, но сетевые сокеты полезны не только в локальной сети, любая машина с подключением к Интернету (даже по модемной линии связи) может применять сетевые сокеты для обмена данными с другими компьютерами. Программу, основанную на сетевых подключениях, можно применять даже на изолированном компьютере с ОС UNIX, т. к. такой компьютер обычно настроен на использование виртуальной сети или внутренней петли (loopback network), включающей только его самого. Для демонстрационных целей данный пример использует виртуальную сеть, которая может быть также полезна для отладки сетевых приложений, поскольку она устраняет любые внешние сетевые проблемы.Примечание
Вам следует знать, что в программах client2.c и server2.c умышленно допущена ошибка, которую вы устраните в программах client3.c и server3.c. Пожалуйста, не используйте текст примеров client2.c и server2.c в собственных программах.
Вы сможете увидеть номера портов, присвоенные соединению сервера с клиентом. Локальный адрес отображает сервер, а внешний адрес — удаленного клиента. (Даже если клиент размещен на той же машине, он все равно подключается через сеть.) Для четкого разделения всех сокетов порты клиентов обычно отличаются от сокета сервера, ожидающего запросы на соединения, и уникальны в пределах компьютера.Примечание
Прежде чем испытывать последующие примеры этой главы, убедитесь в том, что завершено выполнение серверных программ-примеров, поскольку они будут конкурировать при приеме соединений клиентов, и вы увидите вводящие в заблуждение результаты. Удалить их все (включая те, что будут приведены позже в этой главе) можно с помощью следующей команды:
killall server1 server2 server3 server4 server5
Примечание
Если вы пользуетесь компьютером, у которого собственный формат представления целых совпадает с сетевым порядком следования байтов, вы не увидите никакой разницы. Но для обеспечения корректного взаимодействия клиентов и серверов с разной архитектурой важно всегда применять функции преобразования.
Программа xinetd обычно настраивается с помощью пользовательского графического интерфейса для управления сетевыми сервисами, но вы можете изменять и непосредственно файлы конфигурации программы. К ним относятся файл /etc/xinetd.conf и файлы в каталоге /etc/xinetd.d.Примечание
В современных системах Linux роль интернет-демона исполняет программа xinetd. Она заменила оригинальную UNIX-программу inetd, которую вы все еще можете встретить в более ранних системах Linux и других UNIX-подобных системах.
Параметр | Описание |
---|---|
SO_DEBUG | Включает отладочную информацию |
SO_KEEPALIVE | Сохраняет активными соединения при периодических передачах |
SO_LINGER | Завершает передачу перед закрытием |
При запуске этой версии сервера многочисленные клиенты будут обрабатываться последовательно в единственном процессе.Примечание
В реальную программу было бы неплохо вставить переменную, содержащую наибольший подключенный номер fd (необязательно самый последний подключенный номер fd). Это помешает просмотру в цикле тысяч номеров fd, которые даже не подсоединены и потенциально не могут быть готовы к чтению. Мы пропустили этот фрагмент кода для краткости и простоты примера.
Телефон | Сетевые сокеты |
---|---|
Звонок в компанию по номеру 555-0828 | Подключение к IP-адресу 127.0.0.1 |
Ответ на звонок секретаря приемной | Установка соединения с remote host |
Просьба соединить с финансовым отделом. | Маршрутизация с помощью заданного порта (9734) |
Ответ на звонок администратора финансового отдела | Вызов select вернул управление серверу |
Звонок переадресован свободному менеджеру по работе с корпоративными заказчиками | Сервер вызывает accept, создавая новый сокет на добавочный номер 456 |
Значение errno | Описание |
---|---|
EBADF | Был передан неверный файловый дескриптор |
EINTR | Появился сигнал |
Примечание
X-клиент необязательно должен быть на той же машине, что и X-сервер.
Несмотря на то, что GTK+ — это проект GNU, как и GIMP, он выпущен на условиях более либеральной лицензии (Lesser General Public License, Стандартная общественная лицензия ограниченного применения GNU), которая освобождает программное обеспечение (включая патентованное программное обеспечение с закрытым программным кодом), написанное с использованием GTK+, от уплаты лицензионных вознаграждений или авторских гонораров, а также других ограничений. Свобода, предлагаемая лицензией GTK+, отличает этот комплект инструментов от его конкурента Qt (который будет обсуждаться в следующей главе), чья лицензия GPL запрещает разработку коммерческого программного обеспечения с использованием Qt (в этом случае вы должны купить коммерческую лицензию для Qt).Примечание
В итоге, GTK+ — это библиотека, которая существенно упрощает создание графических интерфейсов пользователей (Graphical User Interface, GUI), предоставляя набор готовых компонентов, именуемых виджетами, которые вы соединяете вместе с помощью легких в использовании вызовов функций, включенных в логическую структуру вашего приложения.
Примечание
Не беспокойтесь, если вам все это не очень понятно; вам не нужно разбираться в подробностях ООП для того, чтобы освоить GNOME/GTK+. На самом деле это безболезненный способ усвоить идеи и преимущества ООП на базе знакомого вам языка С.
В дистрибутиве Debian и основанных на Debian системах, таких как Ubuntu, вы можете использовать программу apt-get для установки пакетов GNOME/GTK+ с разных сайтов-зеркал (mirrors). Для выяснения подробностей следуйте по ссылкам Web-сайта http://www.gnome.org.Примечание
В этом примере комбинация символов fc7 указывает на дистрибутив Linux Fedora 7. В вашей системе могут быть слегка отличающиеся имена.
Когда вы выполните программу с помощью следующей команды, ваше окно должно раскрыться (рис. 16.4).Примечание
Будьте внимательны и набирайте обратные апострофы, а не обычные апострофы — помните о том, что обратные апострофы — это инструкции, заставляющие оболочку выполнить заключенную в них команду и добавить ее вывод в конец строки.
Как программист, использующий GTK+, вы должны заботиться только о написании и связывании функций обратного вызова, поскольку код порождения сигнала — это внутренний программный код определенного виджета.Примечание
Имейте в виду, что сигнал GTK+ — это нечто иное, чем сигнал UNIX, обсуждавшийся в главе 11.
Вы опробуете функцию g_signal_connect в упражнении 16.2.Примечание
До появления GTK+ 2 для связывания функций обратного вызова применялась функция gtk_signal_connect. Она была заменена функцией g_signal_connect и не должна применяться во вновь разрабатываемом программном коде.
Параметр | Описание |
---|---|
GtkBox *box | Заполняемый упаковочный контейнер |
GtkWidget *child | Виджет, который следует поместить в упаковочный контейнер |
gboolean expand | Если равен TRUE, данный виджет занимает все доступное пространство, используемое совместно с другими виджетами, у которых этот флаг также равен TRUE |
gboolean fill | Если равен TRUE, данный виджет будет занимать всю доступную площадь вместо использования ее как отступа от краев. Действует, только если флаг expand равен TRUE |
guint padding | Размер отступа вокруг виджета в пикселах |
Функция gtk_window_setposition управляет начальным местоположением на экране. Параметр position может принимать пять значений, перечисленных в табл. 16.2.Примечание
Поскольку за отображение оформления окна отвечает оконный менеджер, а не библиотека GTK+, шрифт, цвет и размер текста зависят от вашего выбора оконного менеджера.
Параметр position | Описание |
---|---|
GTK_WIN_POS_NONE | Окно располагается по усмотрению оконного менеджера |
GTK_WIN_POS_CENTER | Окно центрируется на экране |
GTK_WIN_POS_MOUSE | Расположение окна задаётся указателем мыши |
GTK_WIN_POS_CENTER_ALWAYS | Окно остается отцентрированным независимо от его размера |
GTK_WIN_POS_CENTER_ON_PARENT | Окно центрируется относительно родительского окна (удобно для диалоговых окон) |
Примечание
Вы можете использовать комплект инструментов GTK+ для создания меню, но среда GNOME предоставляет полезные структуры и макросы, которые существенно облегчают эту задачу. В интерактивной документации описывается, как создавать меню средствами GTK+.
Типы GnomeUIInfоТуре | Описание |
---|---|
GNOME_APP_UI_ENDOFINFO | Означает, что этот элемент — последний пункт меню в массиве |
GNOME_APP_UI_ITEM | Обычный пункт меню или переключатель, если ему предшествует элемент GNOME_APP_UI_RADIOITEMS |
GNOME_APP_UI_TOGGLEITEM | Пункт меню в виде кнопки-переключателя или кнопки-флажка |
GNOME_APP_UI_RADIOITEMS | Группа переключателей или зависимых переключателей |
GNOME_APP_UI_SUBTREE | Означает, что данный элемент представляет собой подменю. Задайте moreinfo для указания на массив подменю |
GNOME_APP_UI_SEPARATOR | Вставляет разделительную линию в меню |
GNOME_APP_UI_HELP | Создает список тем справки для использования в меню Help (Справка) |
GNOME_APP_UI_BUILDER_DATA | Задает данные построения (builder data) для следующих элементов |
GNOME_APP_UI_ITEM_CONFIGURABLE | Настраиваемый пункт меню |
GNOME_APP_UI_SUBTREE_STOCK | Такой же, как GNOME_APP_UI_SUBTREE за исключением того, что надписи следует искать в каталоге gnome-libs |
GNOME_APP_UI_INCLUDE | Такой же, как GNOME_APP_UI_SUBTREE за исключением того, что пункты включены в текущее меню, а не в подменю |
Тип GtkButtonsType | Описание |
---|---|
GTK_BUTTONS_OK | Кнопка OK |
GTK_BUTTONS_CLOSE | Кнопка Close |
GTK_BUTTONS_CANCEL | Кнопка Cancel |
GTK_BUTTONS_YES_NO | Кнопки Yes и No |
GTK_BUTTONS_OK_CANCEL | Кнопки OK и Cancel |
GTK_BUTTONS_NONE | Нет кнопок |
Из соображений простоты и ясности мы создадим базовый скелетный интерфейс, в котором реализовано лишь подмножество функций — к примеру, вы не сможете добавлять информацию о дорожках в компакт-диски или удалять CD. Но вы увидите в вашем приложении в действии виджеты, обсуждавшиеся в этой главе, и поймете, как они применяются в реальных программах.Примечание
Для проверки примера приложения для работы с базой данных компакт-дисков у вас должны быть установлены СУБД MySQL и библиотеки разработки, т.е. должны выполняться те же самые требования, что и к аналогичному приложению в главе 8.
С точки зрения программиста, KDE предлагает десятки виджетов KDE, обычно унаследованных от их аналогов Qt, но улучшенных и облегчающих использование. Виджеты KDE обеспечивают более тесную связь с рабочим столом KDE, чем сам по себе комплект инструментов Qt; у вас появляется, например, возможность управления сеансами.Примечание
Во время написания книги последней версией KDE была версия 3.5.7, и поскольку эта версия включена в современные дистрибутивы Linux, мы считаем, что у вас установлена версия KDE 3.5 или более свежая. Продолжается работа над крупным обновлением — KDE 4.0. Вы можете также загрузить из Интернета предварительные версии KDE 4.0. Точно так же самая свежая версия Qt — 4.3, но в большинстве дистрибутивов Linux установлена версия Qt 3, например версия 3.3, как стандартная версия Qt. В этой главе обсуждается Qt 3.3, потому что она встречается чаще других.
В настоящее время компания Trolltech продает коммерческие версии Qt случайным пользователям и любителям по завышенным ценам. К счастью, Trolltech понимает важность бесплатной версии для сообщества, распространяющего свободное программное обеспечение, и предлагает свободно распространяемую версию Qt Open Source Edition для. ОС Linux, Windows и Mac OS X. В ответ Trolltech получает большую базу пользовательских установок, обширное сообщество программистов и высокое реноме своего продукта.Примечание
Специализированная версия Qt выполняется на сотовых телефонах. Еще одна версия работает на PDA (Personal Digital Assistant, электронный секретарь) Sharp Zaurus и аналогичных платформах. Qt Jambi представляет собой версию комплекта инструментов для языка Java.
Если комплект Qt установлен корректно, переменная окружения QTDIR будет содержать каталог установки. Проверить это можно следующим образом:Примечание
В системах Linux Fedora и Red Hat эту строку нужно сохранить в файле /etc/ld.so.conf.d/qt-i386.conf. Если вы устанавливали Qt, как показано на рис. 17.1, этот этап уже будет пройден.
Выполнив приложение, вы должны получить окно Qt (рис. 17.2).Примечание
На некоторых платформах в конце строки указывается библиотека -lqt. В версии Qt 3.3, тем не менее, используйте -lqui.
Вот как устроено программирование, управляемое событиями: графический интерфейс пользователя состоит из меню, панелей инструментов, кнопок, полей ввода и множества других элементов GUI, называемых виджетами. Когда пользователь взаимодействует с виджетом, например, активизирует пункт меню или вводит какой-то текст в поле ввода, виджет порождает именованный сигнал, такой как clicked, text_changed или key_pressed. Как правило, вам захочется сделать что-то в ответ на действие пользователя, например, сохранить документ или выйти из приложения, и вы выполняете это, связав сигнал с функцией обратного вызова или слотом на языке Qt.Примечание
Имейте в виду, что сигналы Qt отличаются от сигналов UNIX, обсуждавшихся в главе 11.
На способы применения сигналов и слотов в Qt есть несколько ограничений, но они не слишком существенные:Примечание
Таким образом, программный код с использованием Qt — не настоящий программный код на С++. Порой это становится проблемой для некоторых разработчиков. См. документацию Qt на Web-сайте http://doc.trolltech.com/, чтобы понять причину применения этих новых псевдоключевых слов в С++. Более того, применение сигналов и слотов не так уж отличается от Microsoft Foundation Classes (MFC, библиотека базовых классов Microsoft) в ОС Windows, в которой также используется модифицированное определение языка С++.
Обязательный символ | Символы, которые разрешены, но не обязательны | Значение |
---|---|---|
A | a | Символы ASCII А–Z, а–z |
N | n | Символы ASCII A–Z, a–z, 0–9 |
X | x | Любой символ |
9 | 0 | Цифры 0–9 |
D | d | Цифры 1–9 |
Символ | Значение |
---|---|
# | Разрешен, но не обязателен знак +/- |
> | Преобразует все последующие введенные символы в символы верхнего регистра. |
< | Преобразует все последующие введенные символы в символы нижнего регистра |
! | Останавливает преобразование регистра |
\ | Символ управляющей последовательности для применения специальных символов в качестве разделителей |
Пример | Допустимый ввод |
---|---|
"AAAAAA-999D" | Допустимо Athens-2004, но не Sydney-2000 или Atlanta-1996 |
"ААААnn-99-99;" | Допустимо March-03-12, но не Мау-03-12 или September-03-12 |
"000.000.000.000" | Допустим IP-адрес, например, 192.168.0.1 |
Значение | Действие |
---|---|
QComboBox::AtTop | Вставляет вводимый в список элемент первым |
QComboBox::AtBottom | Вставляет вводимый в список элемент последним |
QComboBox::AtCurrent | Заменяет предварительно выбранный вариант в списке |
QComboBox::BeforeCurrent | Вставляет вводимый элемент перед предварительно выбранным вариантом из списка |
QComboBox::AfterCurrent | Вставляет вводимый элемент после предварительно выбранного варианта из списка |
QComboBox::NoInsertion | Новый элемент не вставляется в список вариантов |
У объекта QDialog есть два слота — accept и reject, которые применяются для обозначения результата, полученного в диалоговом окне. Этот результат возвращается методом exec. Как правило, вы будете связывать кнопки OK и Cancel со слотами, как в MyDialog.Примечание
Имейте в виду, что в этом примере пропущен программный код для создания виджетов ok_pushbutton и cancel_pushbutton.
Утилита qmake принимает в качестве входного файл .pro. Этот файл содержит самые существенные сведения, необходимые для компиляции, такие как исходные тексты, заголовочные файлы, результирующий двоичный файл и местонахождения библиотек KDE/Qt.Примечание
Если вы уже пользовались комплектом Qt, вам, возможно, знакома утилита tmake — более раннее (и теперь устаревшее) воплощение qmake, поставлявшееся с предыдущими версиями Qt.
$ qmake cdapp.pro -о MakefileПримечание
Обратите внимание на то, что приведенный программный код позволяет вам немного схитрить, просто переименовав файл app_mysql.c в файл app_mysql.cpp; таким образом, вы сможете использовать его как обычный исходный файл на языке С++. Это устраняет небольшое усложнение, необходимость редактирования связей или компоновки объектного файла на языке С и объектного файла на языке С++,
Примечание
Существует еще огромное множество дополнительных опций предупреждений, все подробности см. на Web-страницах gcc. В основном мы рекомендуем применять -Wall; это удачный компромисс между проверкой, обеспечивающей программный код высокого качества, и необходимостью вывода компилятором массы тривиальных предупреждений, которые становится трудно свести к нулю.
Примечание
Следует отметить, что "Linux" — это торговая марка, принадлежащая Линусу Торвальдсу (Linus Torvalds). См. http://www.linuxmark.org/.
Уровень запуска | Описание |
---|---|
0 | Halt. Применяется как логическое состояние, к которому следует перейти при остановке системы |
1 | Однопользовательский режим. Каталоги, отличающиеся от / (корневой), могут не монтироваться, и сетевой поддержки не будет. Обычно применяется для обслуживания системы |
2 | Многопользовательский режим, но без сетевой поддержки |
3 | Обычный многопользовательский режим с сетевой поддержкой, использующий экран регистрации в текстовом режиме |
4 | Зарезервирован |
5 | Обычный многопользовательский режим с сетевой поддержкой, использующий экран регистрации в графическом режиме |
6 | Псевдоуровень, применяемый для перезагрузки |
Параметр | Значение |
---|---|
start | Запускает (или перезапускает) сервис |
stop | Останавливает сервис |
restart | Перезапускает сервис; обычно реализован как простой останов сервиса, за которым следует запуск этого сервиса |
reload | Переустанавливает сервис, повторно загружая параметры без реальной остановки сервиса. Этот вариант поддерживают не все сервисы, поэтому данный параметр может быть недоступен в некоторых сценариях, а если доступен, то не имеет эффекта |
force-reload | Пытается вызвать переустановку, если сервис ее поддерживает, если нет — выполняет перезапуск сервиса |
status | Выводит текстовое сообщение о состоянии сервиса и возвращает код состояния, который может применяться для определения состояния сервиса |
Каталог | Обязательный? | Назначение |
---|---|---|
/bin | Да | Важные системные двоичные файлы |
/boot | Да | Файлы, необходимые для загрузки системы |
/dev | Да | Устройства |
/etc | Да | Системные файлы конфигурации |
/home | Нет | Каталоги для файлов пользователей |
/lib | Да | Стандартные библиотеки |
/media | Да | Место для съемных монтируемых носителей с отдельными подкаталогами для каждого типа носителей, поддерживаемого системой |
/mnt | Да | Удобная точка для временно монтируемых устройств, таких как CD-ROM и накопители флэш-памяти |
/opt | Да | Дополнительное прикладное программное обеспечение |
/root | Нет | Файлы пользователя root |
/sbin | Да | Важные системные двоичные файлы, которые необходимы в процессе запуска системы |
/srv | Да | Предназначенные только для чтения данные для сервисов, предоставляемых данной системой |
/tmp | Да | Временные файлы |
/usr | Да | Вспомогательная иерархия. Традиционно файлы пользователей также хранятся здесь, но в наши дни это считается дурным стилем и обычным пользователем не следует предоставлять право записи в этот каталог |
/var | Да | Переменные данные, например файлы регистрации |
□ /root — это каталог для файлов, используемых пользователем root. Он не входит в ветвь каталога /home в дереве каталогов, поскольку может не монтироваться в однопользовательском режиме.Примечание
По принятому соглашению многие пакеты Open Source Linux используют каталог /usr/local для инсталляции.
□ /var — содержит часто меняющиеся данные, такие как файлы буферов печати, файлы регистраций приложений и каталоги буферизации электронной почты.Примечание
Когда только появились системы UNIX и Linux, каталог /usr также имел подкаталоги для регистраций, буферизации электронной почты и т.п. Теперь все эти подкаталоги удалены из каталога usr и помещены в каталог var. Преимущество такого подхода в том, что теперь /usr может быть монтируемой файловой системой, ее могут совместно использовать другие системы в сети, и он стал менее чувствителен к повреждениям системы, которые останавливают ее неуправляемым образом, например из-за отказа электропитания.
Спасибо, что скачали книгу в бесплатной электронной библиотеке BooksCafe.Net
Оставить отзыв о книге
Все книги автора