Text
                    ii пользователей
У ЛЯ	3-е издание
программистов о пользователей

Unix® for Programmers and Users Third Edition
Unix® for Programmers and Users Third Edition Graham Glass and King Ables PEARSON Education Pearson Education, Inc. Upper Saddle River, New Jersey 07458
Г. Гласс К. Эйблс УЛЯ З-е издание программистов и пользователей Санкт-Петербург «БХВ-Петербург» 2004
УДК 681.3.066 ББК 32.973.26-018.2 Г52 Гласс Г., Эйблс К. Г52 UNIX для программистов и пользователей. — 3-е изд., перераб. и доп.— СПб.: БХВ-Петербург, 2004. — 848 с.: ил. ISBN 5-94157-404-5 Приводятся общие сведения о развитии UNIX. Рассматриваются утилиты, команды, системные вызовы и библиотечные функции для различных категорий пользователей. Описываются командные интерпретаторы Bourne shell, Korn shell, C shell и Bourne Again shell. Обсуждаются проблемы организации сети и использования Интернета. Подробно рассматриваются организация файловой системы, управление вызовами, ввод/вывод и взаимодействие процессов. Обсуждаются вопросы системного администрирования. Особое внимание уделено средствам программирования на языке С и системному программированию. Для преподавателей и студентов, а также широкого круга пользователей, программистов и системных администраторов УДК 681.3.066 ББК 32.973.26-018.2 Группа подготовки издания: Главный редактор Зав. редакцией Перевод с английского Редактор Компьютерная верстка Корректор Дизайн обложки Зав. производством Екатерина Кондукова Григорий Добин Андрей Питько Анна Кузьмина Натальи Смирновой Наталия Першакова Игоря Цырульникова Николай Тверских Authorized translation from the english language edition, entitled UNIX FOR PROGRAMMERS AND USERS, 3rd Edition, ISBN 0130465534, by ABLES, KING and GLASS, GRAHAM, published by Pearson Education, Inc, publishing as Prentice Hall Copyright © 2003. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. RUSSIAN language edition published by BHV St. Peteisbuig, Copyright © 2004. Авторизованный перевод английской редакции, выпущенной Prentice Hall, Pearson Education, Inc, © 2003. Bee права защищены. Никакая часть настоящей книги не может быть воспроизведена или передана в какой бы то ни было с}юрме и какими бы то ни было средствами, будь то электронные или механические, включая фотокопирование и запись на магнитный носитель, если на то нет разрешения Pearson Education, Inc. Перевод на русский язык "БХВ-Петербург", © 2004. Лицензия ИД № 02429 от 24.07.00. Подписано в печать 21.06.04. Формат 70х1001/16. Печать офсетная. Усл. печ. л. 68,37. Тираж 4000 экз. Заказ № 786 "БХВ-Петербург", 190005, Санкт-Петербург, Измайловский пр., 29. Гигиеническое заключение на продукцию, товар № 77.99.02.953.Д.001537.03.02 от 13.03.2002 г. выдано Департаментом ГСЭН Минздрава России. Отпечатано с готовых диапозитивов в ОАО "Техническая книга" 190005, Санкт-Петербург, Измайловский пр., 29. ISBN 0-13-046553-4 (англ.) ISBN 5-94157-404-5 (русск.) © 2003 Pearson Education, Inc., Pearson Prentice Hall © Перевод на русский язык "БХВ-Петербург", 2004
Содержание Информация о торговых марках.......................................2 Об авторах.........................................................3 Введение......................................................... 4 О чем эта книга..................................................4 Структура книги..................................................5 Структура глав................................................. 6 Мотивация.....................................................6. Предпосылки....................................................6 Задачи.........................................................6 Изложение......................................................6 Утилиты........................................................6 Системные вызовы...............................................6 Команды shell..................................................6 Перечень тем...................................................6 Контрольные вопросы............................................6 Упражнения.....................................................7 Проекты........................................................7 Руководство для преподавателей...................................7 Условные обозначения.............................................7 Ссылки на другие книги...........................................8 Доступность исходного кода в режиме on-line......................9 Благодарности.....................................................10 Глава 1. Что такое UNIX?...........................................И Мотивация.........:............................................. 11 Предпосылки.....................................................11 Задачи..........................................................11 Изложение....................................................... 11 Компьютерные системы............................................12 Операционные системы............................................15 Программное обеспечение.........................................15 Разделение ресурсов.............................................16 Коммуникация................................................... 17 Утилиты.........................................................18
Поддержка программиста..........................................................19 Стандарты.......................................................................19 Особенности UNIX................................................................20 Принципы UNIX...................................................................20 Прошлое UNIX....................................................................22 Настоящее UNIX..................................................................23 Будущее UNIX.................................................................. 24 Остальная часть этой книги......................................................24 Обзор главы.....................................................................25 Перечень тем.................................................................25 Контрольные вопросы..........................................................25 Упражнение...................................................................26 Проект.......................................................................26 Глава 2. Утилиты UNIX для непрограммистов.........................................27 Мотивация.......................................................................27 Предпосылки.....................................................................27 Цели............................................................................27 Представление................................................................. 27 Утилиты.........................................................................28 Команда shell...................................................................28 Получение учетной записи........................................................28 Вход в систему..................................................................29 Командные интерпретаторы — shell................................................30 Выполнение программ.............................................................30 Входной, выходной каналы и канал сообщения об ошибках...........................31 Получение оперативной помощи: man...............................................32 Специальные символы.............................................................34 Завершение процесса: <Ctrl>+<C>..............................................35 Приостановка вывода: <Ctrl>+<S>/<Ctrl>+<Q>...................................35 Завершение ввода: <Ctrl>+<D>.................................................36 Установка пароля: passwd........................................................................................ 36 Выход из системы.............................................................. 37 Поэзия в движении: изучение файловой системы................................38 Определение текущего каталога: pwd..............................................39 • Абсолютные и относительные имена путей..........................................40 Создание файла..................................................................41 Просмотр содержимого каталога: Is...............................................42 Распечатка файла: cat/ тоге/page/ head/ tail............................................................. 44 Переименование файла: mv........................................................46 Создание каталога: mkdir........................................................46 Перемещение по каталогам: cd....................................................47 Копирование файла: ср........................................................................................... 49 Редактирование файла: vi........................................................49 Удаление каталога: rmdir........................................................50 Удаление файла: гт..............................................................51
Печать файла: lp/lpstat/cancel.................................................................52 Печать файла: Ipr/lpq/lprm ....................................................................54 Подсчет слов в файле: wc.......................................................................56 Атрибуты файла............................................................................... 56 Размер файла................................................................................57 Имя файла...................................................................................57 Время модификации...........................................................................58 Владелец файла..............................................................................58 Группа владельцев файла.....................................................................58 Типы файла..................................................................................59 Параметры полномочий файла..................................................................60 Счетчик жесткой связи.......................................................................62 Группы.........................................................................................62 Вывод групп: groups............................................................................63 Изменение группы: chgrp........................................................................................ 63 Изменения прав доступа файла: chmod............................................................64 Изменение владельца файла: chown ...................................................................... 66 Изменение групп: newgrp........................................................................................ 67 Поэзия в движении: эпилог......................................................................68 Определение типа вашего терминала: tset........................................................68 Изменение характеристик терминала: stty............................................................ 71 Редактирование файла: vi....................................................................................... 73 Запуск vi............................................................................................................... 73 Режим ввода текста..........................................................................74 Режим ввода команд..........................................................................75 Буфер памяти и временные файлы..............................................................76 Общие функции редактирования................................................................76 Перемещение курсора.........................................................................77 Удаление текста.............................................................................77 Замена текста...............................................................................78 Вставка текста..............................................................................79 Поиск.......................................................................................80 Поиск и замена..............................................................................80 Сохранение или загрузка файлов..............................................................81 Разное......................................................................................82 Настройка vi................................................................................83 Сохранение пользовательских настроек........................................................84 Для дополнительной информации...............................................................84 Редактирование файла: emacs....................................................................84 Запуск emacs................................................................................84 Команды emacs...............................................................................85 Как избежать проблем...................................................................... 86 Получение помощи............................................................................86 Выход из emacs..............................................................................86 Режимы emacs................................................................................86 Ввод текста.................................................................................87
Общие функции редактирования..................................................87 Перемещение курсора...........................................................87 Удаление, вставка и отмена....................................................88 Поиск....................’....................................................89 Поиск и замена................................................................90 Сохранение и загрузка файлов..................................................90 Дополнительные команды........................................................90 Для дополнительной информации.................................................90 Электронная почта: mail/mailx....................................................91 Отправка почты................................................................93 Чтение почты..................................................................94 Связь с системным администратором.............................................96 Обзор главы......................................................................96 Перечень тем..................................................................96 Контрольные вопросы...........................................................96 Упражнения....................................................................97 Проект........................................................................97 Глава 3. Утилиты UNIX для опытных пользователей....................................99 Мотивация........................................................................99 Предпосылки......................................................................99 Задачи...........................................................................99 Изложение........................................................................99 Утилиты.........................................................................100 Фильтрация файлов...............................................................101 Шаблоны фильтрации: egrep/fgrep/grep.........................................101 Шаблоны соответствия....................................................... 104 Удаление одинаковых строк: uniq.....................................................................105 Сортировка файлов: sort.........................................................106 Сравнение файлов................................................................109 Тестирование на сходство: стр.........................................................................109 Различие файлов: diff........................................................111 Поиск файлов: find..............................................................113 Архивы..........................................................................115 Копирование файлов: cpio.....................................................116 Архивация на ленту: tar......................................................119 Инкрементальные резервные копирования: dump и restore...........................122 Планирование выполнения команд..................................................123 Периодическое выполнение: cron/crontab.......................................124 Однократное выполнение: at............................................................................126 Программируемая обработка текста: awk...:.......................................128 яи;А:-программы..............................................................129 Доступ к отдельным полям.....................................................130 BEGIN и END..................................................................130 Операторы....................................................................131 Переменные...................................................................131
Структуры управления....................................................................132 Расширенные регулярные выражения........................................................132 Цепочки условий.........................................................................133 Разделители полей.......................................................................133 Встроенные функции......................................................................134 Жесткие и символические связи: In..........................................................134 Идентификация shell: whoami................................................................137 Замена пользователя: su.........................................................................................137 Проверка почты: biff...............................................................................................138 Преобразование файлов......................................................................139 Сжатие файлов: compress/uncompress и gzip/gunzip........................................139 Шифрование файла: crypt.................................................................141 Потоковое редактирование: sed......................................................... 142 Команды sed........................................143 Замена текста.........................................................................143 Удаление текста.......................................................................144 Вставка текста........................................................................145 Замена текста.........................................................................145 Вставка файлов........................................................................146 Составные команды sed.................................................................................146 Преобразование символов: tr.............................................................147 Преобразование подчеркнутых последовательностей: id...............................148 Просмотр необработанного содержимого файла: od..........................................149 Монтирование файловых систем: mount/ amount.............................................151 Идентификация терминалов: tty.......................................................................152 Форматирование текста: nroff/troff/style/spell....................................................153 Измерение времени выполнения: time......................................................153 Создание собственных программ: Perl........................................................154 Получение Perl..........................................................................154 Печать текста...........................................................................155 Переменные, строки и целые..............................................................155 Массивы.................................................................................156 Математические и логические операторы...................................................158 Строковые операторы.....................................................................159 Операторы сравнения.....................................................................160 Конструкции if, while, for и foreach ................................................................... 160 Ввод/вывод файла........................................................................161 Функции.................................................................................162 Библиотека функций......................................................................163 Аргументы командной строки..............................................................164 Пример из реального мира............................................................... 165 Обзор главы................................................................................168 Перечень тем............................................................................168 Контрольные вопросы.....................................................................168 Упражнения..............................................................................169 Проекты............................................................................... 169
Глава 4. Командные интерпретаторы shell.........................................171 Мотивация.....................................................................171 Предпосылки...................................................................171 Задачи........................................................................171 Утилиты.......................................................................172 Команды shell.................................................................172 Общие сведения о shell...................................................... 172 Функциональные возможности shell..............................................173 Выбор shell...................................................................173 Функционирование shell........................................................175 Исполняемые файлы и встроенные команды....................................... 175 Вывод информации на экран: echo............................................176 Смена каталогов: cd............................................................................................176 Метасимволы...................................................................176 Перенаправление ввода/вывода..................................................178 Перенаправление вывода.....................................................178 Переназначение ввода.......................................................179 Групповые символы поиска файлов...............................................180 Конвейеры.....................................................................181 Замещение команды.............................................................183 Последовательности............................................................184 Условные последовательности................................................184 Группирование команд..........................................................185 Фоновое выполнение........................................................ 186 Перенаправление фоновых процессов.............................................187 Перенаправление вывода.....................................................187 Перенаправление ввода......................................................188 Программы shell: скрипты......................................................188 Дочерние shell................................................................190 Переменные....................................................................191 Использование кавычек.........................................................193 Перенаправление ввода в буфер shell...........................................194 Управление работой............................................................195 Статус процесса: ps........................................................196 Процессы передачи сигналов: kill...........................................199 Ожидание дочернего процесса: wait.................................................................201 Поиск команды: $РАТН........................................................................................202 Подмена стандартных утилит....................................................203 Завершение и коды выхода.................................................... 203 Основные встроенные команды...................................................205 eval.......................................................................205 exec.......................................................................205 shift......................................................................206 umask......................................................................207 Обзор главы...................................................................208 Перечень тем...............................................................208
Контрольные вопросы..............................................................209 Упражнения.......................................................................209 Проект...........................................................................210 Глава 5. Bourne shell................................................................211 Мотивация..........................................................................211 Предпосылки........................................................................211 Задачи.............................................................................211 Изложение..........................................................................211 Утилиты............................................................................211 Команды shell......................................................................212 Общие сведения о Bourne shell......................................................212 Запуск.............................................................................212 Переменные.........................................................................213 Создание и назначение переменной.................................................213 Доступ к переменной..............................................................214 Чтение переменной со стандартного ввода..........................................216 Экспорт переменных...............................................................217 Переменные только для чтения.....................................................218 Предопределенные локальные переменные.......................................... 219 Предопределенные переменные окружения............................................220 Арифметические действия............................................................222 Условные выражения.................................................................224 Структуры управления...............................................................226 case ... in ... esac..................................................................................................226 for ... do ... done....................................................................................................228 if... then ...ft........................................................................................................229 trap.............................................................................230 until... do ... done.................:...........................................231 while ... done.........................................................................................................232 Пример проекта: track..............................................................233 track.sed........................................................................235 track, cleanup...................................................................236 track............................................................................236 Дополнительные встроенные.команды..................................................237 Команда чтения: точка (.)........................................................237 Команда null........................................................................................................238 Установка опций shell: set.......................................................238 Усовершенствования.................................................................239 Перенаправление................................................................ 239 Последовательности команд........................................................240 Опции командной строки........................................................... 241 Обзор главы........................................................................241 Перечень тем.....................................................................241 Контрольные вопросы..............................................................242 Упражнения.......................................................................242 Проекты..........................................................................243
Глава 6. Korn shell......................................................245 Мотивация..............................................................245 Предпосылки............................................................245 Задачи.................................................................245 Изложение..............................................................245 Команды shell..........................................................245 Общие сведения о Korn shell............................................246 Запуск.................................................................246 Псевдонимы.............................................................248 Создание псевдонимов встроенных команд...............................249 Удаление псевдонимов.................................................249 Предопределенные псевдонимы..........................................250 Некоторые полезные псевдонимы........................................250 Псевдонимы путей.....................................................251 Экспортируемые псевдонимы............................................251 История................................................................252 Пронумерованные команды............................................ 252 Сохранение команд....................................................253 Повторное выполнение команд..........................................253 Редактирование команд................................................254 Редактирование команд..................................................255 Встроенный редактор и................................................256 Дополнительные перемещения.........................................256 Дополнительный поиск...............................................257 Использование маски для имени файла................................257 Замещение псевдонима...............................................258 Встроенный редактор emacs/gmacs......................................258 Арифметические действия................................................259 Предотвращение интерпретации метасимволов............................260 Возвращаемые значения................................................261 Замена тильды..........................................................261 Меню: select.............................................................................................................262 Функции................................................................263 Использование параметров в функциях..................................265 Возврат из функции...................................................265 Контекст.............................................................266 Локальные переменные.................................................266 Рекурсия.............................................................267 Рекурсивный факториал: использование кода возврата.................267 Рекурсивный факториал: использование стандартного вывода...........268 Использование кода функций в нескольких скриптах.....................268 Расширенное управление заданиями.......................................269 Задания..............................................................269 Спецификация задания.................................................270 bg...................................................................270 fg................................................................. 271 kill.................................................................272
Усовершенствования...........................................................................273 Перенаправление............................................................................273 Конвейеры..................................................................................274 Замещение команды..........................................................................274 Переменные.................................................................................275 Гибкие методы доступа...................................................................275 Предопределенные локальные переменные...................................................276 Одномерные массивы......................................................................278 typeset.................................................................................278 Форматирование.............................................................................279 Регистр....................................................................................279 Тип........................................................................................280 Разное................................................................................... 281 typeset о не именованными переменными...................................................282 Встроенные команды.........................................................................283 cd.......................................................................................................................283 set.....................................................................................284 print................................................................................. 286 read...................................................................................................................287 test.....................................................................................................................287 trap....................................................................................................................288 Пример проекта: junk.......................................................................289 junk...................................................................................................................290 Ограниченный shell...........................................................................293 Опции командной строки.......................................................................293 Обзор главы..................................................................................294 Перечень тем...............................................................................294 Контрольные вопросы........................................................................294 Упражнения.................................................................................294 Проекты....................................................................................295 Глава 7. С shell................................................................................297 Мотивация....................................................................................297 Предпосылки..................................................................................297 Задачи..................................................................................... 297 Изложение.................................................................................. 297 Команды shell................................................................................297 Общие сведения о С shell.....................................................................298 Запуск.......................................................................................299 Переменные...................................................................................300 Создание и присвоение значений простым переменным..........................................300 Доступ к простой переменной.............................................................. 301 Создание списочных переменных..............................................................302 Доступ к списочной переменной..............................................................303 Построение списков.........................................................................304
Предопределенные локальные переменные...............................................304 Создание и присвоение переменных окружения..........................................306 Предопределенные переменные окружения...............................................306 Выражения............................................................................ 307 Строковые выражения............................................................... 307 Арифметические выражения............................................................307 Выражения, ориентированные на файл..................................................310 Автоматическое дописывание имени файла................................................311 Псевдонимы............................................................................311 Удаление псевдонима.................................................................313 Полезные псевдонимы.................................................................313 Разделение псевдонимов..............................................................314 Параметризованные псевдонимы...................................................... 314 История...............................................................................314 Пронумерованные команды.............................................................314 Сохранение команд...................................................................315 Чтение истории......................................................................315 Повторное выполнение команды...................................................... 316 Доступ к частям команд истории................................................317 Доступ к частям имен файлов....................................................318 Замена истории......................................................................318 Структуры управления..................................................................319 foreach ... end.....................................................................319 goto................................................................................320 if... then ... else ... endif.......................................................321 onintr............................................................................ 322 repeat..............................................................................323 switch ... case ... endsw...........................................................323 while ... end...........................................................................................................326 Пример проекта: junk.............................................................................................327 junk.............................................................................. 327 Усовершенствования....................................................................329 Повторное выполнение команды: клавиатурная комбинация быстрого вызова.....................................................................330 Метасимволы: {}................................................................................................330 Замещение имен файлов...............................................................330 Запрещение замещения имени файла.................................................331 Ситуации несовпадения............................................................331 П еренаправление....................................................................331 Перенаправление стандартного канала ошибки.......................................331 Защита файлов от случайного переписывания........................................332 Конвейеризация......................................................................332 Управление заданием.................................................................333 stop.............................................................................333 suspend..............................................................................................................334 nice.............................................................................334
nohup.................................................................................................................334 notify..................................................................................................................335 Завершение входного shell................................................................335 Встроенные команды.........................................................................336 chdir......................................................................................................................336 glob........................................................................................................................336 source....................................................................................................................336 Стек каталогов.............................................................................337 Хеш-таблица..............................................................................339 Опции командной строки.....................................................................340 Обзор главы................................................................................341 Перечень тем.............................................................................341 Контрольные вопросы......................................................................341 Упражнения...............................................................................342 Проект...................................................................................342 Глава 8. Bourne Again shell................................................................. 343 Мотивация..................................................................................343 Предпосылки................................................................................343 Задачи.....................................................................................343 Изложение..................................................................................344 Команды shell..............................................................................344 Общие сведения о Bourne Again shell........................................................344 Получение Bash...........................................................................345 Запуск.....................................................................................345 Переменные.................................................................................346 Создание и назначение простой переменной.................................................346 Доступ к простой переменной..............................................................347 Создание списочных переменных............................................................347 Доступ к списочным переменным............................................................348 Построение списков.......................................................................349 Удаление списков.........................................................................350 Экспорт переменных.......................................................................350 Предопределенные переменные..............................................................351 Клавиатурные комбинации быстрого вызова команд.............................................352 Псевдонимы...............................................................................352 История команд...........................................................................353 Хранение команд.......................................................................353 Чтение истории команд.................................................................353 Повторное выполнение команд...........................................................353 Замена истории........................................................................354 Редактирование команды................................................................355 Автозаполнение...........................................................................356 Арифметические действия....................................................................356 Условные выражения.........................................................................357 Арифметические выражения.................................................................357
Сравнение строк..............................................................358 Выражения, ориентированные на файл...........................................358 Структуры управления...........................................................360 case ... in ... esac...................................................................................................360 if... then ... elif... then ... else ...ft........................................................................361 for ... do ... done....................................................................................................362 while/until... do ... done...................................................362 Стек каталогов............................................................... 363 Управление заданием............................................................364 Функции........................................................................365 Разные встроенные команды......................................................366 Опции командной строки....................................................... 367 Обзор главы....................................................................368 Перечень тем.................................................................368 Контрольные вопросы..........................................................368 Упражнение...................................................................369 Проект.......................................................................369 Глава 9. Организация сети........................................................371 Мотивация......................................................................371 Предпосылки....................................................................371 Задачи.........................................................................371 Изложение......................................................................371 Утилиты........................................................................372 Общие сведения о сетях.........................................................372 Построение сети................................................................372 Сети Ethernet................................................................373 Мосты........................................................................374 Маршрутизаторы............................................................. 375 Шлюзы........................................................................375 Объединение сетей..............................................................376 Коммутация пакетов...........................................................376 Адреса Интернета.............................................................377 Именование...................................................................378 Маршрутизация................................................................378 Безопасность.................................................................378 Порты и общие сервисы...................................................... 379 Сетевое программирование.....................................................380 Пользователи...................................................................380 Распечатка списка пользователей: users/rusers................................381 Расширенные сведения о пользователях: who/rwho/w....................................382 Собственное имя хоста: hostname..............................................383 Персональные данные: finger..................................................384 Взаимодействие с пользователями................................................386 Защита от общения: mesg......................................................386 Передача строки за один раз: write...........................................387
Интерактивные диалоги: talk............................................................................388 Сообщения всем пользователям: wall..............................................................388 Распределенные данные..............................................................389 Копирование файлов между двумя UNIX-хостами: гср................................390 Копирование файлов между He-UNIX-хостами: ftp.......................................390 Распределенная обработка...........................................................393 Удаленный вход в систему: rlogin .....................................................................394 Выполнение удаленных команд: rsh.................................................................395 Удаленные соединения: telnet....................................................396 Сетевая файловая система: NFS......................................................399 Для дополнительной информации......................................................400 Обзор главы........................................................................400 Перечень тем....................................................................400 Контрольные вопросы.............................................................400 Упражнения......................................................................400 Проект..........................................................................401 Глава 10. Интернет...................................................................403 Мотивация..........................................................................403 Предпосылки........................................................................403 Задачи.............................................................................403 Изложение..........................................................................403 Эволюция Интернета.................................................................404 В начале: 1960-е................................................................404 Сетевая связь.................................................................405 ARPANET.......................................................................405 Стандартизация Интернета: 1970-е................................................405 Семейство протокола IP........................................................406 TCP/IP........................................................................406 UDP/IP........................................................................407 Интернет-адресация............................................................407 Интернет-приложения...........................................................408 Изменение архитектуры и переименование Интернета: 1980-е........................408 Служба доменных имен........................................................ 409 Дальнейшее развитие...........................................................412 Web: 1990-е.....................................................................413 "Убийственное приложение"................................................... 413 Web против Интернета..........................................................415 Достижимость..................................................................415 Изменения в Интернете.........................................................416 Безопасность..................................................................417 Авторское право...............................................................418 Цензура.......................................................................418 Дезинформация.................................................................418 Приемлемое использование......................................................419
Современный Интернет...........................................419 URL..........................................................420 Web-поиск..................................................421 Поиск пользователей и доменов............................ 422 Факторы, влияющие на будущее использование.................422 Обзор главы....................................................422 Перечень тем............................................... 422 Контрольные вопросы..........................................423 Упражнения...................................................423 Проект.......................................................423 Глава 11. Пользовательские интерфейсы............................425 Мотивация......................................................425 Предпосылки....................................................425 Задачи.........................................................425 Изложение......................................................425 Утилиты........................................................426 Общие сведения.................................................426 Графические пользовательские интерфейсы......................426 X Window System..............................................427 Х-серверы......................................................428 Геометрия экрана.............................................428 Безопасность и авторизация...................................429 Диспетчеры окон................................................430 Фокус........................................................430 Запуск программы.............................................431 Открытие и закрытие окон.....................................431 Выбор диспетчера окна........................................432 Виджеты........................................................433 Меню....................................................... 434 Командные кнопки.............................................434 Флажки и переключатели.......................................435 Полосы прокрутки.............................................435 Функции диспетчера окна Motif..................................436 Вызов корневого меню.........................................436 Открытие окна................................................437 Закрытие окна................................................437 Перемещение окна.............................................437 Изменение размера окна.......................................437 Размещение поверх других окон.........;......................437 Вызов меню окна............................................. 437 Приложение-клиент..............................................438 xclock.......................................................438 xbiff........................................................438 xterm...................................................... 440
Стандартные аргументы X-клиента................................440 Геометрия....................................................440 Цвет переднего и заднего плана...............................441 Заголовок....................................................441 Значок.......................................................441 Дополнительные темы............................................441 Копирование и вставка........................................441 Сетевые возможности..........................................443 Ресурсы приложения...........................................443 Как работают ресурсы.......................................444 Определение ресурсов.......................................445 Конфигурация и запуск........................................447 xinit и .xinitrc...........................................447 mwm и .mwmrc...............................................448 Обзор других Х-совместимых рабочих столов......................448 CDE..........................................................449 Gnome........................................................449 KDE..........................................................449 Open Windows.................................................449 VUE..........................................................450 Обзор главы....................................................450 Перечень тем.................................................450 Контрольные вопросы..........................................450 Упражнения...................................................451 Проект.......................................................451 Глава 12. Инструментальные средства программирования на С........453 Мотивация......................................................453 Предпосылки....................................................453 Задачи.........................................................453 Изложение......................................................453 Утилиты........................................................454 Язык С.........................................................454 Компиляторы С..................................................455 Одномодульные программы........................................455 Компиляция С-программы.......................................456 Листинг скорректированной программы reverse..................457 Выполнение С-программы.......................................458 Переопределение имени исполняемого файла.....................459 Многомодульные программы.......................................459 Многократно используемые функции.......................459 Подготовка многократно используемой функции..................460 reverse.h..................................................460 reverse, с.................................................460 mainl.c....................................................461
Отдельное компилирование и компоновка модулей......................................461 Автономный загрузчик: Id.................................................................................462 Повторное использование функции reverse.....................................................463 palindrome.h....................................................................463 palindrome.с....................................................................463 main2.c.........................................................................464 Поддержка многомодульных программ..................................................464 Система зависимости файлов UNIX: make................................................465 Make-файлы.........................................................................466 Порядок make-правил................................................................467 Выполнение таке...............................................................................................468 Маке-правила.......................................................................469 Написание собственных пользовательских правил......................................470 touch..............................................................................470 Макросы............................................................................471 Другие возможности таке............................................................472 Система поддержки архивов UNIX: аг...................................................472 Создание архива....................................................................473 Добавление файла...................................................................473 Присоединение файла................................................................473 Получение оглавления...............................................................474 Удаление файла.....................................................................474 Извлечение файла...................................................................474 Обработка архива из командной строки...............................................474 Обработка архива при помощи утилиты таке...........................................475 Упорядочение архивов...............................................................476 Создание оглавления: ranlib........................................................477 Разделяемые библиотеки.............................................................478 Система управления исходным кодом UNIX: SCCS.........................................479 Создание SCCS-файла................................................................480 Выборка файла......................................................................481 Наблюдение SCCS-активности.........................................................482 Отмена выборки и возврат файла.....................................................483 Создание новой дельты..............................................................483 Получение истории файла............................................................485 Идентифицирующие ключевые слова SCCS...............................................485 Создание нового релиза.............................................................486 Выборка копий только для чтения предыдущих версий..................................487 Выборка редактируемых копий предыдущих версий......................................487 Редактирование различных версии....................................................488 Удаление версии....................................................................489 Сжатие SCCS-фаилов.................................................................490 Ограничение доступа к SCCS-фаилам..................................................491 Блокировка релизов.................................................................492 Профайлер UNIX: prof...........................................................................................492 Перепроверка программ : lint................................................................................493
Отладчик UNIX: dbx............................................................................494 Подготовка программы для отладки............................................................496 Вход в режим отладки........................................................................496 Выполнение программы........................................................................497 Трассировка программы.......................................................................497 Трассировка переменных и вызовов функции....................................................498 Ошибки......................................................................................500 Точки останова..............................................................................500 Пошаговое выполнение........................................................................501 Организация доступа к переменным............................................................501 Листинг программы...........................................................................502 Выход из отладчика..........................................................................503 Резюме......................................................................................503 Удаление лишнего кода: strip..................................................................503 Обзор главы...................................................................................504 Перечень тем................................................................................504 Контрольные воросы..........................................................................504 Упражнения..................................................................................505 Проекты.....................................................................................505 Глава 13. Системное программирование.............................................................507 Мотивация.....................................................................................507 Предпосылки...................................................................................507 Задачи........................................................................................507 Изложение.....................................................................................507 Системные вызовы и библиотечные процедуры.....................................................508 Общие сведения................................................................................508 Обработка ошибки: реггог()...................................................................................510 Управление обычными файлами...................................................................513 Общие сведения об управлении файлами........................................................513 Первый пример: reverse......................................................................................515 Как работает reverse............................................................................................517 Листинг: reverse.с..........................................................................518 Открытие файла: ореп()......................................................................524 Создание файла...........................................................................526 Открытие существующего файла.............................................................526 Другие флаги открытия....................................................................526 Чтение из файла: read().....................................................................526 Запись в файл: \vrite().........................................................................................527 Перемещение в файле: lseek()................................................................528 Закрытие файла: close()......................................................................................530 Удаление файла: unlink()....................................................................531 Второй пример: monitor.................................................................... 532 Как работает monitor...................................................................................... . ..533 Листинг: monitor.c..........................................................................534 Получение информации о файле: stat()...........................................................543
Чтение информации каталога: getdentsQ...................................................545 Смешанные вызовы системы управления файлами.............................................546 Замена владельца файла или группы: chown() и fchovm()...................................547 Изменение прав доступа файла: chmod() и fchmod()........................................548 Дублирование дескриптора файла: dup() и dup2() ..........................................549 Действия с дескриптором файла: fcntl()..................................................550 Управление устройствами: ioctl()......................................................................552 Создание жестких связей: Нпк()........................................................................552 Создание специальных файлов: mknod()..........................................................554 Сбрасывание на диск буферов файловой системы: sync()....................................554 Усечение файла: truncate() и ftruncateQ.................................................555 STREAMS.................................................................................556 Усовершенствования по сравнению с традиционным вводом/выводом UNIX..................................................................556 Анатомия STREAMS.....................................................................557 Системные вызовы STREAMS.............................................................557 Управление процессами.....................................................................558 Создание нового процесса: fork() .....................................................................560 Осиротевшие процессы....................................................................562 Завершение процесса: exit().............................................................564 Зомби-процессы..........................................................................565 Ожидание дочернего процесса: wait().....................................................566 Замена кода процесса: ехес()............................................................568 Смена каталогов: chdir()................................................................569 Смена приоритетов: nice().................................................................................570 Доступ к ID пользователя и ID группы....................................................572 Пример программы: фоновая обработка.....................................................573 Пример программы: использование диска...................................................573 Подпроцессы-нити........................................................................576 Управление нитями....................................................................577 Синхронизация нитей..................................................................577 Безопасность нитей...................'...............................................577 Перенаправление.........................................................................578 Сигналы...................................................................................580 Определенные сигналы....................................................................581 Список сигналов.........................................................................581 Сигналы терминала.......................................................................582 Запрос аварийного сигнала: alarm()......................................................583 Обработка сигналов: signal()..............................................................................584 Защита критического кода и формирование цепочки обработчиков прерываний..............................................................................586 Посылка сигналов: кШ()..................................................................587 ’’Смерть" дочерних процессов............................................................587 Приостановка и возобновление процессов..................................................589 Группы процесса и терминалы управления..................................................591
IPC..................................................................596 Конвейеры..........................................................596 Безымянные конвейеры: pipe()......................................................................597 Именованные конвейеры............................................601 Программа-читатель...............................................603 Программа-писатель...............................................604 Примерный вывод..................................................605 Сокеты.............................................................605 Виды сокетов.....................................................607 Написание сокетных программ......................................608 Листинг примера “Chef-Cook"......................................609 Анализ исходного кода............................................613 Разделяемая память.................................................628 Семафоры...........................................................629 Internet shell.......................................................630 Ограничения........................................................630 Синтаксис команды..................................................631 Запуск Internet shell..............................................631 Встроенные команды.................................................631 Примеры обычных команд.............................................632 И нтернет-примеры..................................................633 Как работает Internet shell........................................635 Основной командный цикл............................................636 Анализ........................................................... 636 Выполнение командной последовательности............................637 Выполнение конвейеров..............................................637 Выполнение простой команды.........................................638 Переключение.......................................................638 Расширение возможностей............................................639 Листинг исходного кода Internet shell............................639 Обзор главы..........................................................666 Перечень тем.......................................................666 Контрольные вопросы................................................666 Упражнения.........................................................667 Проекты............................................................669 Глава 14. UNIX изнутри.................................................673 Мотивация............................................................673 Предпосылки..........................................................673 Задачи...............................................................673 Изложение............................................................673 Общие сведения...................................................... 674 Основы ядра..........................................................674 Подсистемы ядра....................................................674 Процессы и файлы...................................................675 Взаимодействие с ядром.............................................675
Системные вызовы..............................................676 Пользовательский режим и режим ядра...........................677 Синхронная обработка против асинхронной.......................679 Прерывания....................................................680 Прерывание прерывании.........................................681 Файловая система................................................683 Архитектура диска.............................................684 Чередование...................................................686 Хранение файла................................................686 Блочный ввод/вывод............................................687 Индексный дескриптор или inode................................688 Содержимое inode..............................................689 Карта блоков..................................................690 Размещение файловой системы...................................691 Суперблок.....................................................692 Bad-блоки.....................................................693 Каталоги......................................................693 Преобразование путевых имен в номера inode....................694 Пример преобразования путевого имени в inode..................695 Монтирование файловых систем..................................696 Система ввода/вывода файлов...................................697 Управление процессами...........................................697 Исполняемые файлы.............................................697 Первые процессы...............................................698 Процессы ядра и пользовательские процессы.....................699 Иерархия процессов............................................699 Состояния процесса............................................700 Состав процесса...............................................701 Область пользователя..........................................701 Таблица процессов.............................................702 Планировщик...................................................703 Правила планирования..........................................704 Управление памятью............................................706 Страницы памяти............................................. 706 Таблицы страниц и области.................................... 706 Таблица ОЗУ...................................................708 Загрузка исполняемого файла: ехес()...........................708 Преобразование адреса.........................................709 Иллюстрация алгоритма MMU.....................................710 ММU и таблица страниц.........................................710 Схема памяти после первой команды.............................711 Схема памяти после нескольких команд..........................712 Демон страниц.................................................714 Пространство обмена...........................................714 Алгоритм демона страниц.......................................714 Схема памяти после удаления нескольких страниц................715
Доступ к странице, которая хранится в пространстве обмена.................716 Дублирование процесса: fork()............................................................717 Обработка ссылок на разделяемые страницы ОЗУ и пространства обмена....................................................................719 Пробуксовка и свопинг....................................................................720 Прекращение процесса: exit() ...............................................................720 Сигналы..................................................................................721 setpgrp()..............................................................................721 signal()...............................................................................................................722 Сигналы после системных вызовов fork() или ехес() ................................722 Обработка сигнала......................................................................723 exit()..................................................................................................................723 wait ()................................................................................723 кШ()...................................................................................724 Ввод/вывод..................................................................................724 Объекты ввода/вывода.....................................................................724 Системные вызовы ввода/вывода............................................................725 Буферизация ввода/вывода.................................................................725 sync().................................................................................727 Ввод/вывод обычных файлов................................................................728 ореп()................................................................................................................728 read().................................................................................................................729 yvrite()...............................................................................730 IseekQ.................................................................................730 close()................................................................................731 dup()................................................................................ 733 unlink()........................................................................................ ....................733 Ввод/вывод каталогов.....................................................................734 mknod()................................................................................734 link().................................................................................735 Монтирование файловых систем.............................................................735 mount().............................................................................. 735 Перевод имен файлов......................................................................736 amount()...............................................................................737 Ввод/вывод специальных файлов............................................................737 Интерфейс устройства...................................................................738 Старшие и младшие номера...............................................................739 Таблицы переключения...................................................................739 ореп().................................................................................741 read().................................................................................742 write()................................................................................742 close()742 ioctl()................................................................................742 Ввод/вывод терминала.....................................................................743 Структуры данных терминала.............................................................744
Чтение с терминала.........................................744 Запись на терминал.........................................745 Потоки.......................................................745 Взаимодействие процессов.......................................746 Конвейеры....................................................746 Конвейеры System V Release 3...............................746 Структуры данных конвейера.................................747 Запись в конвейер..........................................747 Чтение из конвейера........................................747 Закрытие конвейера....................................... 747 Конвейеры System V Release 4............................. 748 Конвейеры BSD..............................................748 Сокеты.......................................................748 Управление памятью.........................................748 Сокеты и таблица открытых файлов......................... 749 Запись в сокет.............................................749 Чтение из сокета...........................................750 Обзор главы....................................................750 Перечень тем.................................................750 Контрольные вопросы..........................................750 Упражнения...................................................751 Проекты......................................................752 Глава 15. Системное администрирование............................753 Мотивация......................................................753 Предпосылки....................................................753 Задачи.........................................................753 Изложение......................................................753 Утилиты........................................................754 Общие сведения о системном администрировании...................754 Как стать привилегированным пользователем......................755 Запуск UNIX....................................................755 Остановка системы..............................................757 Поддержка файловой системы.....................................759 Целостность файловой системы.................................759 Использование диска........................................ 760 Назначение квот..............................................763 Создание новых файловых систем...............................763 Создание резервных копий файловых систем.....................764 Поддержка пользовательских учетных записей.....................764 Файл паролей.................................................765 Файл групп...................................................766 Установка программного обеспечения.............................767 Периферийные устройства........................................769 Установка драйвера устройства................................769 Терминальные файлы.......................................-...770
Сетевой интерфейс...............................................771 Автоматизация задач.............................................772 Учет системных ресурсов.........................................773 Конфигурирование ядра...........................................773 Проблемы безопасности...........................................774 Обзор главы.....................................................776 Перечень тем..................................................776 Контрольные вопросы...........................................776 Упражнения....................................................777 Проект........................................................777 Глава 16. Будущее.................................................779 Мотивация.......................................................779 Предпосылки.....................................................779 Задачи..........................................................779 Изложение.......................................................779 Общие сведения..................................................780 Влияние настоящего и будущего на UNIX...........................780 Объектно-ориентированное программирование.....................780 Что такое объект?...........................................781 Как объект используется.....................................781 Так чем же хорошо все это?..................................782 Наследование................................................782 Открытые программные средства.................................783 Free Software Foundation....................................783 Linux.......................................................784 Параллельные, распределенные и многопроцессорные системы......784 Параллельная обработка......................................785 Распределенные системы......................................785 Многопроцессорные системы...................................786 "Ошибка" 2000 года............................................786 Что же это в действительности?..............................787 Год в две цифры.............................................787 Годы, начиная с 1900........................................788 UNIX и XXI столетие.........................................789 64-разрядные системы..........................................789 Интернет-адресация: IPv6......................................790 Сети с высокой пропускной способностью........................791 Отказоустойчивые системы......................................792 Обзор современных популярных версий UNIX........................792 AIX...........................................................794 Caldera SCO/Unixware..........................................794 FreeBSD.......................................................794 HP-UX.........................................................795 IRIX..........................................................795 Linux.........................................................796
NetBSD......................................................796 OpenBSD.....................................................797 Tru64 UNIX..................................................797 Solaris.....................................................797 Обзор главы...................................................798 Перечень тем................................................798 Контрольные вопросы.........................................798 Упражнение..................................................799 Проект......................................................799 Приложение......................................................801 Регулярные выражения..........................................801 Шаблоны.....................................................802 Расширенные регулярные выражения............................802 Модифицированная для UNIX нотация Бэкуса—Наура................803 Библиография....................................................805 Предметный указатель............................................808
Правде и Красоте, где бы их ни находили, и Свободе, и всем, кто жертвовал ради них
Информация о торговых марках AIX — торговая марка корпорации IBM. Ethernet — зарегистрированная торговая марка корпорации Xerox. FreeBSD — торговая марка Berkeley Software Design, Inc. GNU — торговая марка Free Software Foundation. HP-UX — зарегистрированная торговая марка компании Hewlett-Packard. Itanium — зарегистрированная торговая марка корпорации Intel. IRIX — зарегистрированная торговая марка Silicon Graphics, Inc. Java — торговая марка Sun Microsystems, Inc. KDE и К Desktop Environment — торговые марки KDE e. V. Linux — торговая марка Linus Torvalds. MacOS — зарегистрированная торговая марка Apple Computer. Microsoft Windows, Windows NT и Windows 2000 — зарегистрированные торговые марки корпорации Microsoft. Netscape — зарегистрированная торговая марка корпорации Netscape Communications. SCO и UNIXWare — торговые марки Caldera. Solaris, Spare и Open Windows — торговые марки Sun Microsystems, Inc. Tru64 — торговая марка компании Hewlett-Packard. UNIX — зарегистрированная торговая марка The Open Group. VMS и Open VMS — зарегистрированные торговые марки компании Hewlett-Packard. X Window System — торговая марка The Open Group.
Об авторах Грэхэм Гласс (Graham Glass) окончил Университет Саутгемптона (Англия) со степенью бакалавра по информатике и математике в 1983 г. Эмигрировав в Соединенные Штаты, он получил степень мастера по информатике Техасского университета в Далласе (University of Texas at Dallas) в 1985 г. В то время он работал как системный аналитик UNIX/С и активно принимал участие в исследованиях нейронных сетей и параллельной распределенной обработки данных. Позже он преподавал в Техасском университете в Далласе разнообразные курсы, включая UNIX, С, ассемблер, языки программирования C++ и Smalltalk. Он был соучредителем корпорации ObjectSpace и в настоящее время обучает и консультирует такие компании, как DSC Corporation, Texas Instruments, Northern Telecom, J.C. Penney и Bell Northern Research, используя свои знания объектно-ориентированного программирования (ООП) и параллельных систем, чтобы проектировать и строить параллельную объектно-ориентированную компьютерную систему и язык, основанные на транспьютерном чипе Inmos Т9000. В свободное время он пишет музыку, ныряет с аквалангом, ходит на лыжах и иногда спит. Кинг Эйблс (King Ables) получил степень бакалавра по информатике в Техасском университете в Остине (University of Texas at Austin) в 1982 г. Он был пользователем, разработчиком, системным администратором UNIX и консультантом с 1979 г., работая как в маленьких начинающих компаниях, так и в больших корпорациях. Обеспечивал поддержку и обучение, разрабатывал программное обеспечение UNIX и системные инструментальные средства, писал документацию на продукты и материалы для обучения. В 1990-х гг. он был единоличным владельцем консультационной фирмы по UNIX в Остине до момента, когда решил перебраться в горы Колорадо. До этого проекта он издал книгу по администрированию системы UNIX. Он также написал много журнальных статей на различные темы, относящиеся к UNIX, и имеет патент на механизм секретности для электронной коммерции. Его профессиональные интересы включают организацию безопасности сети и конфиденциальности в Интернете, но он любит путешествовать пешком и кататься на лыжах немного больше.
Введение О чем эта книга Одной из моих работ1 перед написанием этой книги было преподавание UNIX множеству разных людей, включая университетских студентов, промышленных С-хакеров и иногда друзей и коллег. За это время я приобрел обширные знания, в том числе и в форме существенной библиотеки примеров. Поэтому я часто думал, что будет хорошо систематизировать их и написать книгу. Когда я начал готовить мою университетскую серию лекций о UNIX, то нашел, что ни один из доступных учебников UNIX не удовлетворяет моей цели — они были или слишком неструктурированными, слишком специализированными или страдали недостатком неподходящих упражнений и проектов для моих студентов. В ответ на сложившуюся ситуацию я написал самую первую версию этой книги. После прошествия пары лет я полностью ее переписал, допуская осторожную мысль о включении нового материала. Я решил сгруппировать информацию, основываясь на типичных категориях пользователей UNIX, позволяя использовать книгу большому количеству людей без превышения (или принижения) умственных способностей каждого. Одно хитрое решение касалось уровня деталей, чтобы включить темы, подобные системным вызовам и утилитам. Большинство их имеет множество специализированных опций и особенностей, которые редко используются, и описание их всех при охвате всего диапазона желаемых тем завершится книгой толщиной приблизительно в два фута1 2. Из-за этого я включил в книгу информацию только о наиболее общих и полезных особенностях утилит, командных интерпретаторов (shells) и системных вызовов. Я включаю ссылки на другие коммерчески доступные книги для большего количества деталей. Этот гибридный подход оказался хорошим компромиссом; я надеюсь, что вы согласны. В это издание добавлена глава о командном интерпретаторе Bourne Again shell (также называемом Bash), который стал важным из-за его всеобъемлющей позиции в Linux. Также обновлена информация о версиях UNIX/Linux, рабочих столах X Window System и нюансах работы менеджера окон, расширено описание' редактора vi, языка Perl и стандарта IPv6, добавлено и улучшено описание некоторых команд, контрольных вопросов и упражнений. 1 Здесь, по видимому, повествование идет от имени Грэхэма Гласса. — Ред. 2 Около 60 см. — Ред.
Структура книги UNIX — большая система. Чтобы описать ее полностью, требуется объяснение многих различных вопросов с нескольких различных точек зрения. Что я как раз и попытался сделать. Книга разбита на следующие секции, каждая предназначена для конкретной категории пользователей: П Глава 1. Что такое UNIX? П Глава 2. Утилиты UNIX для непрограммистов. □ Глава 3. Утилиты UNIX для опытных пользователей. □ Глава 4. Командные интерпретаторы shell. П Глава 5. Bourne shell. □ Глава 6. Korn shell. П Глава 7. С shell. П Глава 8. Bourne Again shell. □ Глава 9. Организация сети. □ Глава 10. Интернет. □ Глава 11. Пользовательские интерфейсы. □ Глава 12. Инструментальные средства программирования на С. □ Глава 13. Системное программирование. □ Глава 14. UNIX изнутри. □ Глава 15. Системное администрирование. П Глава 16. Будущее. □ Приложение. □ Библиография. Я рекомендую, чтобы различные категории пользователей читали главы так, как представлено в табл. В1. Таблица В1 Категория пользователя Главы Повседневные нерегулярные пользователи 1,2 Опытные пользователи 1-4, 9-11 Программисты 1-13, 16 Системные аналитики 1-14, 16 Мастера Все главы 2 Зак. 786
Структура глав Каждая глава в этой книге имеет перечисленные ниже стандартные вводные разделы. Мотивация Объясняется, почему полезно изучить материал, который представлен в главе. Предпосылки Описано, что читатель должен знать, чтобы успешно усвоить материал главы. Задачи Приводится список представленных тем. Изложение Описывается метод, которым представлены темы. Утилиты Дается список утилит, описываемых в главе (когда уместно). Системные вызовы Приводится список системных вызовов, рассматриваемых в главе (когда уместно). Команды shell Представлен список команд shell, охваченных в главе (когда уместно). Кроме того, каждая глава заканчивается разделом обзора, содержащим перечисленные ниже разделы. Перечень тем Резюме тем. Контрольные вопросы Быстрая самопроверка.
Упражнения Список упражнений, расположенных по рангу: легкий, средний или высокий. Проекты Один или более имеющих отношение к теме главы проектов, расположенных по рангу: легкий, средний или высокий. Руководство для преподавателей Как было упомянуто ранее, эта книга была первоначально написана для студентов старших курсов и аспирантов. Я советую разрабатывать лекционный цикл, основанный на книге, следующим образом. П Если студенты не знают язык С, то среднескоростной курс может начинаться с глав 1, 2, 4 и 12. Лектор может тогда представить студентам С и использовать содержание главы 13 для упражнений в аудитории и проектов. □ Если студенты уже знают язык С, то среднескоростнои курс может включать главы 1, 2, 4, 7, 12—14. Проекты, ориентированные на параллельную обработку и взаимодействие процессов, будут гарантировать, что студенты окончат курс с хорошим знанием основных принципов UNIX. □ Если студенты знают язык С и полны энтузиазма, предлагаю охватить все главы за исключением глав 3, 5 и 6 в одном семестре. Знаю, что это возможно, поскольку я преподавал курс лекций этим способом! Условные обозначения В книге имеются ссылки на утилиты UNIX, команды shell (т. е. команды, которые являются непосредственно частью командного интерпретатора) и системные вызовы (функции библиотеки UNIX). Весьма легко перепутать эти три вещи, так что я принял непротиворечивый способ для их различия: □ утилиты UNIX всегда написаны полужирным моноширинным шрифтом, вот так: "утилита mkdir создает каталог"; П команды shell всегда написаны моноширинным шрифтом, вот так: "команда history выводит ваши предыдущие команды"; □ системные вызовы всегда сопровождаются круглыми скобками, вот так: "системный вызов fork() дублирует процесс".
Формальные описания утилит, команд shell и системных вызовов предваряются выделенной серым цветом строкой, за которой следует синтаксис и разъяснение. Для примера ниже приведено описание утилиты UNIX man. Синтаксис man [глава] слово man -к ключевоеСлово Первое использование man выводит содержимое секций справочника, связанных с параметром слово. Значение параметра глава необязательно. Если номер главы не указан, будет показана первая глава, которую найдет man. Второе использование man выводит список всех статей справочника, которые содержат ключевоеСлово. Примеры UNIX-сессий представлены шрифтом Courier. Пользовательский ввод с клавиатуры всегда показывается курсивом, а примечаниям всегда предшествуют пропуски слов (...). Вот пример: $ 1s ...генерирует листинг каталога. myfile.txt yourfile.txt $ whoami glass $ ... выводится новое приглашение. Ссылки на другие книги Насколько удобно повторно использовать существующий код, настолько хорошо иметь другой справочный материал, когда он не пересекается с естественным потоком изложения. Информация, которая, как мы считаем, слишком специализирована для данной книги, отмечается ссылкой на публикацию в библиографии, приведенной в конце книги. Например, "Для получения информации относительно порта UNIX на процессоре 68030, см. с. 426 из [Wait 1987]". В квадратных скобках обычно указаны имя автора и год публикации, когда книге дано право "относиться к литературе по UNIX".
Доступность исходного кода в режиме on-line Примеры исходного кода, используемого в этом издании, доступны в режиме on-line. Короткие примеры не включены, но примеры любой "существенной” длины могут быть найдены в сети по адресу ftp://ftp.prenhall.com/pub/esm/the_apt__series.s-042/glass_ables_unix-3e/. (Вы можете напечатать эту строку в браузере или см. главу 9 для получения дополнительной информации об FTP.)
Благодарности Следующие люди способствовали выпуску предыдущих изданий этой книги: Джеймс Ф. Петерс (James F. Peters), Фади Диик (Fadi Deek), доктор Уильям Бурне (Dr. William Burns), Ричард Невман-Волф (Richard Newman-Wolfe), Дэвид Карвер (David Carver), Билл Тепфенхарт (Bill Tepfenhart), Стивен Раго (Stephen Rago) и Марк Эллис (Mark Ellis). Этому изданию способствовал ценный технический вклад от Лори Мурфи (Lori Murphy), Лоренса Б. Веллса (Lowrence В. Wells) и Майкла Д. Брека (Michael D. Breck). Как всегда, сотрудники Prentice Hall — особенно Петра Ректер (Petra Recter), Камилла Трентакост (Camille Trentacoste) и Лакшми Баласубраманиан (Lakshmi Balasubramanian) — всегда были благосклонны и ободряли нас.
Глава 1 Что такое UNIX? Мотивация UNIX — хорошо известная в техническом мире операционная система, популярность которой в последнее время растет и в деловых кругах. Знание ее возможностей и особенностей поможет понять, почему все больше и больше людей предпочитает использовать UNIX, и сделает вашу работу более эффективной. Предпосылки Для понимания данной главы необходим небольшой опыт работы с компьютером и знакомство с такими компьютерными терминами, как программа, файл и центральный процессор (ЦП). Задачи В этой главе будет дано определение термину "операционная система" н описаны ее основные компоненты, а также рассказано, почему UNIX очень перспективна. Мы рассмотрим эту систему с нескольких различных ракурсов, поэтому информация будет интересна и полезна достаточно широкой аудитории, от начинающего пользователя до продвинутого системного программиста. Изложение Сначала будет рассказано о главных частях и элементах, которые формируют обычную компьютерную систему. Затем мы убедимся, насколько необходима специальная программа, называемая операционной системой, чтобы эффективно управлять этими частями, и рассмотрим некоторые ее возможности. Далее обратимся к философии UNIX, которая лежит в основе всей
этой книги. И, наконец, познакомимся с краткой историей UNIX и получим некоторое представление, о ее (т. е. системы) происхождении. Компьютерные системы Обычная однопользовательская компьютерная система состоит из многих частей, таких как центральный процессор (ЦП- Central Processing Unit, CPU), память, диски, монитор и клавиатура. Маленькие системы, подобные этой, могут быть связаны вместе, чтобы формировать большие компьютерные сети, распределять задачи между отдельными компьютерами. Рис. 1.1 является иллюстрацией такой сети. ОЗУ ПЗУ Рис. 1.1. Типичная компьютерная сеть
Аппаратные средства ЭВМ, которые составляют компьютерную сеть — только половина истории; программное обеспечение, которое работает на компьютерах, не менее важно. Давайте рассмотрим детальнее различные аппаратные средства ЭВМ и компоненты программного обеспечения компьютерной системы. □ Аппаратные средства (hardware). Компьютерные системы, большие или маленькие, одно- или многопользовательские, дорогие или дешевые, состоят из множества компонентов. П Центральный процессор (ЦП). ЦП (Central Processing Unit, CPU) читает машинные коды (инструкции в форме, которую компьютер может понимать) из памяти и выполняет их. Как часто считают, ЦП является "мозгом" компьютера. П Оперативное запоминающее устройство (ОЗУ). ОЗУ (Random Access Memory, RAM) хранит машинные коды и данные, к которым обращается ЦП. ОЗУ обычно "забывает" все, что хранит, когда питание выключено. □ Постоянное запоминающее устройство (ПЗУ). ЗУ (Read Only Memory, ROM) хранит машинные коды и данные. Его содержимое не изменяется и хранится, даже когда питание выключено. □ Диск (disk). Диски хранят большое количество данных и кода в магнитной или оптической среде и "помнят” все это, даже когда питание выключено. Дискеты, как правило, сменные, тогда как жесткие диски — нет. Объем жестких дисков позволяет хранить на нем гораздо больше информации, чем на дискете. □ Накопитель CD-ROM (CD-ROM Drive). Накопители CD-ROM позволяют компьютеру читать информацию, записанную в цифровой форме, с компактного диска. Информация может представлять собой поток данных или файловую систему, которую ОС (операционная система) может читать так, как если бы она была расположена на жестком диске. □ Монитор (monitor). Мониторы отображают информацию и поставляются в двух разновидностях: монохромные и цветные. Монохромные мониторы редки в более новых (современных) компьютерных системах. □ Видеокарта (Graphics card). Видеокарты позволяют ЦП показывать информацию на мониторе. Некоторые графические карты могут показывать только знаки, тогда как другие поддерживают графику.
□ Клавиатура (keyboard). Клавиатура позволяет пользователю вводить алфавитно-цифровую информацию. Доступны несколько различных видов раскладок клавиатуры, что частично-зависит от языка пользователя. Например, японская раскладка клавиатура больше, чем западная, поскольку алфавит первой намного больше. Западная раскладка клавиатуры часто называется QWERTY-клавиатура — по первым шести символам левой верхней строки. □ Мышь (mouse). Мышь обеспечивает легкое позиционирование курсора на экране короткими движениями руки. Большинство мышей имеет ’’хвосты”, которые соединяют их с компьютером, но некоторые имеют радио- или инфракрасные связи, которые делают ’’хвост" ненужным. Беспроводная форма будет весьма удобна для того, кто имеет кота, т. к. эти животные очень часто запутываются в этом проводе. □ Принтер (printer). Принтер позволяет пользователю получить твердую копию информации. Некоторые принтеры печатают только знаки, тогда как другие печатают графику. □ Лента (tape). Магнитные ленты используются для создания резервных копий информации, хранящейся на дисках. Они медленнее, чем диски, но хранят большие количества данных и довольно дешевы. □ Модем (modem). Модем позволяет связываться с другими компьютерами по телефонной линии. Различные модемы допускают разные скорости связи. Большинство модемов даже исправляет ошибки, которые происходят из-за плохой телефонной связи. □ Ethernet-интерфейс (Ethernet interface). Ethernet — это среда (обычно провода), которая делает доступной связь на высоких скоростях. Компьютеры подсоединяются к Ethernet через специальное устройство аппаратных средств, называемое интерфейсом Ethernet. □ Другие периферийные устройства (peripherals). Существует множество периферийных устройств, которые могут поддерживать компьютерные системы, включая графические планшеты, оптические сканеры, матричные процессоры, звуковые карты, карты распознавания голоса и синтезаторы (это далеко не полный список). Вы не можете просто соединить эти части аппаратных средств ЭВМ вместе и иметь рабочую систему: необходимо установить программное обеспече
ние, управляющее и координирующее все части. Способность разделять периферийные устройства, распределять память, связываться с другими компьютерами, выполнять более, чем одну программу одновременно обеспечивается специальным видом программы, называемой операционной системой (ОС). Можно представить себе ее как "суперпрограмму", которая обеспечивает работу остальных программ. Давайте поближе познакомимся с операционными системами. Операционные системы Как вы могли заметить, компьютер не может функционировать без операционной системы. Существует множество различных операционных систем, доступных для персональных компьютеров (ПК — Personal Computer, PC), мини-компьютеров и универсальных ЭВМ; наиболее распространенными являются Windows NT и Windows 20001, VMS, MacOS и разновидности UNIX. Операционная система UNIX доступна для различных платформ, тогда как большинство других ОС привязано к определенному семейству аппаратных средств. Одно из главных достоинств в UNIX — доступность практически для любого компьютера. Из перечисленных операционных систем только UNIX и VMS позволяют использовать ресурсы компьютера более, чем одному пользователю одновременно, что является очевидным преимуществом для коммерческих систем. Многие фирмы покупают мощный мини-компьютер с двадцатью или более терминалами и устанавливают операционную систему UNIX, позволяющую распределять ЦП, память и дисковое пространство между пользователями. Что же мы получаем, когда выбираем UNIX, как операционную систему? Давайте рассмотрим ее с точки зрения программного обеспечения. Программное обеспечение Один из способов описать аппаратные средства системы состоит в том, чтобы рассказать, какие они обеспечивают условия для выполнения программ и хранения файлов. Виды программ, работающих на UNIX-платформах, различаются по размеру и сложности, но имеют некоторые общие характеристики. Далее приведен список характеристик UNIX-программ и файлов. □ Файл — набор данных, который обычно хранится на диске или другом носителе. UNIX обращается с периферийными устройствами как со специальными файлами, поэтому терминалы, принтеры и другие устройства были доступны таким же образом, как файлы на обычном диске. * В настоящий момент есть и другие версии Windows. — Ред.
□ Программа — собрание байтов, представляющих код и данные, которые хранятся в файле. П Запущенная программа загружается с диска в ОЗУ (фактически загружена только ее часть, но мы поговорим об этом позже). Когда программа выполняется, она называется процессом. □ Большинство процессов читает и пишет данные через файлы. □ Процессы и файлы имеют владельца и могут быть защищены от несанкционированного доступа. □ UNIX поддерживает иерархическую структуру каталогов. □ Файлы и процессы имеют "местоположение" в пределах иерархии каталогов. Процесс может изменять его собственное местоположение или местоположение файла. □ UNIX предоставляет возможность создания, модификации и уничтожения программ, процессов и файлов. На рис. 1.2 приведена иллюстрация крошечной иерархии UNIX-каталогов, которая содержит четыре файла и процесс, управляющий обслуживающей программой sort. / (Корневой каталог) I---------------1---------------------. home bin •---------------1--------------• — glass tim who sort myfile.txt afile.txt Обозначения: Процесс Файл Рис. 1.2. Иерархия каталогов Разделение ресурсов Другая функция операционной системы, которую реализует UNIX, — разделение ограниченных ресурсов среди конкурирующих процессов. Чаще всего
ограниченные ресурсы в компьютерной системе включают ЦП, память, место на диске и периферийные устройства типа принтеров. Вот краткая схема того, как эти ресурсы разделяются. □ UNIX разделяет ЦП среди процессов путем деления каждой секунды процессорного времени на "кванты" равного размера (обычно 1/10 секунды) и затем выдает их процессам на основе системы приоритетов. Важным процессам выделяется большее количество квантов, чем другим. □ UNIX разделяет память среди процессов путем деления ОЗУ на тысячи "страниц" памяти равного размера и затем выделяет их процессам на основе системы приоритетов. Только те части процесса, которые фактически должны быть в ОЗУ, всегда загружаются с диска. Страницы ОЗУ, к которым не обращаются некоторое время, вновь сохраняются на диск так, чтобы память могла быть перераспределена другим процессам. □ UNIX разделяет дисковое пространство среди пользователей путем деления дисков на тысячи "блоков" равного размера и затем выделяет их пользователям согласно системе квот. Отдельный файл построен из одного или более блоков. Глава 14 содержит подробное описание, как реализуется механизм разделения ресурсов. Итак, мы рассмотрели все функции, которые выполняет UNIX как операционная система, кроме одной — среды коммуникации. Коммуникация Компоненты системы малоэффективны без взаимодействия друг с другом. Это хорошо иллюстрируют следующие примеры: □ процесс может нуждаться во взаимодействии с видеокартой, чтобы вывести результаты на экран; □ процессу требуется взаимодействие с клавиатурой, чтобы получить входные данные; □ почтовой системе необходимо взаимодействие с другими компьютерами, чтобы посылать и получать почту; □ два процесса должны взаимодействовать друг с другом для совместного решения отдельной проблемы. В зависимости от типа и скорости связи UNIX предусматривает несколько различных способов взаимодействия процессов и периферийных устройств. Например, один из путей, посредством которого процесс может взаимодействовать с другим процессом, —- это механизм межпроцессной связи, называемый pipe (конвейер). Конвейер — это односторонний канал данных средней скорости, который позволяет взаимодействовать двум процессам на той
же самой машине. Если процессы находятся на различных машинах, связанных сетью, то вместо него используется механизм, называемый сокетом (socket — гнездо, двунаправленный канал). Сокет — двусторонний быстродействующий канал данных. Разделение задачи между различными процессами — распространенная в настоящее время технология. Например, есть графическая система X Window, которая работает, используя так называемую клиент-серверную модель. Один компьютер (Х-сервер) используется для управления графическим терминалом и рисования различных линий, кругов и окон, в то время как другой (X-клиент) воспроизводит данные, которые должны быть показаны. Системы, подобные этой, являются примерами распределенной обработки, в которой вычислительная нагрузка разделена среди нескольких компьютеров. Фактически единственный Х-сервер может обслуживать множество Х-клиентов. На рис. 1.3 представлена иллюстрация X Window System. Х-сервер Ethernet Рис. 1.3. Х-сервер и Х-клиенты Мы обсудим X Window System в главе 11. Утилиты Даже очень мощная операционная система не представляет большой ценности для пользователя, если не содержит достаточного количества полезных программ. Успех на рынке и достаточно ’’солидный” возраст UNIX делают очень разнообразным состав входящего в эту операционную систему программного обеспечения. Стандартная UNIX-система дополняется, как минимум, парой редакторов, С-компилятором, утилитами сортировки, графическим пользовательским интерфейсом, различными оболочками, программами обработки текста. Коммерчески доступны популярные пакеты, включающие в
себя электронные таблицы, компиляторы, издательские системы и т. д. Кроме того, большое количество бесплатного программного обеспечения распространяется через Интернет, которому посвящена глава 10. Поддержка программиста Система UNIX очень удобна для программистов. Это открытая система, внутренняя программная архитектура которой хорошо документирована и доступна либо в форме исходного текста, либо за небольшую плату. Особенности этой операционной системы, такие как параллельная обработка, взаимодействие процессов и работа с файлами, — все является легко доступным из языка программирования С и набора библиотечных подпрограмм, называемых системными вызовами. Многие функции, использование которых было затруднено в старых операционных системах, теперь легкодоступны для любого системного программиста. Стандарты Эта операционная система придерживается определенных стандартов, разработанных двумя основными группами. UNIX была создана в AT&T Bell Laboratories и впоследствии развилась в систему, известную как System И Калифорнийский Университет (Беркли) получил копию UNIX в самом начале его разработки и создал другую версию, впоследствии ставшую доминирующей, — Berkeley Standard Distribution (BSD) UNIX. System V и BSD UNIX имеют свои сильные и слабые стороны, но в них и много общего. Два консорциума ведущих компьютерных изготовителей развивают каждый свою систему и полагают, что их версия будет лучшей. Консорциум UNIX International, возглавляемый AT&T и Sun, поддержал самую последнюю версию System V UNIX — System V Release 4. Группа Open Software Foundation (OSF), возглавляемая IBM, Digital Equipment Corporation и Hewlett-Packard, попыталась создать преемника BSD UNIX, названного OSF/1. Обе группы следовали набору стандартов, установленных комитетом Portable Operating System Interface (POSIX) и подобными организациями. Проект OSF не так давно провалился, сделав System V "победителем UNIX-войны”, хотя лучшие черты BSD UNIX были включены в большинство версий операционных систем, базирующихся на System V. В разной степени черты BSD UNIX свойственны таким дистрибутивам, как Solaris (от Sun Microsystems), HP-UX (от Hewlett-Packard), AIX (от IBM) и IRIX (от Silicon Graphics, Inc). Система UNIX написана главным образом на языке С, который делает относительно несложным ее перенос на различные аппаратные платформы. Такая мобильность — одно из основных свойств, способствующих быстрому распространению и успеху UNIX.
Особенности UNIX Краткий перечень основных особенностей UNIX таков: □ позволяет нескольким пользователям одновременно взаимодействовать с системой; □ поддерживает создание, модификацию и уничтожение программ, процессов и файлов; □ реализует иерархическую систему каталогов; □ эффективно разделяет ресурсы системы: ЦП, память и дисковое пространство между процессами; □ позволяет процессам и внешним устройствам, взаимодействовать друг с другом, даже если они находятся на различных компьютерах; □ включает в себя большое количество различных утилит; □ для большинства версий UNIX имеется множество коммерческих программных пакетов; □ позволяет программистам взаимодействовать с операционной системой через набор системных вызовов, аналогичных библиотеке подпрограмм. UNIX — мобильная операционная система, доступная практически на всех аппаратных платформах. Теперь, после того как мы рассмотрели основные особенности UNIX, пришло время исследовать принципы ее организации и заглянуть в прошлое и будущее. Принципы UNIX Исходная реализация UNIX-системы была весьма и весьма ограничена. Она содержала небольшое число утилит, не имела практически никаких сетевых возможностей и средств администрирования. Первые разработчики UNIX выработали основной принцип, положенный в основу создания утилит: программа должна хорошо справляться с конкретной проблемой, а сложные задачи выполняются путем использования этих утилит вместе. Так возник специальный механизм, называемый конвейером (pipe). Конвейер предоставляет возможность использовать выходные данные одного процесса как входные данные для другого процесса. Два или более процесса могут быть связаны этим способом, создающим конвейер данных, текущих от первого процесса до последнего, как показано на рис. 1.4 и 1.5.
Рис. 1.4. Конвейер устройство Рис. 1.5. Сортирующий конвейер Компоновка процессов в виде конвейера оказалась исключительно эффективной. Каждый процесс в этом случае выполняет набор операций над данными и затем передает результаты следующему процессу для дальнейшей обработки. Например, вообразите, что вы желаете получить отсортированный список всех пользователей UNIX-системы. Есть утилита who, которая выводит несортированный список пользователей, и другая утилита sort, которая выводит отсортированную версию ее входных данных. Обе утилиты могут быть связаны вместе каналом так, чтобы выходные данные от who передавались непосредственно в sort, что дает в результате отсортированный список пользователей. Это более эффективный подход к решению проблем, чем написание новой программы с нуля или использование двух программ, одна из которых должна будет сохранять промежуточные данные во временном файле, который в последствии будет использоваться второй программой. Основной алгоритм UNIX, подходящий для решения любой задачи, можно выразить следующим образом: □ если можно решить проблему, используя каналы для объединения существующих утилит, делайте это; □ иначе обратитесь к другим пользователям в Интернете. Если они знают, как решить эту проблему, воспользуйтесь их советом; □ иначе если вы можете написать собственную утилиту для решения этой проблемы — напишите ее и добавьте в коллекцию UNIX. Проектируйте каждую утилиту так, чтобы она хорошо справлялась с поставленной задачей и могла использоваться другими для решения аналогичных проблем. Если дописанные утилиты не могут решить проблему, напишите программу для ее решения (например, на С, C++ или Java). ОС UNIX реализует еще одну концепцию, от которой постепенно приходится отказываться. Изначально система была разработана программистами, которые хотели иметь доступ к данным или коду вне зависимости от уста
новленных прав доступа. Для реализации этой идеи они разработали концепцию суперпользователя (привилегированного пользователя, root), которая подразумевала получение неограниченных прав некоторыми пользователями. Например, администратор UNIX-системы всегда имеет возможность стать привилегированным пользователем для выполнения таких задач, как завершение нестандартных процессов или удаление нежелательных пользователей из системы. Очевидно, что концепция суперпользователя подрывает систему безопасности: любой пользователь с правильным паролем может получить доступ к защищенным данным или уничтожить всю систему. Поэтому в некоторых, находящихся в разработке, версиях UNIX полностью отказываются от концепции привилегированного пользователя, подразделяя задачи между несколькими "менее привилегированными". Прошлое UNIX Кен Томпсон (Ken Thompson) из Bell Laboratories разработал самую первую версию UNIX. Кен работал над проблемой создания видеоигры под названием "Космические войны" ("Space Wars"), которая требовала быстрой реакции системы. Используемая им операционная система MULTICS не давала ему той производительности, в которой тот нуждался. Он назвал свою систему UNIX: часть названия "UNI" подразумевала, что она будет делать нечто единственное хорошо, в противоположность "MULTI" — части имени "MULTICS" — которая пыталась делать многое, но без особого успеха. Кен написал систему на ассемблере, и первая версия оказалась очень простой: это была однопользовательская система без каких-либо сетевых возможностей с примитивной системой управления разделением памяти. Однако она была компактной и быстродействующей, как и хотел Кен Томпсон. Несколькими годами позже коллега Кена, Деннис Ритчи (Dennis Ritchie), предложил переписать UNIX, используя язык С, который Деннис недавно разработал на основе языка В. Идея написания операционной системы на языке высокого уровня в те времена была необычной. Большинство программистов полагали, что скомпилированный код не будет работать достаточно быстро2 и что для операционной системы обоснованно только прямое использование машинного языка. К счастью, выбор С оказался удачным, и система UNIX внезапно получила огромное преимущество над другими операционными системами: ее исходный код был понятен. На ассемблере осталась лишь небольшая часть, а это означало возможность переноса операционной системы на другую платформу. Если платформа имеет С-компилятор, большая часть кода будет работать без изменений; должны быть переписаны только секции ассемблера. 2 С тех пор технология компиляторов также претерпела изменения, поэтому большинство компиляторов создает более эффективный код.
Bell Laboratories начала использовать этот прототип версии UNIX в ее патентном отделе, прежде всего, для обработки текста, и множество UNIX-утилит, которые присутствуют в современных UNIX-системах — например, nroff и troff — были разработаны в этот период. Но в то время в соответствии с антимонопольными инструкциями AT&T были запрещены продажи программного обеспечения, поэтому Bell Laboratories бесплатно передала лицензию на исходный код UNIX университетам, надеясь, что инициативные студенты расширят систему и поспособствуют ее продвижению на рынок. Действительно, аспиранты Университета Калифорнии в Беркли отнеслись к задаче серьезно и внесли немало усовершенствований, включая создание хорошей системы управления памятью и реальной возможности организации сети. Университет начал продавать всем желающим свою собственную версию UNIX, названную Berkeley Standard Distribution (BSD) UNIX. Различия между версиями UNIX сохраняются и по сей день. Настоящее UNIX Многие компании производят и продают собственные версии UNIX, обычно предназначенные для работы на собственных аппаратных платформах. Не так давно появилась еще одна UNIX-подобная операционная система — Linux. В разработке Linux участвовали многие программисты со всего мира, и теперь она продается и поддерживается несколькими различными компаниями. UNIX Рис. 1.6. Сокращенная UNIX-генеалогия
Предыдущие версии UNIX базировались либо на System V, либо на BSD, тогда как современные включают в себя особенности обеих систем. На рйс. 1.6 представлена сокращенная генеалогия UNIX. Так как ОС Linux полностью написана заново и не использует общих кодов UNIX, она не входит в состав "генеалогического дерева". Тем не менее, ощущается значительное влияние всех версий UNIX на создание и развитие этой операционной системы. В главе 16 мы увидим, какие версии UNIX являются доступными для различных аппаратных платформ. Будущее UNIX Вероятно, последующие версии UNIX будут поддерживать ее философию подобно современным версиям UNIX — например, сохраняя идею построения приложения из конвейера связанных утилит. Кроме того, UNIX должна реализовать некоторые актуальные тенденции, такие как параллельная обработка и объектно-ориентированное программирование. Мы рассмотрим ряд вопросов, связанных с перспективами развития UNIX, в главе 16. Остальная часть этой книги Теперь вы, скорее всего, осознали, что описание UNIX — довольно обширная тема, которая может быть должным образом усвоена лишь небольшими порциями. Для удобства пользователей и предоставления возможности сосредоточиться на наиболее интересных для них темах главы книги ориентированы на различные категории пользователей. Эти пользователи могут быть объединены в следующие группы: □ непрограммисты, или простые пользователи, которым время от времени необходимо выполнять простые задачи, такие как отправление и получение электронной почты, использование электронных таблиц или обработка текстов; □ пользователи shell (shell — командный интерпретатор), использующие фоновую обработку и пишущие небольшие программы на макроязыке shell в рамках пользовательского интерфейса; □ опытные пользователи, применяющие шифрование файлов, потоковые редакторы и файловую обработку данных; □ опытные пользователи shell, пишущие программы на языке высокого уровня shell (он немного похож на язык управления задачами, или JCL) для того, чтобы автоматизировать такие задачи, как создание резервных
копий файлов, мониторинг использования диска, установка программного обеспечения; □ программисты, создающие программы на языке типа С; □ системные программисты, которым необходимо хорошее знание операционной системы для создания программ взаимодействия с сетью или доступа к файлам; □ системные архитекторы, совершенствующие компьютерные системы; □ системные администраторы, поддерживающие работу системы и пользователей. Читайте наиболее заинтересовавшие вас главы. Затем, если располагаете временем, вернитесь назад и заполните пробелы в своих знаниях. Если вы не можете определить, где содержится необходимая информация, ознакомьтесь с Введением. Обзор главы Перечень тем В этой главе мы познакомились с: □ главными компонентами аппаратных средств системы; П назначением операционной системы; □ значением терминов программа, процесс и файл', □ схемой иерархической структуры каталогов; П разделением процессорного времени, памяти, дискового пространства между процессами; П взаимодействием между процессами и внешними устройствами; □ набором стандартных утилит UNIX; П главными пакетами программ, доступными для UNIX-систем; П концепцией "открытой" системы; □ перспективами развития UNIX. Контрольные вопросы 1. Как называются основные версии UNIX, как они развивались? 2. Назовите пять главных функций операционной системы. 3. Укажите различие между процессом и программой.
4. Расскажите об основных концепциях, легших в основу UNIX. 5. Назовите создателей UNIX. 6. Почему UNIX называется "открытой" системой? Упражнение Составьте список популярных в настоящее время операционных систем, отличных от UNIX, выделите их достоинства и недостатки. [Уровень: средний.] Проект Рассмотрите систему MULTICS и найдите сходство и различия с UNIX-системой. [Уровень: средний.]
Глава 2 Утилиты UNIX для непрограммистов Мотивация Эта глава содержит основы, необходимые вам для работы с UNIX. Предпосылки Для понимания изложенной ниже информации вам необходимо ознакомиться с главой 7. Кроме того, более глубокому усвоению будет способствовать наличие UNIX на вашем компьютере для того, чтобы вы могли познакомиться на практике с теми особенностями, которые мы рассмотрим в теории. Цели В этой главе мы познакомимся с процедурой входа/выхода из системы, научимся изменять пароль, пользоваться встроенным справочником, работать с файловой системой. Кроме того, мы узнаем, как пользоваться почтовой системой, что станет первым шагом на нашем пути в Интернет. Представление Информация в этой главе представлена в форме нескольких примеров UNIX-сессий. Если сейчас на вашем компьютере не установлена ОС UNIX, попробуйте повторить описанные процедуры, как только появится такая возможность.
Утилиты Ниже в алфавитном порядке приведен список стандартных утилит UNIX: cancel head mv wc cat Ip newgrp chgrp Ipr page chmod Iprm passwd chown Ipq pwd clear Ipstat rm cp Is rmdir date mail stty emacs man tail file mkdir tset groups more vi Команда shell Этот раздел посвящен следующей команде shell: cd Получение учетной записи Для того чтобы установить UNIX-систему на своем компьютере, вы можете купить один цз представленных дистрибутивов Linux в любом компьютерном магазине либо скачать ее из Интернета. Если вы располагаете необходимыми средствами, то можете приобрести коммерческий дистрибутив UNIX. В настоящее время существуют как коммерческие, так и бесплатные версии UNIX (см. главу 16). Преимущество в наличии собственной UNIX-системы состоит в том, что вы можете быть привилегированным пользователем, полноправно распоряжающимся всеми ресурсами. Если у вас нет возможности установить UNIX, то для того, чтобы поработать с этой операционной системой, вам придется получить учетную запись у обладателя этой установленной системы. Естественно, ваши права в этом случае будут сильно ограничены.
Вход в систему Первое, что необходимо сделать для работы с UNIX-системой — войти в нее, бведя учетное имя пользователя (suitable username) — уникальную комбинацию символов, отличающую вас от других пользователей. Как правило, учетное имя пользователя и пароль назначаются администратором системы, либо в случае, если вы установили UNIX на свой компьютер, эти параметры установлены в процессе конфигурации или заложены по умолчанию. Бывает, необходимо нажать клавишу <Enter> (также известна как клавиша <Return>) несколько раз, прежде чем появится приглашение ввести имя пользователя (login) и пароль (password). Из соображений безопасности символы, которые вы вводите при наборе пароля, не отображаются. UNIX чувствительна к регистру клавиатуры, поэтому удостоверьтесь, что вводите имя пользователя и пароль в том регистре, в котором оно было выдано вам администратором. В зависимости от настроек системы вы должны увидеть приглашение $ или %. Эти символы означают, что регистрация в системе прошла успешно, и она ожидает ваших дальнейших команд. Так выглядит процедура регистрации пользователя в UNIX: UNIX(г) System V Release 4.0 login: glass Password: ...то, что я напечатал здесь — секрет и не показано Last login: Sun Feb 15 18:33:26 from dialin $ _ В процессе регистрации система спросит вас, какой вид терминала вы используете для того, чтобы адекватно реагировать на вводимые вами символы. Если вам неизвестна эта информация, просто нажмите клавишу <Enter>, тем самым соглашаясь использовать установленный по умолчанию терминал. Позже будет рассказано, как в случае необходимости изменить тип терминала. В зависимости от настроек системы в процессе регистрации может происходить следующее: □ если вы входите в систему в первый раз, вам может быть предложено пройти ознакомительный тур по UNIX; □ на вашем экране могут появляться новости дня и другая полезная информация. Ниже приведен еще один пример входа в систему, где предлагается выбрать тип терминала. Нажав клавишу <Enter>, мы подтверждаем выбор терминала по умолчанию — vtioo: UNIX(г) System V Release 4.0 login: glass Password: ...секрет
Last login: Sun Feb 15 21:26:13 from dialin You have mail. ...система сообщает о наличии почты. TERM = (vtlOO) ...я нажал клавишу <Enter>. Командные интерпретаторы — shell Приглашения $ или %, которые пользователь видит, когда в первый раз регистрируется в UNIX, выводятся специальным видом программы, называемой командным интерпретатором или shell, являющейся посредником между пользователем и операционной системой. Shell позволяет выполнять программы, строить конвейеры из процессов, сохранять результаты в файлы и управлять несколькими программами одновременно. Shell выполняет все команды, которые вы вводите. Существуют четыре наиболее популярных программных оболочки: □ Bourne shell; □ Korn shell; П C shell; □ Bourne Again shell (или Bash). Все эти оболочки похожи друг на друга, хотя и имеют некоторый ряд отличий. Большинство пользователей предпочитают Korn shell, потому что эта оболочка имеет лучший интерфейс командной строки и в ней легко программировать. Каждой оболочке посвящена одна из глав этой книги. Но до этого, в главе 4, мы рассмотрим, общие принципы работы с shell. Каждый shell имеет свой собственный язык программирования. Вы можете спросить, зачем писать программу на языке shell, а не языке С или Java? Ответ — языки shell разработаны специально для управления файлами и процессами в UNIX, поэтому во многих ситуациях они более удобны. В этой главе мы научимся пользоваться разнообразными утилитами UNIX и сохранять результаты работы в файл. Рассмотрим выполнение нескольких простых UNIX-команд. Выполнение программ Для того чтобы запустить программу, просто вводят ее название и нажимают клавишу <Enter>. Давайте договоримся, что в тех случаях, когда в книге говорится, что вы должны ввести какой-нибудь текст, имеется в виду также, что вы должны нажать клавишу <Enter> после того, как закончите набор. Этим вы сообщаете операционной системе, что закончили ввод команды и желаете, чтобы она была выполнена.
Все системы обладают разным набором утилит, так что, возможно, некоторые примеры не будут работать в вашей версии UNIX. Рассматривая специфические утилиты, мы будем указывать, в каких версиях они будут работать. А сейчас рассмотрим утилиту date, имеющуюся в каждой системе и показывающую текущую дату и время. $ date ... запуск утилиты date. Thu Mar 12 10:41:50 MST 1998 $ _ Для описания синтаксиса используется интуитивно понятная система обозначений в форме Бэкуса—Наура (Backus—Naur FORM, BNF), расшифровка которой описана в Приложении. Книга не ставит своей целью описать все параметры какой-либо утилиты. При необходимости вы можете узнать их, пользуясь встроенным в систему справочником или специализированной литературой. Синтаксис date [yymmddhhmm [.ss]] Утилита date по умолчанию показывает текущие дату и время. В остальных случаях date возвращает заданные в параметрах значения, где уу — последние две цифры года, первые mm — месяц (числовая нумерация), dd — день, hh — час (используется 24-часовая система) и следующие mm — минуты. Дополнительный параметр — ss — секунды. Устанавливать дату может только привилегированный пользователь (root). Ниже описана команда, очищающая экран. Синтаксис clear Эта утилита очищает экран. Входной, выходной каналы и канал сообщения об ошибках Результаты выполнения команды date, рассмотренной в предыдущем разделе, выводились на терминал. Кроме того, что UNIX может записывать полу
ченные результаты в файл, для любой команды или программы существуют три стандартных канала ввода/вывода: □ стандартный вход, известный как stdin, при помощи которого программа получает входные данные; П стандартный выход, называемый stdout, в который по умолчанию программа пишет выходные данные; □ стандартный канал вывода сообщений об ошибках — stder. По умолчанию все три канала ввода/вывода взаимодействуют с терминалом, выполняющим команду или программу, что позволяет одним программам использовать результаты выполнения других как входные данные. Вывод результатов работы одной команды может быть легко передан на вход другой с помощью переназначения. Чуть позже мы поподробнее остановимся на переназначении ввода/вывода. А более подробно разберемся с механизмом в работы каналов в главе 13. Получение оперативной помощи: man При работе часто случается, что вы не знаете, что делает или как называется та или иная утилита, или, возможно, не помните ее синтаксиса. Для выхода из такой ситуации во всех версиях UNIX предусмотрен встроенный справочник, вызываемый по команде man (сокращение от англ, manual — справочник). Синтаксис man [ [—s] раздел] слово man -к ключевое слово На страницах этого справочника собрана вся документация по UNIX, предназначенная для работы в диалоговом режиме и разделенная на восемь секций. В справочнике содержится информация об утилитах, системных вызовах, форматах файлов и командных интерпретаторах (shell). При выводе справки о некоторой конкретной утилите указывается также, к какой секции она принадлежит. При первом обращении man выводит содержимое раздела справочника, связанного с интересующей вас командой. Некоторые версии UNIX используют аргумент -s, чтобы указать номер секции. Если номер секцищ не указан, будет показана первая секция, которую найдет man. Второе использование man выводит список всех статей справочника, которые содержат ключевое_слово (keyword).
Справочник содержит следующие разделы. 1. Команды и прикладные программы. 2. Системные вызовы. 3. Библиотечные функции. 4. Специальные файлы. 5. Файловые форматы. 6. Игры. 7. Разное. 8. Утилиты системного администрирования. Иногда ключевое слово входит в несколько различных секций справочника. Например, есть утилита chmod, описание которой находится в секции 1, и системный вызов chmod (), информация о котором находится в секции 2. По умолчанию man выдает первую статью, в которой встречается искомое слово. В случае повторного поиска программа выдаст список всех статей, в которых искомое слово встречается. Ниже приведен пример работы утилиты man. $ man -к mode chmod (IV) chmod, fchmod (2V) getty (8) ieeeflags (3M) umask (2V) $ man chmod ...поиск ключевого слова "mode". - change the permissions mode of a file - change mode of file - set terminal mode - mode and status function - set file creation mode mask ...выбор первой статьи справочника. CHMOD(IV) USER COMMANDSCHMOD (IV) NAME chmod — change the permissions mode of a file SYNOPSIS chmod C -fR V mode filename ... ...the description of chmod goes here. SEE ALSO csh(l), Is(IV), sh(l), chmod (2V), chown(8) $ man 2 chmod ...выбор статьи справочника из секции 2. CHMOD(2V) SYSTEM CALLS CHMOD(2V) NAME chmod, fchmod — change mode of file SYNOPSIS #include <sys/stat.h> int chmod (path, mode)
char *path; mode_t mode; ...the description of chmod () goes here. SEE ALSO chown(2V), open(2V), stat(2V), sticky(8) $ Специальные символы Некоторые символы интерпретируются специальным образом, вводятся с UNIX-терминала. Такие знаки называются метасимволами и могут быть выведены утилитой stty с опцией -а (от англ. all). Утилита stty более подробно рассматривается в конце этой главы. Пример: $ stty -а ...получение списка метасимволов терминала speed 38400 baud; -parity hupcl rows = 24; columns = 80; ypixels = 0; xpixels = 0; -inpck -istrip ixoff imaxbel crt tostop iexten erase kill werase rprnt flush Inext susp intr quit stop eof Лн Ли Aw ло AV Лг/Лу Лс Л\ Лз/Ло $ _ Знак Л перед каждым символом означает, что клавиша <Ctrl> должна быть нажата одновременно с символом. В табл. 2.1 перечислены значения по умолчанию. Описание символов этого списка ожидает вас в других главах данной книги, однако о некоторых из них мы поговорим прямо сейчас. Таблица 2.1. Опции утилиты stty Опция Описание erase Сдвиг назад на один символ kill Стирание всей текущей строки werase Стирание последнего слова rprnt Повторение строки flush Игнорирование любого незаконченного ввода и повторный вывод строки Inext Отказаться от рассмотрения следующего символа, как специального susp Приостановка процесса для будущего пробуждения
Таблица 2.1 (окончание) Опция Описание Intr Завершение (прерывание) фоновой работы без дампа ядра операционной системы quit Завершение фоновой работы и генерация дампа ядра операционной системы stop Остановка/возобновление вывода на терминал Eof Конец ввода Завершение процесса: <Ctrl>+<C> Иногда возникает необходимость завершить программу до того, как она выполнится. Сделать это можно, нажав комбинацию клавиш <Ctrl>+<C>. Большинство программ сразу же реагируют, выводя приглашение shell. Но есть программы, которые невозможно завершить таким способом. Давайте посмотрим на примере, что происходит при нажатии этих клавиш: $ man chmod CHMOD(IV) USER COMMANDS CHMOD(IV) NAME chmod — change the permissions mode of a file SYNOPSIS ЛС ...прерывание работы и возвращение в shell. $_ Приостановка вывода: <Ctrl>+<S>/<Ctrl>+<Q> Иногда, в результате выполнения команды выводится слишком много данных, которые не помещаются на экране, в таких случаях можно приостановить вывод, нажав комбинацию клавиш <Ctrl>+<S>. Для возобновления вывода необходимо вновь воспользоваться этой комбинацией (<Ctrl>+<S>) или нажать комбинацию клавиш <Ctrl>+<Q>. Такая последовательность управляющих символов известна также, как протокол XON/XOFF. Пример: $ man chmod CHMOD(IV) USER COMMANDS CHMOD(IV) NAME chmod — change the permissions mode of a file AS ...приостанавливает вывод на терминал. ...возобновляет вывод.
SYNOPSIS chmod С -fR V mode filename ... ...the rest of the manual page is displayed here. SEE ALSO csh(l), Is(IV), sh(l), chmod (2V) , chown(8) $ _ Завершение ввода: <Ctrl>+<D> Многие утилиты UNIX получают входную информацию из файла или с клавиатуры. Если данные вводятся с клавиатуры, вам необходимо сообщить системе о завершении ввода. Для этого нажмите комбинацию клавиш <Ctrl>+<D> после того, как наберете последнюю строчку. Система воспринимает эту комбинацию как завершение ввода информации. Рассмотрим это на примере утилиты mail, позволяющей посылать почту конкретному пользователю: $ mail tim . . .посылка почты моему другу Тиму. Hi Tim, ...ввод информации с клавиатуры. I hope you get this piece of mail. How about building a country one of these days? - with best wishes from Graham ...говорит системе, что ввод окончен. $_ Более подробно утилита mail будет рассмотрена в конце этой главы. Установка пароля: passwd После того как вы зарегистрировались в системе, целесообразно будет сменить свой первоначальный пароль, т. к. по крайней мере, он известен человеку, который выдал вам его. Отнеситесь к выбору пароля серьезно. Он должен состоять не менее, чем из шести символов, и не являться правильным существительным или каким-либо другим словом из словаря. Это необходимо для того, чтобы злоумышленник, решивший воспользоваться вашим паролем, не смог получить его, установив специальную программу, которая попробует подобрать пароль, перебирая слова стандартного словаря. В качестве примера хорошего пароля можно привести: "GWK145W". Для изменения существующего пароля воспользуйтесь утилитой passwd.
Синтаксис passwd Утилита passwd позволяет изменять пароль. Для этого вам потребуется ввести старый пароль, после чего дважды ввести новый. Это необходимо потому, что вводимый пароль не отображается на экране, и проверить, не допустили ли вы опечатку, можно только подтверждением ввода и проверкой их на совпадение. После того как вы поменяли пароль, он в зашифрованном виде сохраняется в зависимости от версии UNIX в файле пароля /etc/passwd или в shadow-файле (для большей безопасности). В некоторых версиях UNIX пароль может сохраняться в базе данных на удаленном компьютере. Для большей наглядности в приведенном далее примере отображаются пароли, но обычно при работе с UNIX символы, которые вы вводите, на экране не отображаются. $ passwd Current password: penguin New password (? For help): GWK145W New password (again): GWK145W Password changed for glass $_ Если вы забыли пароль, единственное, что можно сделать, — связаться с системным администратором и попросить его выдать вам новый. Выход из системы Для выхода из системы воспользуйтесь комбинацией клавиш <Ctrl>+<D>. Подавляющее большинство систем после этого выводит приглашение login:, после чего к работе может приступить другой пользователь. Пример: $ ... я все сделал! UNIX(г) System V Release 4.0 login: ...ожидает другого пользователя для регистрации. Теперь вы знаете, как зарегистрироваться в системе, изменить пароль и выйти из системы. В следующих разделах мы рассмотрим утилиты, которые позволят вам перемещаться по каталогам и управлять файлами. 3 Зак. 786
Поэзия в движении: изучение файловой системы Вероятно, лучший способ познакомиться с общими утилитами UNIX — это рассмотреть их на примере. Представим себе поэта, которому необходимо написать заключительную версию стихотворения. В табл. 2.2 приведена последовательность действий, которую ему для этого необходимо совершить. Таблица 2.2. Пример последовательности действий для написания стихотворения Действие Утилита Определение текущего местонахождения pwd Сохранение наброска в файле heart cat Вывод содержимого каталога для определения размера файла Is Просмотр файла с использованием нескольких утилит cat, more, page, head, tail Переименование файла heart в файл heart.verl mv Создание каталога lyrics для сохранения в нем вариантов mkdir стихотворений Перемещение файла heart.verl в каталог lyrics mv Создание копии файла heart.verl с именем heart.ver2 ср Редактирование файла heart.ver2 vi Возвращение в домашний каталог cd Создание каталога lyrics.final mkdir Переименование каталога lyrics в lyrics.draft mv Копирование файла heart.ver5 из каталога lyrics.draft ср в каталог lyrics.final, переименование файла в heart, final Удаление файлов из каталога lyrics.draft rm Удаление каталога lyrics.draft rmdir Перемещение в каталог lyrics.final cd Распечатка файла heart.final 1рг Подсчет слов в файле heart.final wc Определение атрибутов файла heart.final Is Определение типа файла heart.final file
Таблица 2.2 (окончание) Действие Утилита Определение группы владельцев groups Изменение группы владельцев файла heart.final chgrp Изменение прав на файл heart.final chmod Определение текущего каталога: pwd Работа в UNIX начинается с определенного места в системе, называемого текущим рабочим каталогом. Когда происходит регистрация пользователя в системе UNIX, shell начинает работать в индивидуальном каталоге — домашнем каталоге. Вообще, каждый пользователь имеет свой домашний каталог, который обычно начинается с префикса /home. Например, каталог пользователя glass может располагаться в каталоге /home/glass. Системный администратор указывает местонахождение каждого пользователя. Для определения местонахождения пользователя применяется утилита pwd. Синтаксис pwd Печатает имя текущего рабочего каталога. Для иллюстрации утилиты рассмотрим, что произошло при регистрации в UNIX пользователя, который хочет начать работу над лирическими стихами: UNIX(г) System V Release 4.0 login: glass Password: ...секрет. $ pwd /home/glass $ _ На рис. 2.1 изображена схема нахождения пользователя glass во время регистрации в системе.
home glass Положение Korn shell во время входа в систему Рис. , 2.1. Запуск командного интерпретатора из домашнего каталога пользователя Абсолютные и относительные имена путей Перед тем как мы продолжим знакомство с системой каталогов, нам необходимо обратить внимание на уникальность названий файлов и каталогов. Два файла, расположенные в одном и том же каталоге, не могут называться одинаково. Однако никто не запрещает вам давать одни и те же имена файлам, находящимся в разных каталогах. На рис. 2.2 представлена иерархия каталога, содержащего процесс ksh и три файла с одинаковым именем my File. home myFile myFile , Г" glass myFile Рис. 2.2. Различные файлы с одинаковыми именами Несмотря на то, что файлы имеют одинаковые имена, они идентифицируются по месту расположения относительно каталога / — корня всей иерархии каталогов. Путь — последовательность имен каталогов, от стартового каталога до необходимого файла. Путь, определяемый относительно корневого каталога, часто называют абсолютным или полным. В табл. 2.3 представлено местоположение трех файлов с одинаковыми именами.
Таблица 2.3. Абсолютные пути Файл Абсолютное путевое имя А /home/glass/myFile В /home/myFile С /bin/myFile Не менее успешно можно определить файл, указывая его расположение относительно текущего рабочего каталога. При задании относительного пути в UNIX принято использовать символы, представленные в табл. 2.4. Табл. 2.5 иллюстрирует расположение файлов myFile относительно домашнего каталога пользователя glass. Внимание Указание пути myFile эквивалентно ./myFile, однако эта форма является избыточной и поэтому используется редко. Таблица 2.4. Условные обозначения текущего и родительского каталога Поле Описание Текущий каталог • • Родительский каталог Таблица 2.5. Относительные пути Файл Относительный путь А myFile В ../myFile С ../../bin/myFile Создание файла Для того чтобы создать файл в UNIX, как правило, пользуются специальными редакторами, например, vi или emacs, но в этой главе мы рассмотрим более простой, но не менее эффективный способ — утилиту cat.
Синтаксис cat -п {имяФайла} * Название утилиты — cat (от сокращения англ, concatenate — связывать) — переводится, как соединять в последовательность связей. Она читает входные данные из файла или стандартного входа и передает их на стандартный выход. Опция -п позволяет указать номера необходимых строк. По умолчанию стандартный вход процесса — это ввод данных с клавиатуры, стандартный выход — вывод данных на экран. Мы можем перенаправить стандартный выход в файл, используя переназначение вывода. Если после команды вы укажете символ > и имя файла, результат работы этой программы будет сохранен в файле с указанным именем. Если такого файла не существует, он создается, в противном случае, вся информация, содержащаяся в нем до этого, перезаписывается. В главе 4 мы рассмотрим этот вопрос более подробно. Ниже приведен пример работы утилиты cat: $ cat > heart , ...сохраняет ввод с клавиатуры в файл heart. I hear her breathing, I’m surrounded by the sound. Floating in this secret place, I never shall be found. ...говорит cat, что конец ввода был достигнут. $ Просмотр содержимого каталога: Is После создания файла вам, вероятно, захочется убедиться, что он действительно существует, и узнать его размер. Для получения этой информации служит утилита is. Синтаксис Is -adglsFR {имяФайла}* {имяКаталога}★ По умолчанию утилита is выводит в алфавитном порядке список всех файлов текущего каталога за исключением скрытых файлов, имена которых начинаются с точки. Опция -а включает в листинг скрытые файлы.
Для вывода содержимого каталогов необходимо указать их имена после параметров команды. Опция -d включает в листинг описание каталогов, а не их содержание. Опция -д вносит в список группу файла. Опция -1 выводит список файлов с такими параметрами, как время последней модификации, имя владельца файла и флаги доступа. Опция -s выводит размер файла. Опция f указывает тип файла: • * — исполняемый файл; • / — каталог; • @ — связанный файл; • = — сокет. Опция -r рекурсивно выводит содержимое каталога и его подкаталогов. Большинство описанных выше опций утилиты is вам пока не потребуются. Пример выполнения утилиты is: $ Is ...распечатывает все файлы в текущем каталоге, heart $ Is -1 heart ...большая распечатка файла heart. -rw-r—г— 1 glass 106 Jan 30 19:46 heart $_ Немного позже мы рассмотрим значение каждого поля, выводимого утилитой is, а пока в табл. 2.6 представлен их краткий обзор. Таблица 2.6. Описание вывода утилиты 1s Номер поля Символы Значение 1 -rw -г —г-- Тип и режим полномочий файла, которые указывают, кто может читать, писать и выполнять файл 2 1 Счетчик жестких связей (обсуждаемый намного позже в этой книге) 3 glass Имя пользователя — владельца файла 4 106 Размер файла в байтах 5 Jan 30 19:46 Время последней модификации файла 6 heart Имя файла $ Is -algFs total 3 ...полный листинг текущего каталога. ...общее число блоков памяти.
1 drwxr-xr-x 3 glass cs 512 Jan 30 22:52 , / 1 drwxr-xr-x 12 root cs 1024 Jan 30 19:45 • . / 1 —rw-r—r— 1 glass cs 106 Jan 30 19:46 heart $ Опция -s выводит размер каждого файла. Если размер блока диска равен 1024 байта, то файл размером в 106 байт займет его целиком. Это следствие физического устройства файловой системы, которое мы рассмотрим в главе 14. Опция -а выводит полный листинг каталога, включая скрытые файлы, имена которых начинаются с точки. Например, "." и — скрытые файлы, которые представляют собой текущий и родительский каталоги соответственно. Опция -F добавляет в конец символ / ко всем именам, которые являются каталогами, а опция -д выводит группу, владеющую файлом. Распечатка файла: cat/тоге/раде/head/tail Чтобы просмотреть содержимое файла, можно воспользоваться утилитой cat. Для этого после команды необходимо указать имя файла: $ cat heart ...выводит содержимое файла heart. I hear her breathing, I’m surrounded by the sound. Floating in this secret place, I never shall be found. $ _ Утилита cat принимает в качестве аргументов любое количество файлов, имена которых указываются друг за другом. Она отлично подходит для вывода небольших файлов. Для вывода информации большого объема следует пользоваться утилитами more и раде, которые позволяют приостановить вывод и прокручивать файл. Ниже представлено описание этих утилит. Синтаксис more -f [+номерС троки] {имяФайла}* Утилита more организует постраничный вывод на экран. Вывод начинается с первой строки каждого файла, но с помощью опции + можно указать стартовую строку. Опция -f предписывает не переносить длинные строки. После заполнения страницы появляется сообщение "—More—". Для распечатки следующей страницы вам нужно всего лишь нажать клавишу <Пробел>. Для
выхода используйте клавишу <q>. Для получения более подробной информации нажмите клавишу <h>. Синтаксис page -f [ +номерСтроки] {имяФайла}* Утилита раде работает подобно утилите more, за исключением того, что первая очищает экран перед выводом каждой страницы. В некоторых случаях это помогает ускорить вывод. Следует упомянуть еще о двух полезных утилитах: head и tail, с помощью которых можно просмотреть начало и конец файла соответственно. Синтаксис head -п {имяФайла}* Утилита head показывает первые п строк файла. Если п не определено, по умолчанию выводятся 10 строк. Если необходимо вывести начальные строки нескольких файлов, перед каждым из них будет указано его имя. Синтаксис tail -п {имяФайла}* Утилита tail показывает последние п строк файла. Если п не определено, по умолчанию выводятся последние 10 строк. Выводу содержимого нескольких файлов предшествуют их имена. Пример: S head -2 heart ...вывод первых двух строк I hear her breathing I’m surrounded by the sound. $ tail -2 heart ...вывод последних двух строк Floating in this secret place I never shall be found.
Переименование файла: mv Очень часто в процессе работы возникает необходимость переименовать файл. Для этого используется утилита mv. Синтаксис mv -i староеИмяФайла новоеИмяФайла mv -i {имяФайла}* имяКаталога mv -i староеИмяКаталога новоеИмяКаталога Утилита mv перемещает или переименовывает файлы и каталоги. Для того чтобы переименовать файл или каталог, необходимо указать в качестве параметров старое и новое имя файла/каталога. Для перемещения файлов в каталог потребуется указать имена файлов и каталога после команды. Вследствие того, что физического перемещения не происходит, а меняются только метки, утилита mv работает очень быстро. Опция -i выводит предупреждение, что файл с указанным именем уже существует. Пример: $ mv heart heart.ver1 ...переименование в heart.verl $ Is heart.verl $ _ Пример перемещения каталогов и файлов в каталоги будет приведен чуть позже. Создание каталога: mkdir Для создания каталогов пользуются утилитой mkdir. Синтаксис mkdir [~р] новоеИмяКаталога Утилита mkdir создает каталог. Опция -р создает любые родительские каталоги в каталоге новоеИмяКаталога, который еще не существует. Если новоеИмяКаталога уже существует, выводится сообщение об ошибке, и существующий файл никаким образом не изменяется.
Пример: $ mkdir lyrics ...создает каталог lyrics. $ Is -IF ...подтвердить. -rw-r—г— 1 glass 106 Jan 30 23:28 heart.verl drwxr-xr-x 2 glass 512 Jan 30 19:49 lyrics/ $ _ Символ d в начале поля полномочий говорит о том, что это каталог. Для облегчения поиска необходимо, чтобы имя каталога отвечало его содержанию. Чтобы убедиться, удалось ли переместить файл в нужное место, также воспользуемся утилитой is: $ mv heart.verl lyrics ...переместить в lyrics. $ Is ...вывод текущего каталога, lyrics/ ...heart.verl ушел. $ Is lyrics ...вывод каталога lyrics, heart.verl ...heart.verl перемещен. $ Перемещение по каталогам: cd Можно оставаться в своем рабочем каталоге, создавая по мере необходимости подкаталоги внутри него. Но это неудобно, по крайней мере, по нескольким причинам: во-первых, это затруднит поиск, а во-вторых, придется указывать очень длинные пути, содержащие имена всех каталогов, предшествующих каталогу, в котором находится необходимый файл. Чтобы сделать работу более удобной, лучше заранее переместиться в каталог, с содержимым которого вы собираетесь работать. Например, если вы собираетесь редактировать файл heart.verl, то целесообразно переместиться из своего стартового каталога в каталог lyrics, в котором этот файл находится. $ vi lyrics/heart.verl ...запуск'редактора vi. Для перемещения по каталогам служит команда cd, которая фактически представляет собой встроенную команду shell. Внимание Название всех команд shell дается светлым моноширинным шрифтом, согласно системе обозначений, описанных во Введении.
Синтаксис cd [имяКаталога] Команда cd (от англ, change directory — изменить каталог) изменяет текущий рабочий каталог на указанный в имяКаталога. Если аргумент имяКаталога опущен, shell перемещается в домашний каталог его владельца Проверить, произошло ли перемещение в необходимый каталог можно, используя утилиту pwd: $ pwd ...определение текущего каталога. /home/glass $ cd lyrics ...переместить в .каталог lyrics. $ pwd ...вывести, где я теперь. /home/glass/lyrics На рис. 2.3 проиллюстрировано перемещение shell, инициированное командой cd: home lyrics glass shell перемещается в каталог /home/glass/lyrics Рис. 2.3. Перемещение shell Возможно перемещение на уровень выше или в рабочий каталог с помощью указания ".и соответственно. Пример: /home/glass/lyrics $ cd . . ...переместиться вверх на один уровень. $ pwd /home/glass $ ...вывести новое текущее положение.
Копирование файла: ср Часто возникает необходимость скопировать файл, например, для того, чтобы отредактировать его, не испортив оригинал. Чуть ниже описана утилита ср, предназначенная для копирования файлов. Синтаксис ср -i староеИмяФайла новоеИмяФайла ср -ir {имяФайла}* имяКаталога Утилита ср копирует файлы, при этом необходимо указать староеИмяФайла и новоеИмяФайла. Если файл с таким именем уже существует, его содержимое перезаписывается. Опция -i выводит предупреждение о том, что файл с таким именем уже существует. Опция -г рекурсивно копирует файлы и дочерние каталоги в указанный каталог. Утилита ср создает физическую копию содержимого каталога и новую метку, указывающую на скопированные файлы. Поэтому любая работа с копией документа никак не затронет оригинал. Ниже приведен пример работы этой утилиты: $ ср heart.verl heart.ver2 ...копировать в файл heart.ver2. $ Is -1 heart.verl heart.ver2 ...подтверждение. -rw-r—r— 1 glass -rw-r—r— 1 glass 106 Jan 30 23:28 heart.verl 106 Jan 31 00:12 heart.ver2 $ Редактирование файла: vi В этой главе мы познакомимся с двумя программами обработки текстов: редакторами vi и emacs. Представим себе, что нам необходимо отредактировать файл в vi. Ниже показано, какие действия необходимо совершить для этого: $ vi heart.ver2 ...редактировать файл. ...сессия редактирования приводится здесь. $ cat heart.ver2 ...вывести файл. I hear her breathing, I’m surrounded by the sound. Floating in this secret place,
I never shall be found. She pushed me into the daylight, I had to leave my home. But I am a survivor, And I’ll make it on my own. $ После создания пяти версий лирических стихов песни моя работа была завершена. Я вернулся к своему домашнему каталогу и создал подкаталог lyrics.final, чтобы хранить заключительную версию лирических стихов. Я также переименовал первоначальный каталог lyrics в lyrics.draft. Команды, реализующие описанный алгоритм, таковы: $ cd $ mkdir lyrics.final $ mv lyrics lyrics.draft ...вернуться в свой домашний каталог. ...создать финальный каталог lyrics. ...переименовать старый каталог lyrics. $ Заключительная версия лирических стихов была сохранена в файле heart.ver5 каталога lyrics.draft, который я затем скопировал в файл heart.final в каталоге lyrics.final: $ ср lyrics.draft/heart.ver5 lyrics.final/heart.final $ Удаление каталога: rmdir Сохранение информации для потомков — цель весьма и весьма достойная, однако не реализуемая в условиях ограниченного дискового пространства. Поэтому время от времени необходимо удалять ненужные файлы и каталоги. Однако перед тем как подписать смертный приговор какому-либо файлу, подумайте, не потребуется ли он (т. е. файл) вам в будущем. Если возникают сомнения по этому поводу, то перед удалением лучше заархивировать файл при помощи утилиты cpio, о которой мы подробнее поговорим в главе 3. Теперь, когда информация сохранена, можно удалить каталог, пользуясь утилитой rmdir. Синтаксис rmdir {имяКаталога}+ Утилита rmdir удаляет указанный каталог и все его подкаталоги. Удалить можно только пустые каталоги. Для того чтобы рекурсивно удалить ката
логи и подкаталоги вместе со всем их содержимым, следует воспользоваться утилитой rm с опцией -г. При попытке удалить каталог, содержащий файлы, система выдаст сообщение об ошибке: $ rmdi г lyri cs. dr a f t nadir: lyrics.draft: $ Directory not empty1 Удаление файла: rm Утилита rm удаляет метки, ссылающиеся на файл. Как правило, этого достаточно, чтобы удалить и сам файл. Однако, если файл имеет более чем одну метку — такие случаи мы рассмотрим в главе 3 — данная утилита удаляет лишь ссылку на файл. Синтаксис rm -fir {имяФайла} * Утилита rm удаляет ссылку на файл из иерархии каталогов. Если файла не существует, выводится сообщение об ошибке. Опция -i выводит предупреждение перед удалением файла; требуется нажать клавишу <у> для подтверждения операции или клавишу <п> для отмены. Использование этой утилиты с опцией -г для удаления каталога вызывает удаление всего его содержимого, включая подкаталоги. Опция -f подавляет вывод сообщений об ошибках и предупреждений. Удаление файлов из каталога: $ cd lyrics.draft ...переместиться в каталог lyrics.draft. $ rm heart.verl heart.ver2 heart.ver3 heart.verA heart.ver5 $ Is ... ничего не осталось. $ _ Удаление пустого каталога: $ cd ... возвращаемся в домашний каталог. $ rmdir lyrics.draft ...каталог пуст, и теперь мы можем его удалить. $ 1 Каталог не пуст. — Пер.
В главе 4 мы обсудим более простой способ удаления файлов: $ cd lyrics.draft ...переместиться в каталог lyrics.draft. $ rm * ...удалить все файлы из текущего каталога. $ Можно воспользоваться лучшим способом: указать более "продвинутую" опцию -г утилиты rm, чтобы удалить каталог lyrics.draft и все его содержимое одной командой: $ cd $ rm -г lyrics.draft $ ...переместиться в домашний каталог. ...рекурсивно удалить каталог. Печать файла: 1р/Ipstat/cancel Мы выяснили, как создавать, редактировать и удалять файлы. Теперь было бы неплохо научиться их распечатывать. Для вывода документа на печать используется утилита 1р. Синтаксис ip [-d пунктНазначения] [-п копий] {имяФайла}* Утилита 1р отправляет выбранные файлы на принтер, который необходимо указать с помощью опции -d. Если не заданы имена файлов, на печать выводятся данные, поступающие со стандартного входа. По умолчанию печатается одна копия. Однако количество необходимых экземпляров можно изменить, пользуясь опцией -п. Говоря о печати файлов, нельзя обойти вниманием еще одну полезную утилиту — ipstat — отображающую состояние печати и загрузку принтера. Синтаксис Ipstat [пунктНазначения] Утилита ipstat выводит информацию о статусе принтера, объеме выполненной работы, пользователе, отправившем задание на печать с помощью команды 1р. Если принтер определен, ipstat сообщает информацию об очереди только для этого принтера.
Если по каким-либо причинам вам нужно отменить печать документа, вы можете сделать это, воспользовавшись утилитой cancel. Синтаксис cancel {ID—запроса} + Утилита cancel удаляет все указанные задания из очереди принтера. В качестве параметра команды необходимо указать ID задания, который можно узнать, воспользовавшись утилитой ipstat. Привилегированный пользователь (root) может отменить печать любого документа. Представим, что нам поручили распечатать два экземпляра файла heart.final на принтере Iwcs. После отправки задания на печать оказалось, что вполне достаточно будет одного экземпляра. Ниже приведена последовательность действий, которые необходимо совершить, чтобы реализовать задуманное: $ Ip -d Iwcs heart.final ...отправили на печать, request id is lwcs-37 (1 file) $ Ipstat Iwcs ...узнали статус принтера, printer queue for Iwcs lwcs-36 ables priority 0 Mar 18 17:02 on Iwcs inventory.txt 457 bytes lwcs-37 glass priority 0 Mar 18 17:04 on Iwcs heart.final 213 bytes $ Ip -n 2 -d Iwcs heart.final ...заказали еще две копии, request id is lwcs-38 (1 file) $ Ipstat Iwcs ...еще раз посмотрели статус принтера. printer queue for Iwcs lwcs-37 glass priority 0 Mar 18 17:04 on Iwcs heart.final 213 bytes lwcs-38 glass priority 0 Mar 18 17:05 on Iwcs heart.final 2 copies 213 bytes $ cancel lwcs-38 ...удалили последнее задание. request "lwcs-38" cancelled $ В приведенном ниже примере проиллюстрирован вывод на печать данных, введенных с клавиатуры: $ Ip -d Iwcs ...печать со стандартного входа. Hi there,
This is a test of the print facility. - Graham ... конец ввода. request id is lwcs-42 (standard input) $ Печать файла: Ipr/lpq/lprm Утилиты печати, с которыми мы уже познакомились, уходят корнями к System V и поддерживаются практически во всех версиях UNIX. Однако в некоторых версиях и Linux используются другие команды, берущие свое начало в BSD UNIX. Эти команды выполняют те же самые функции, но имеют другие названия и аргументы. Так, например, для печати файла применяется утилита ipr. Для определения статуса принтера и мониторинга выполнения задания служит утилита ipq. Остановимся на них более подробно. Синтаксис 1рг -ш [-Рпринтер] [-#копий] {имяФайла} * Утилита ipr выводит на печать указанные файлы, принтер задается опцией -р. Если принтер не определен, используется значение переменной окружения $ printer (об этих переменных мы поговорим в главе 4). Если не указано имя файла, печатаются данные со стандартного входа. По умолчанию печатается одна копия каждого файла, хотя необходимое количество экземпляров задается опцией -#. С помощью опции -т можно настроить отправление уведомления о завершении печати. Синтаксис Ipq -1 [-Рпринтер] {номерЗа Дания}* {Ю_пользователя}* Утилита ipq показывает информацию о текущих заданиях и пользователях, отправивших их на печать. Если не определено конкретное задание, будут показаны все задания на указанном с помощью опции -р принтере. В противном случае выводятся данные работы принтера, прописанного в переменной окружения $ printer. Опция -1 позволяет получить более подробную информацию.
Отменить печать можно с помощью утилиты iprm. Синтаксис Iprm [-Рпринтер] [-] [номерЗа дания] * {Ю_пользователя} * Утилита iprm отменяет задания на принтере, указанном опцией -р, либо (если принтер не определен) прописанном в переменной окружения $ printer. Опция - отменяет все назначенные вами задания. Привилегированный пользователь root может прекратить печать заданий конкретного пользователя, идентифицируя его по ю_пользователя. Пример: $ Ipr -Plwcs heart.final ...вывод на печать. $ Ipq -Plwcs glass ...просмотр статуса принтера. Iwcs is ready and printing Rank Owner Job Files Total Size active glass 731 heart.final 213 bytes $ Ipr -#2 -Plwcs heart. final ...еще две 2 копии. $ Ipq -Iwcs is Plwcs glass ready and printing ...статус принтера снова. Rank Owner Job Files Total Size active glass 731 heart.final 213 bytes active glass 732 heart.final 426 bytes $ Iprm -Plwcs 732 ...удаление последнего задания. centaur: dfA732vanguard dequeued centaur: cfA732vanguard.utdallas.edu dequeued $ _ Пример вывода на печать данных, введенных непосредственно с клавиатуры. $ Ipr -m -Plwcs ...печать со стандартного входа. Hi there, This is a test of the print facility. - Graham ...конец ввода. $ . подождал немного. $ mail ...читать почту.
Mail version SMI 4.0 Sat Oct 13 20:32:29 PDT 1990 Type ? for help. >N 1 daemon@utdallas.edu Fri Jan 31 16:59 15/502 printer job & 1 ...читать первое почтовое сообщение. From: daemon@utdallas.edu То: glass@utdallas.edu Subject: printer job Date: Wed, 18 Mar 1998 18:04:32 -0600 Your printer job (stdin) Completed successfully & q ...завершил почтовый сеанс. $ Подсчет слов в файле: wc Иногда бывает весьма полезно узнать, сколько слов содержит тот или иной файл. Сделать это гораздо проще, чем можно предположить: достаточно воспользоваться утилитой wc. Синтаксис wc -Iwc {имяФайла}* Утилита wc считает строки, слова или символы в одном или нескольких файлах, либо в данных, введенных с клавиатуры Опция -1 осуществляет подсчет строк, опция -w — слов, опция -с — символов. Если никакие опции не определены, то выполняются все три подсчета. Слово определено как последовательность символов, окруженная символами табуляции, пробелами или новыми строками. Рассмотрим пример: $ wc heart.final ...выполнить подсчет слов. 9 43 213 heart.final Атрибуты файла Теперь, когда рассмотрены основные утилиты работы с файлом, пришло время обратить внимание на его атрибуты.
Для получения подробной информации о файле используется рассмотренная уже утилита is: $ Is -IgsF heart. final 1 -rw-r—r— 1 glass cs 213 Jan 31 00:12 heart.final $ _ В табл. 2.7 расшифровано значение каждого поля. Таблица 2.7. Атрибуты файла Номер поля Символы Описание 1 1 Число блоков физической памяти, занятой файлом ' 2 -rw-r—г— Тип и режим полномочий файла, который указывает, кто может читать, записывать и выполнять файл 3 1 Счетчик жестких связей (обсуждаемый в главе 3) 4 glass Имя владельца файла 5 cs Группа, владеющая файлом 6 213 Размер файла в байтах 7 Jan 31 00:12 Время последней модификации 8 heart.final Имя файла В следующих разделах мы поподробнее остановимся на значениях каждого поля. Размер файла Первое поле атрибутов файла указывает количество занимаемых файлом блоков. Фрагментированные файлы, имеющие большой объем в байтах, могут занимать совсем немного физической памяти. Фрагментированные файлы обсуждаются подробно в главе 13. Имя файла Имя файла отображается в восьмом поле. Имена файлов в UNIX могут содержать до 255 символов. При этом можно использовать любые печатные символы, кроме косой черты (/). Однако не рекомендуется также использовать знаки, являющиеся специальными для shell, например, <,>,*, ?, табуляции, т. к. они могут неправильно трактоваться как пользователем, так и системой. Нельзя также называть файлы и поскольку эти имена
зарезервированы для обозначения родительского и текущего каталогов. В отличие от некоторых операционных систем, не требуется, чтобы файл заканчивался расширением типа .с и .h, хотя многие утилиты UNIX (например, С-компилятор) работают с файлами, которые заканчиваются определенным суффиксом. Поэтому, heart и heart.fmal вполне допустимые имена. Время модификации Седьмое поле показывает время последней модификации файла. Например, утилита make, описанная в главе 12, использует время последней модификации файлов, чтобы управлять средством контроля зависимости. Утилита find, представленная в главе 3, использует это поле для поиска наиболее поздних версий файлов. Владелец файла Четвертое поле сообщает нам имя владельца файла. Каждый процесс UNIX имеет владельца, имя которого совпадает с именем пользователя, его запустившего. Например, мой shell запущен от имени пользователя glass, поэтому каждый создаваемый файл принадлежит данному пользователю, владельцу shell. В главе 13 мы более подробно рассмотрим процессы и их владельцев. Имя пользователя ассоциируется с тем или иным набором символов, хотя сама система использует для идентификации число, называемое пользовательским ID. Однако человеку проще запомнить какое-либо имя, нежели число, поэтому, когда мы будем говорить об имени пользователя, то станем иметь в виду какую-либо буквенную комбинацию и применять термин "пользовательский ID" для указания числового значения. Группа владельцев файла Пятое поле информирует нас о группе, владеющей файлом. Каждый пользователь UNIX является членом какой-либо группы. Принадлежность к группе назначается системным администратором и является инструментом, позволяющим повысить безопасность системы. Каждый процесс UNIX также принадлежит определенной группе, обычно эквивалентной группе пользователя, запустившего процесс. Если пользователь входит в группу cs, то все создаваемые им файлы также принадлежат этой группе. В главе 13 этот вопрос будет рассмотрен подробнее. Использование групп относится к механизму безопасности UNIX, которому посвящены следующие разделы. Как и в ситуации с именем пользователя, имя группы задается набором буквенных символов. Однако системой используется числовой идентификатор — ID группы.
Типы файла Во втором поле указывается тип файла и полномочия. Для удобства еще раз приведем еже знакомую нам строчку листинга: 1 -rw-r—г— 1 glass cs 213 Jan 31 00:12 heart.final Первый символ второго поля указывает на тип файла. В табл. 2.8 даны описание и обозначение различных типов. Мы с вами познакомились только с обычными файлами. В главе 3 будут рассмотрены файлы с символическими связями, в главе 13 — каналы и сокеты, а в главе 14 — буферированные и небуферированные файлы. Таблица 2.8. Типы файла Символ Тип файла Обычный файл d Каталог Ь Буферированный специальный файл (например, драйвер диска) с Небуферированный специальный файл (например, терминал) 1 Символическая связь р Канал s Сокет Тип файла определяется утилитой file, которую мы сейчас и рассмотрим. Чаще всего эта утилита будет выдавать такой результат: $ file heart.final ...определить тип файла. heart.final: ascii text $ Синтаксис file {имяФайла} + Утилита file определяет тип файла по его содержимому2. При использовании для файла символической связи утилита выдает характеристики того файла, на который эта связь указывает. 2 Эта программа весьма полезна, однако ее использование не гарантирует 100% верного результата.
Параметры полномочий файла Следующие 9 символов второго поля указывают назначения параметров полномочии файла. В текущем примере назначения параметров полномочий — это rw-r--г--: 1 -rw-r—г— 1 glass cs 213 Jan 31 00:12 heart.final Итак, мы разобрались со значением первого символа, теперь пришло время рассмотреть следующие девять, представляющие собой три группы по три символа (табл. 2.9 и 2.10). Прочерк на месте какого-либо символа говорит о юм, что этот вид работы с файлом запрещен. Разрешение на чтение, запись и выполнение файла очень часто зависят от типа файла (табл. 2.11). Таблица 2.9. Гоуппы параметров полномочий файла Группа параметров Описание rw- Пользователь (владелец) г-- Группа г-- Другие Таблица 2.10. Значения параметров полномочий файла Значение Описание г Разрешение на чтение W Разрешение на запись X Разрешение на выполнение Таблица 2.11. Описание значений полномочий для файлов различных типов Операция Обычный файл Каталог Специальный файл Чтение Процесс может читать содержимое Процесс может читать каталог (выводить имена входящих в него файлов) Процесс может читать из файла, используя системный вызов read() Запись Процесс может изменять содержимое Процесс может добавлять и удалять файлы из каталога Процесс может писать в файл, используя системный вызов write() Выполнение Процесс может выполнять файл (при условии что файл — программа) Процессу разрешен доступ к файлам каталога и его подкаталогов —
Запущенный процесс обладает следующими характеристиками: □ реальный пользовательский ID; П эффективный пользовательский ID; □ реальный ID группы; □ эффективный ID группы. Эти значения определяются во время регистрации в системе и являются характеристиками любого запушенного вами процесса. Параметры полномочий применяются следующим образом: П если эффективный пользовательский ID процесса такой же, как у владельца файла, применяются пользовательские параметры полномочий; а если эффективный пользовательский ID процесса отличается от ID владельца файла, но его эффективный ID группы равен ID группы, владеющей файлом, то применяются групповые параметры полномочий; □ если ни эффективный пользовательский ID процесса, ни эффективный ID группы не совпадают, применяются другие параметры полномочий. Следовательно, система полномочий является средством, с одной стороны, позволяющим повысить безопасность, защитив ваши файлы от несанкционированного доступа, а с другой — разрешает работать с ними пользователям, принадлежащим к определенной группе. Мы рассмотрим оптимальные для работы и безопасности установки доступа к файлам и научимся пользоваться утилитами, их изменяющими. Обратите внимание, что разрешение на доступ к файлу устанавливается на основе эффективного пользовательского и группового ID; его реальный пользовательский и групповой ID используются только для учетных целей. Кроме того, права на доступ к файлу обычно зависят от имени инициатора процесса, а не от владельца исполняемого файла. Тем не менее, иногда эта особенность мешает. Например, существует игра rogue, которая поставляется с некоторыми системами UNIX, записывает в отдельный файл лучшие результаты предыдущих игроков. Очевидно, во время выполнения rogue-процесс должен иметь право изменить этот файл, но игрок, от имени которого тот запущен, таких возможностей иметь не должен. Это кажется невозможным на основе той системы полномочий, которая была описана выше. Для того чтобы обойти эту проблему, разработчики UNIX добавили еще две характеристики файла: когда выполняется файл с полномочием "присваиваемый пользовательский ID", эффективный пользовательский и групповой ID устанавливаются равными ID исполняемого файла. Реальный пользовательский или групповой ID не затрагиваются. В нашем примере исполняемый файл и файл результатов принадлежат пользователю rogue, а т. к. в файл результатов может записывать результаты только его владелец (в данном случае rogue), то он (т. е. файл) защищен от изменений обычными пользователями. Так что, когда игрок запускает игру,
она выполняется с эффективным пользовательским ID rogue и таким образом способна изменить файл результатов. Полномочия ’’присваиваемый пользовательский ID” и "присваиваемый групповой ID" обозначаются как s вместо х в пользовательском и групповом наборе полномочий. Они могут быть установлены с использованием утилиты chmod и системного вызова chmod (), описанного в главе 13. Вот еще несколько примечаний, касающихся параметров полномочий файла: П когда процесс создает файл, полномочия по умолчанию, данные этому файлу, заменяются специальным значением, называемым umask. Об этом значении мы поговорим позже, в главе 4; □ привилегированный пользователь автоматически имеет все права доступа независимо от того, предоставлены они или нет; П владелец файла может иметь меньшие права доступа, чем группа или кто-то еще. Счетчик жесткой связи Третье поле указывает на счетчик жесткой связи файла, т. е. сколько ссылок на один физический файл существует в иерархии. Жесткие связи являются отдельной темой и обсуждаются в главе 3 вместе с утилитой in. Г руппы Теперь, когда мы описали параметры полномочий файла, пришло время выяснить, как они работают. Рассмотрим уже известный нам пример, в котором имя пользователя установлено равным glass, а группа равной cs: $ Is -lg heart.final -rw-r—r— 1 glass cs 213 Jan 31 00:12 heart.final $ _ По умолчанию установки доступа разрешают любому пользователю читать файл, однако правами на запись в него обладает только его владелец. Представим себе, что нам необходимо запретить доступ к файлу всех пользователей, кроме входящих в группу music, которым бы разрешалось чтение файла, и его владельца, у которого были бы права на чтение и запись в него. Если такой группы не существует, то единственный способ ее создать — попросить об этом системного администратора. Сам же процесс создания будет рассмотрен в главе 15.
Вывод групп: groups Утилита groups позволяет вывести названия всех групп, членом которых вы являетесь. Синтаксис groups [ID—Пользова теля] По умолчанию утилита groups показывает список всех групп, членом которых вы являетесь. Если имя пользователя определено, выводится список групп, в которые он входит. Пример: $ groups cs music $ . . .вывести мои группы. Изменение группы: chgrp Первый шаг к защите моих лирических стихов должен был состоять в изменении имени группы heart.final с cs на music. Сделано это с помощью утилиты chgrp: $ Is -lg heart.final -rw-r—r— 1 glass cs $ chgrp music heart.final $ Is -lg heart.final 213 Jan 31 00:12 heart.final ...изменить группу. ...подтвердить, что изменилось. -rw-r—г— 1 glass music 213 Jan 31 00:12 heart.final $ Синтаксис chgrp -R имяГруппы {имяФайла}* Утилита chgrp предоставляет возможность пользователю изменять групповую принадлежность файлов, которыми он владеет. Привилегированный пользователь (root) может изменять групповую принадлежность любого файла. За аргументом имяГруппы следуют имена файлов, групповую
принадлежность которых необходимо изменить. Опция -R рекурсивно изменяет групповую принадлежность файлов в каталоге. Вы можете также использовать утилиту chgrp для изменения группы каталога. Изменения прав доступа файла: chmod Теперь, когда групповая принадлежность файла была изменена, нам может потребоваться изменить уровень доступа. Для этого используется утилита chmod: $ Is -lg heart.final -rw-r—r— 1 glass $ chmod o-r heart.final $ Is -lg heart.final -rw-r----- 1 glass $ ...прежде. music 213 Jan 31 00:12 heart.final ...запрещение чтения для других. ...после. music 213 Jan 31 00:12 heart.final Синтаксис chmod -R замена {, замена} * {имяФайла} + Утилита chmod изменяет атрибуты указанных файлов согласно параметрам замена, которые могут принимать любую из форм: • ВыборГруппы + новыеПрава (добавить права)’ • ВыборГруппы - новыеПрава (убрать права); • ВыборГруппы = новыеПрава (назначить права абсолютно). Здесь ВыборГруппы — это любая комбинация: • и (пользователь/владелец); • g (группа); • о (другие); • а (все). новыеПрава — это любая комбинация: • г (читать); • w (писать); • х (выполнять);
• s (присваиваемый пользовательский ID или присваиваемый групповой ID). Опция -R рекурсивно изменяет атрибуты файлов в каталогах. (Для примера см. фрагмент кода, который следует далее.) Изменение прав доступа каталога не меняет права доступа файлов, содержащихся в каталоге. В табл. 2.12 представлены дополнительные параметры утилиты chmod. Таблица 2.12. Параметры утилиты chmod Требование Параметры изменения Добавить группе право записи g+w Удалить право чтения и записи для пользователя u-rw Добавить право выполнения для пользователя, группы и других а+х Предоставить группе только право чтения g=r Добавить право записи для пользователя и удалить право чтения u+w, g-r для группы Желательно защитить свой домашний каталог от несанкционированного доступа, запретив всем пользователям записывать в него, оставив лишь права чтения и, возможно, выполнения: $ cd $ Is -Id . drwxr-xr-x 45 $ chmod o-rx $ Is -Id drwxr-x--- 45 $ ...перейти в домашний каталог. ...вывести атрибуты домашнего каталога, glass 4096 Apr 29 14:35 ...изменить права доступа. ...получить подтверждение. glass 4096 Apr 29 14:35 Обратите внимание, что для просмотра атрибутов каталога, а не содержащихся в нем файлов, была использована опция -d утилиты 1s. Вы можете определять права доступа, используя восьмеричное число — триплет значений, разрешающих запуск, чтение и изменение файлов. Например, необходимо, чтобы файл имел следующие разрешения: rwxr-x-- Восьмеричный эквивалент этой записи выражается числом 750. В табл. 2.13 представлены различные форматы записи прав доступа.
Ниже приведен пример задания флагов доступа с использованием восьмеричных значений: $ chmod 750 ...обновить права. $ Is -Id ...подтвердить. drwxr-x--- 45 glass 4096 Apr 29 14:35 $ Таблица 2.13. Восьмеричный эквивалент прав доступа Пользователь Группа Другие Установка rwx r-x — Двоичная 111 101 ООО Восьмеричная 7 5 0 Изменение владельца файла: chown Если, по каким-либо причинам, вы захотите передать права собственности на файл, вы сможете это сделать, используя утилиту chown. Некоторые версии UNIX позволяют только привилегированному пользователю (root) изменять права собственности файла, особенно в случае квотирования дискового пространства, доступного каждому пользователю, другие — передавать права может и владелец файла. Случаи, когда системному администратору приходится изменять права собственности на файлы и каталоги, рассмотрены в главе 15. Синтаксис chown -R новыиПользовательскийЮ {имяФайла} + Утилита chown позволяет привилегированному пользователю изменять права собственности на файлы. Смена принадлежности производится для всех файлов, следующих за аргументом новыйпользовательскийю. Опция -R рекурсивно изменяет владельца файлов в каталогах и подкаталогах. Пример передачи прав собственности на файл от владельца glass пользователю tim и возращение их glass: $ Is -lg heart.final ...определить владельца. -rw-r---- 1 glass music 213 Jan 31 00:12 heart.final
$ chown tim heart, final ... изменить - владельца на tim. $ Is -lg heart.final ...проверить владельца. -rw-r---- 1 tim music 213 Jan 31 00:12 heart, final $ chown glass heart.final ...изменить владельца на glass. $ Изменение групп: newgrp Если вы член нескольких групп, то какой из них будет принадлежать создаваемый вами файл? Ответ на вопрос прост — вы можете быть членом нескольких групп, но текущая эффективная группа у вас одна, и процесс, создающий файл, использует эффективный ID именно этой группы. Это означает, что после создания файла из shell групповой ID файла устанавливается на эффективный групповой ID вашего shell. В рассматриваемых примерах членство принадлежит группам cs и music, а эффективное имя группы рабочего shell — cs. Системный администратор выбирает, какая группа является для вас основной. Поэтому при необходимости изменить текущую группу можно воспользоваться УТИЛИТОЙ newgrep. Синтаксис newgrp [-] [имяГруппы\ Утилита newgrp изменят текущую группу пользователя. Если вы указываете символ - вместо имени группы, то ваша группа остается той же, что и при регистрации в системе. В представленном ниже примере созданы файл test 1 с группой владельцев cs и файл test2, которым владеет music: $ date > testl ...создать из shell группу cs. $ newgrp music ...создать группу music. $ date > test2 ...создать из shell группу music. ...прекратить работу нового shell. $ Is -lg testl test2 ...посмотреть атрибуты каждого файла. -rw-r—г— 1 glass cs 29 Jan 31 22:57 testl -rw-r—r— 1 glass music 29 Jan 31 22:57 test2
Поэзия в движении: эпилог Мы познакомились с основными утилитами UNIX, и, желательно, перед дальнейшим чтением попробовать проделать действия, описанные в примерах. Оставшаяся часть главы посвящена настройке терминала и двум наиболее популярным редакторам UNIX. Определение типа вашего терминала: tset Отдельные утилиты UNIX, включая два стандартных редактора vi и emacs, должны ’’знать", какой терминал вы используете, чтобы правильно управлять выводом. Тип вашего терминала сохраняется в глобальной переменной, называемой переменной окружения (см. главу 4). По умолчанию эта переменная чаще всего равна vtioo или vt52. Есть несколько способов задать необходимый тип. П Тип term может устанавливаться непосредственно, через строку вида setenv, TERM vtlOO (ДЛЯ С shell) ИЛИ TERM=vti00; export term (для Bourne, Korn и Bash) вашего терминала. Этот метод установки эффективен, если вы знаете его тип заранее и всегда регистрируетесь с одного и того же терминала. □ Стартовый файл запуска shell может вызвать утилиту tset, определяющую порт коммуникаций, с которым вы связаны, и затем производящую поиск соответствия порт/терминал в специальном файле /etc/ttytab. Если утилита tset не может найти тип терминала, она запрашивает информацию о нем при регистрации в системе. П Вы можете вручную установить term из shell. Далее мы познакомимся с двумя утилитами, позволяющими определить и установить тип терминала: tset и stty. Самый простой способ установить тип терминала состоит в использовании утилиты tset. Синтаксис tset -s [-ес] [~ic] {-m портЮ: [?] типТерминала] * Утилита tset определяет тип терминала. Если опция -s не используется, то предполагается, что ваш тип терминала уже сохранен в переменной term окружающей среды, и утилита tset
определяет тип, используя информацию в зависимости от вашей версии UNIX, хранящуюся в файле /etc/termcap или базе данных terminfo. Если вы используете опцию -s, утилита tset исследует файл /etc/ttytab и пробует соотнести порт вашего терминала с его типом. Если тип найден, утилита указанным в файле /etc/termcap образом его инициирует. Опция -s также выводит команды shell на стандартный выход. Переменные окружающей среды term и termcap устанавливаются в необходимое значение, и запускается нужный тип терминала. В имени файла не должно содержаться символов, которые могут быть неправильно интерпретированы shell. Эти символы будут указаны чуть ниже. Опция -е задает стирающий символ терминала в аргументе с вместо установленной по умолчанию комбинации клавиш <Ctrl>+<H>. Символы управления могут быть обозначены или просто введенным символом, или вместе с предшествующим ему символом л (чтобы указать на комбинацию клавиш <Ctrl>+<H>). Опция -i определяет прерывающий символ терминала в аргументе с вместо установленной по умолчанию комбинации клавиш <Ctrl>+<C>. Обозначение символов управления рассматривается в разд. "Режим ввода текста " далее в этой главе. Записи файла /etc/ttytab могут быть удалены или добавлены с помощью опции -т. Последовательность -mpp:tt сообщает утилите tset следующее: если тип порта терминала является рр, то он должен быть заменен на тип терминала tt. Помещенный после двоеточия (:) знак вопроса (?) показывает tt и просит пользователя либо нажать клавишу <Enter> для подтверждения, либо ввести другой тип терминала. Пример: ttyOf ”usr/etc getty std.9600” vtlOO off local ttypO none network off secure ttypl none network off secure Первое поле содержит имена портов, а третье — типы терминалов. Например, если пользователь зарегистрировался через порт ttyOf, то его тип терминала, в соответствии с записями этого файла, определялся бы как vtioo. В конфигурациях, где терминалы являются жестко замонтированными (т. е. непосредственно связаны с определенным портом), этот алгоритм работает прекрасно, поскольку терминал всегда связан с тем же самым портом. Но, как мы увидим вскоре, это не работает в сетевых конфигурациях. В следующем примере определим фактическое имя порта, используя утилиту tty (описанную в главе 3)\ $ tty ...вывести ID порта моего терминала. /dev/ttypO 4 Зак 786
$ tset -s ...вызов tset. set noglob; ...команды shell, генерируемые tset. TERM=network; export TERM; TERMCAP='sa;cent;network:li#24:co#80:am:do=AJ: ’; export TERMCAP; unset noglob; Erase is Ctrl-H $ Предыдущий пример дан только для иллюстрации работы утилиты tset. Чтобы действительно изменить переменные term и termcap, вы должны выполнить команду eval, которая подробно описана в главе 4. Вот более реалистический пример использования утилиты tset: $ set noglob $ eval 'tset -s' Erase is Backspace $ unset noglob $ echo $TERM network $ ...временно запрещает расширение имени файла. ...оценить вывод tset. ...сообщение tset. ...разрешение расширения имени файла. ...посмотреть новое значение TERM. ...тип терминала, который нашел tset. К сожалению, тип терминала network (сеть) — не очень удобен, поскольку он не имеет практически никаких возможностей. Утилита tset определяется правилом: если обнаружен тип терминала network, следует предполагать, что данный терминал — vtlOO — и запросить у пользователя подтверждение этого. Пример: $ set noglob ...запрещает расширение имени файла. $ eval 'tset -s -т 'network:vtlOO'' ...предоставить правило. TERM = (vtlOO) <Enter> ...нажата клавиша <Enter>. Erase is Backspace $ unset noglob ...разрешение расширения имени файла. $ echo $TERM ...вывести новую установку TERM. vtlOO ...это тип терминала, который использует tset. $ _ Обобщая, можно сказать, что достаточно удобно записать запуск утилиты tset в стартовый файл вашего терминала. Файлы запуска shell описаны в главе 4. Самый простой синтаксис утилиты tset представлен ниже. □ С shell setenv TERM vtlOO tset
□ Bourne/Korn/Bash shell TERM=vt100; export TERM tset Более сложная форма tset определяет местонахождение файла /etc/ttytab и чаще всего выглядит, как это показано в примере. □ С shell set noglob eval ’tset -s -m ’network:?vtl00’' unset noglob □ Bourne/Korn/Bash shell eval ’tset -s -m ’network:?vtl00’’ Изменение характеристик терминала: stty Каждый терминал определенным образом обрабатывает некоторые символы. Эти знаки называются метасимволами. Например, метасимволом является символ возврата на шаг назад и завершающая программу последовательность, генерируемая комбинацией клавиш <Ctrl>+<C>. Переопределить значения метасимволов можно, используя утилиту stty. Синтаксис stty -а {опция}★ {строкаМета символа <значение>} * Утилита stty позволяет проверить и установить характеристики терминала. С ее помощью можно изменить около 100 различных параметров, здесь будут рассмотрены наиболее используемые.. Для получения листинга текущих установок терминала служит опция -а. Чтобы изменить конкретный параметр, используйте одну или несколько следующих опций: Опция Значение -echo He отображать печатаемые символы echo Отображать печатаемые символы -raw Разрешить специальное значение метасимволов raw Запретить специальное значение метасимволов
(окончание) Опция Значение -tostop Позволить фоновым процессам посылать информацию на терминал tostop Остановить фоновые процессы, которые пытаются послать информацию на терминал sane Установить характеристики терминала по умолчанию Также имени или \ 1 новны> вы можете переопределить значение метасимвола, присваивая его новое значение. Символ управления может быть обозначен как Л 1епосредственно перед этим символом. Ниже приведен список ос-с метасимволов и их значений. Опция Значение erase Удалить предыдущий символ kill Стереть всю текущую строку Inext Не обращаться со следующим символом, как со специальным susp Приостановить текущий процесс intr Прервать фоновую работу без распечатки памяти quit Завершить фоновую работу с распечаткой памяти stop Остановить/возобновить вывод на терминал eof Задать конец ввода Вот пример работы утилиты stty: $ stty -а . ..вывести текущие установки терминала. speed 38400 baud, 24 rows, 80 columns parenb -parodd cs7 -cstopb -hupcl cread -clocal -crtscts -ignbrk brkint ignpar -parmrk -inpck istrip -inlcr -igncr icrnl -iuclc ixon -ixany -ixoff imaxbel isig rexten icanon -xcase echo echoe echok -echonl -noflsh -tostop echoctl -echoprt echoke opost -olcuc onlcr -ocrnl —onocr -onlret -ofill -ofdel erase kill werase rprnt flush Inext susp intr quit stop eof
$ stty erase $ stty erase ^h ...задать удаление символа ...через комбинацию клавиш <Ctrl>+<B>. ...задать удаление символа ...через комбинацию клавиш <Ctrl>+<H>. $ _ Используйте утилиту stty для установки более удобных для вас значений метасимволов. Настройте свой терминал "под себя" путем создания сценариев, один из вариантов которого мы рассмотрим в главе 7. Вот пример кода, в котором используется утилита stty, чтобы отключить вывод символов: $ stty -echo $ stty echo $ ...отключить вывод. ...включить его снова. Обратите внимание, что последнюю строку ввода (stty echo) вы не увидите из-за ранее установленного запрета вывода. Теперь, когда мы узнали, как определить тип терминала и его установки, пришло время рассмотреть два наиболее популярных редактора UNIX: vi и emacs. Редактирование файла: vi Как мы уже упомянули, наиболее популярными редакторами в UNIX являются vi и emacs. Неплохо иметь опыт работы с vi, т. к. он поставляется практически с каждой версией UNIX. Второй редактор, emacs, встречается не во всех версиях, однако достаточно традиционен для этой системы. В этом и последующих разделах мы поподробнее познакомимся с каждым из них. Также будут даны ссылки на другие источники, из которых вы можете получить более подробную информацию. Запуск vi Немного истории. Изначально Билл Джой (Bill Joy) из Sun Microsystems, Inc., работая в Калифорнийском университете в Беркли создал этот редактор для BSD UNIX. Однако популярность vi выросла настолько, что он стал стандартной утилитой большинства версий UNIX. Название vi (от англ, visual editor) расшифровывается, как визуальный редактор. Для запуска этого редактора необходимо просто ввести команду vi без параметров. В случае, если вам необходимо редактировать существующий файл, то в качестве параметра следует передать его имя. После запуска чистые (пустые) строки указываются тильдами (~), после чего vi ожидает от вас ввода команд. Для экономии места мы будем рассматривать примеры длиной не более шести строк.
Например, при запуске vi без параметров на вашем экране отобразится следующее: Режим ввода команды — один из двух режимов, которые предоставляет редактор vi. Другой режим называется режимом ввода текста. Так как легче проиллюстрировать работу командного режима на примере каких-нибудь фраз, мы начнем знакомство с режима ввода текста. Режим ввода текста В табл. 2.14 дано описание клавиш ввода текста. Любой текст, который вы вводите, отображается на экране. Для перехода на следующую строку служит клавиша <Enter>. Для удаления последнего символа пользуйтесь клавишей < Backspaced Внимание Вы не можете двигаться по экрану с помощью клавиш перемещения курсора, когда находитесь в режиме ввода текста. В режиме ввода текста эти клавиши интерпретируются, как обычные символы ASCII, и коды управления вводятся, как нормальный текст. Таблица 2.14. Клавиши ввода текста в редакторе vi Клавиша Действие <i> Текст вставляется перед курсором Текст вставляется в начало текущей строки <а> Текст добавляется после курсора <А> Текст добавляется к концу текущей строки <0> Текст добавляется после текущей строки <О> Текст вставляется перед текущей строкой <R> Текст заменяется (переписывается) Для перехода к вводу текста из режима команд нажмите клавишу <Esc>.
Так, чтобы ввести короткую поэму, необходимо нажать клавишу <а> для перехода в текстовый режим, и клавишу <Esc> для возврата к режиму команд. I always remember standing in the rains, On a cold and damp September, Brown Autumn leaves were falling softly to the ground, Like the dreams of a life as they slide away. В следующем разделе мы узнаем, как сделать из представленного текста нечто более интересное. Режим ввода команд Для редактирования текста следует войти в командный режим. Для этого нажмите клавишу <Esc>. Если вы нажмете ее в командном режиме, ничего не произойдет. Система лишь звуковым сигналом напомнит вам, что вы уже работаете с ним. Редактирование документа происходит путем нажатия последовательности специальных клавиш. Например, для того чтобы стереть отдельное слово, поместите курсор к его началу и нажмите клавишу <d> и затем клавишу <w> (от англ, delete word — удалить слово). Некоторым функциям редактирования необходимы параметры, которые передаются после двоеточия (:). Если эта клавиша нажата, остальная часть команды выводится внизу экрана. Например, чтобы удалить строки с 1 по 3, необходимо ввести следующую командную последовательность: :1,3d<Enter> Некоторые функции редактирования типа команды удаления блока, которую мы только что рассмотрели, действуют в каком-либо диапазоне строк. Редактор понимает два формата указания диапазона: □ чтобы выбрать единственную строку, укажите ее номер; □ чтобы выбрать блок строк, укажите номер первой и последней строк включительно, разделенных запятой. Символ $ используется для указания номера последней строки в файле; символ . — для строки, содержащей курсор. Кроме того, для определения строк можно пользоваться различными арифметическими выражениями. Например, такой последовательностью, которая удалила бщ текущую строку и две следующие за ней строки: :.,.+2d<Enter> В табл. 2.15 представлены другие способы задания диапазона.
Таблица 2.15. Выбор диапазона строк в редакторе vi Диапазон Выбирает Все строки в файле 1,. Все строки от начала файла до текущей строки включительно Все строки от текущей строки до конца файла включительно .-2 Отдельную строку, которая находится на две строки выше текущей строки Буфер памяти и временные файлы Во время редактирования файла vi хранит его копию в памяти и вносит туда изменения. Файл на диске не изменяется, пока вы не сохраните его или не выйдете из vi с помощью одной из команд, которая автоматически сохраняет файл (эти команды мы рассмотрим чуть позже). По этой причине рекомендуется почаще сохранять изменения во время работы. В противном случае, при сбое системы будут потеряны все внесенные вами изменения. Однако, если вы сохраняете промежуточные версии, в случае сбоя системы будут потеряны не все изменения, и вы сможете восстановить файл, используя опцию -г (vi -г имяФайла) из временного файла. Некоторые версии UNIX пошлют вам электронное письмо со сведениями, как восстановить утерянный файл. Но, несмотря на существующую возможность восстановления, безопаснее все-таки почаще сохранять изменения. Общие функции редактирования Основные функции редактирования в vi^ могут быть сгруппированы в следующие категории: □ перемещение курсора; □ удаление текста; □ замена текста; □ вставка текста; □ поиск по тексту; □ поиск и замена текста; □ сохранение или загрузка файлов; □ разное (включая, выход из vi). Данные категории описаны и проиллюстрированы чуть ниже, на примере поэмы, о которой мы говорили в разд. "Режим ввода текста" ранее в этой главе.
Перемещение курсора В табл. 2.16 представлены общие команды перемещения курсора. Например, чтобы вставить слово Just перед словом Like в четвертой строке, необходимо переместить курсор на четвертую строку, нажав клавишу <i>, чтобы войти в режим ввода текста, а затем нажать клавишу <Esc> для возвращения в режим команд. Для перемещения курсора на четвертую строку используется последовательность: 4<Enter> (либо 4G). Таблица 2.16. Команды перемещения курсора в редакторе vi Перемещение Ключевая последовательность Вверх на строку <?> или <к> Вниз на строку <Х> или <j> Вправо на один символ <-»> или <1> Влево на один символ «-> или <h> К началу строки В конец строки Назад на одно слово <~> <$> <Ь> Вперед на одно слово Вперед к концу текущего слова К началу экрана В середину экрана В конец экрана Вниз на половину экрана Вперед на один экран Вверх на половину экрана Назад на экран К строке пп <w> <е> <Н> <м> <Ctrl>+<D> <Ctrl>+<F> <Ctrl>+<U> <Ctrl>+<B> : nn<Enter> (nnG также работает) К концу файла <G> Удаление текста В табл. 2.17 приведены общие команды удаления текста. Например, для удаления слова always следует воспользоваться последовательностью: □ i<Enter> для перемещения на начало первой строки;
□ нажать клавишу <w> для перемещения на одно слово вперед; □ ввести dw для удаления. Для удаления буквы s в конце слова rains, находящегося в первой строке, нам необходимо переместить курсор на символ s и затем нажать клавишу <х>. Таблица 2.17. Команды, удаляющие текст Элемент для удаления Ключевая последовательность Символ Поместите курсор на символ и затем нажмите клавишу <х> Слово Поместите курсор на начало слова и затем введите dw Строка Поместите курсор куда-нибудь в строку, а затем введите dd. (Ввод числа перед dd заставит vi удалить указанное число строк, начиная с текущей строки.) С текущей позиции до конца текущей строки Г руппа строк Нажмите клавишу <D> : <диапазон>&<ЕпЪег> Вот как выглядит текст после описанных выше манипуляций: I remember standing in the rain, On a cold and damp September, Brown Autumn leaves were falling softly to the ground, Just Like the dreams of a life as they slide away. Замена текста Основные команды замены текста рассмотрены в табл. 2.18. Так, например, для замены слова standing на walking необходимо переместиться в его начало и набрать cw, а затем напечатать walking и нажать клавишу <Esc>. Для замены строчной s в слове September на прописную S следует поместить курсор на s и нажать клавишу <г>, а затем набрать s. Таблица 2.18. Замена текста в редакторе vi Элемент для замены Символ Ключевая последовательность Поместите курсор на символ, нажмите клавишу <г>, а затем напечатайте символ замены
Таблица 2.18 (окончание) Элемент для замены Ключевая последовательность Слово Поместите курсор в начало слова, наберите cw и затем напечатайте текст замены, в конце нажмите клавишу <Esc> Строка Разместите курсор где-нибудь в строке, наберите с с, а затем напечатайте текст замены, в конце нажмите клавишу <Esc> Теперь наша поэма выглядит так: I remember walking in the rain, On a cold and dark September, Brown Autumn leaves were falling softly to the ground, Just like the dreams of a life as they slip away. Вставка текста Для копирования и вставки текста редактор vi пользуется специальным буфером. Например, для копирования первых двух строк в буфер и вставки их после третьей нам необходимо совершить следующее: :1,2у : Зри В табл. 2.19 описаны основные команды работы с буфером. Таблица 2.19. Команды работы с буфером Действие Ключевая последовательность Скопировать строки в буфер вставки :<диапазон>у<Enter> Скопировать текущую строку в буфер вставки <Y> Вставить содержимое буфера вставки после текущей строки р или :pu<Enter> (содержимое буфера вставки не изменяется) Вставить содержимое буфера вставки после строки ПП : nnpu<Enter> (содержимое буфера вставки не изменяется) Сейчас наша поэма выглядит так: I remember walking in the rain, On a cold and dark September,
Brown Autumn leaves were falling softly to the ground, I remember walking in the rain, On a cold and dark September, Just like the dreams of a life as they slip away. Поиск Если необходимо найти то или иное слово или выражение в тексте, вы можете воспользоваться поиском, который осуществляется выше и ниже от текущей строки. В табл. 2.20 рассмотрены наиболее общие команды поиска. Замыкающие символы / и ? необязательны для первых двух команд (т. к. редактор понимает, что вы имели в виду; однако использование / и ? является полезной привычкой, позволяющей добавить другие команды после этих символов). Таблица 2.20. Команды поиска в vi Действие Ключевая последовательность Поиск вперед от текущей позиции строки sss /sss/<Enter> Поиск назад от текущей позиции строки sss ?sss?<Enter> Повторить последний поиск <n> Повторить последний поиск в обратном направлении <N> Например, для поиска слова ark, начиная с первой строки, необходимо ввести следующие команды: :l<Enter> /ark/<Enter> В результате выполнения этой последовательности курсор будет установлен на часть слова dark, содержащего эту последовательность: I remember walking in the rain, On a cold and dark September, Brown Autumn leaves were falling softly to the ground, Just like the dreams of a life as they slip away. Поиск и замена Очень часто возникает необходимость замены определенных выражений в тексте. Для этого следует сначала найти указанные выражения, а потом
произвести замену. Эта задача выполняется с помощью команд, описанных в табл. 2.21. Таблица 2.21. Поиск и замена в редакторе vi Действие Ключевая последовательность Заменяет первое вхождение sss на ttt :<.диапазонуз/ sss/ ttt/<Enter> в каждой строке Заменяет каждое вхождение sss на ttt :<диапазонУг/ sss/ ttt/g<Enter> в каждой строке После замены всех символов ге на XXX получим следующее: I XXXmember walking in the rain, On a cold and dark September, Brown Autumn leaves weXXX falling softly to the ground, Just like the dXXXams of a life as they slip away. :1,$s/re/XXX/g Сохранение или загрузка файлов Для сохранения и загрузки файла используются команды, описанные в табл. 2.22. Таблица 2.22. Команды сохранения и загрузки файлов в редакторе vi Действие Ключевая последовательность Сохранить файл как <имя> : w<MMtf><Enter> Сохранить файл с текущим именем :w<Enter> Сохранить файл с текущим именем и выйти :wq<Enter> (zz также работает) Сохранить только определенные строки в другой файл : <диапазон>ы<имя><Еп^гУ Прочитать содержимое другого файла в текущую позицию :г <имяХЕп!ег> Редактировать файл <имя> вместо текущего файла : e<wMHXEnter> Редактировать следующий файл из первоначальной командной строки :n<Enter>
Пример записи содержимого буфера в файл с именем rain.doc: I remember walking in the rain, On a cold and dark September, Brown Autumn leaves were falling softly to the ground, Just like the dreams of a life as they slip away. :w rain, doc При сохранении файла редактор vi сообщает его размер. Случайно выйти из vi, не сохранив изменения, невозможно. Если вы задаете больше, чем один файл в командной строке во время первоначального вызова vi, редактор стартует, загружая первый файл. Перейти к редактированию следующего файла можно, используя ключевую последовательность :п. Разное В табл. 2.23 приведены наиболее общие команды работы с редактором vi, включая выход из него. Комбинация клавиш <Ctrl>+<L> особенно полезна для обновления экрана в случае вывода сообщений о сбоях в работы системы во время работы с vi. Таблица 2.23. Основные команды работы с редактором vi Действие Ключевая последовательность Перерисовать экран Отменить последнюю операцию Отменить многочисленные изменения в текущей строке Соединить следующую строку с текущей Повторить последнюю операцию Выполнить команду в новом shell и затем вернутся В vi <Ctrl>+<L> <u> <U> :!<команда><Еп1ег> Выполнить команду в новом shell и прочитать ее вывод в буфер редактирования в текущую позицию Выйти из vi, если работа сохранена :г!<команда><Еп1ег> :q<Enter> Выйти из vi без сохранения :q!<Enter>
Выход из редактора: I remember walking in the rain, On a cold and dark September, Brown Autumn leaves were falling softly to the ground, Just like the dreams of a life as they slip away. Настройка vi Путем установки определенных опций вы можете настроить поведение вашего редактора в тех или иных ситуациях. Полный список доступных опций изменяется в зависимости от версии и платформы, но мы обсудим наиболее часто используемые. Команда :set служит для вывода опций, поддерживаемых редактором vi. После ввода .-set all будут выведены текущие и поддерживаемые редактором установки. Они задаются либо числовыми и строковыми величинами, либо переключателями "Вкл" и "Выкл". Наиболее используемые опции показаны в табл. 2.24. Таблица 2.24. Настройки редактора vi Опция Описание Установка по умолчанию autoindent Во включенном состоянии говорит о том, что следующая строка, которую вы печатаете, имеет такой же отступ, как и предыдущая строка Выкл ignorecase В процессе поиска и замены строчные и прописные символы удовлетворяют критерию, требуемому для совпадения Выкл number Нумерация строк выводится по левой стороне экрана Выкл showmode Показывает текущий режим (текстовый или командный) Выкл showmatch Подсвечивает открывающую скобку при печати закрывающей Выкл Например, для того чтобы включить опцию autoindent, напечатайте :set autoindent<Enter> А для того чтобы выключить, напечатайте :set noautoindent<Enter>
Сохранение пользовательских настроек Для того чтобы не настраивать каждый раз заново редактор, вы можете создать файл, в котором укажите необходимые установки. Файл конфигурации должен называться .ехгс. Внимание Обратите внимание, что имя файла начинается с точки: это специальное соглашение, о котором мы узнаем позже, когда будем рассматривать команды shell. set autoindent set ignorecase set nonumber В действительности нет необходимости устанавливать опцию nonumber, т. к. ее начальное значение "Выкл", но в данном случае имеется в виду, что вы как бы выключили ее. Потому-то она и была установлена. Для дополнительной информации Для более глубокого знакомства с редактором vi рекомендуется обратиться к книге [Christian 1988]. Редактирование файла: emacs emacs (от англ. Editor MACroS) — не менее популярный редактор, который можно обнаружить на многих UNIX-системах (либо загрузить из Интернета). История emacs начиналась в Lisp-based artificial intelligence community. В 1975 г. Ричард Сталлман (Richard Stallman) и Гай Стил (Guy Steele) написали первоначальную версию, которая была в последствии доработана и сейчас свободно распространяется в форме исходных кодов через Free Software Foundation (FSF). О группах Open Sourse и Free Software Foundation мы поговорим в главе 16. Запуск emacs Для запуска этого редактора, как и для запуска vi, необходимо просто ввести команду emacs без параметров. Чтобы начать редактирование существующего файла, задайте его имя в качестве параметра. При запуске emacs без параметров на вашем экране отобразится следующее: GNU Emacs 19.34.1 Copyright (С) 1996 Free Software Foundation, Inc.
Type С-х С-с to exit Emacs. Type C-h for help; C-x u to undo changes. Type C-h t for a tutorial on using Emacs. Emacs: ^scratch* (Fundamental)-----All Для экономии места будем рассматривать небольшие примеры. Вторая снизу строка называется строкой режима и содержит следующую информацию: □ если первые три черты содержат **, то текущий файл был изменен; □ название, которое следует за Emacs: — имя текущего файла; если ни один файл не загружен, вместо него используется имя *scratch*; □ текущий режим редактирования показывается в круглых скобках. В данном случае это Fundamental, который является стандартным режимом редактирования; □ следующий элемент указывает текущую рабочую позицию в файле, как процент относительно размера всего документа. Если файл очень маленький и полностью помещается на экране, то это значение равно ан. Если вы находитесь в начале или конце файла, то соответственно отображается Тор И Bot. Команды emacs В отличие от vi, в редакторе emacs не различаются режим ввода текста и режим команд. Для того чтобы ввести текст, просто начинают печатать. Начальный приветствующий заголовок emacs автоматически исчезает, когда вы вводите первый символ. Длинные строки не разрываются автоматически, так что необходимо нажать клавишу <Enter> для перехода на новую строку. Строки, превышающие ширину экрана, заканчиваются символом \ и переносятся на следующую строку, как это показано в следующем примере: Это очень длинная строка, иллюстрирует способ, каким выв \ одятся неразрывные строки Это более короткая строка --- Emacs: ^scratch* (Fundamental) -- All --------- Редактирование в emacs происходит через набор определенных команд. В данной книге одновременное нажатие клавиш будет обозначаться следующим образом: <Ctrl>+<H> <t> ’
Это означает, что нажимают и удерживают клавишу <Ctrl> и затем нажимают клавишу <Н>. Затем отпускают обе клавиши и нажимают клавишу <t>. Точно так же используется клавиша <Esc>. Например, последовательность <Esc> <х> означает, что нажимают клавишу <Esc> (но не держат ее) и затем нажимают клавишу <х>. Если же когда-нибудь вы нажмете <Esc> два раза подряд, то emacs предложит вам нажать клавишу <п> для отмены операции. В следующих разделах мы познакомимся подробнее с приемами редактирования В emacs. Как избежать проблем Всякий раз, когда вы изучаете новую программу, весьма легко растеряться и запутаться. Вот пара полезных команд для возврата к нормальному состоянию: □ комбинация клавиш <Ctrl>+<G> заканчивает любую команду редактора emacs, даже если она (т. е. команда) только частично введена, и возвращает emacs к ожиданию новых команд; □ комбинация клавиш <Ctrl>+<X> <1> закрывает все окна emacs кроме главного окна редактирования файла. Это полезно, поскольку часто редактор выводит какую-либо информацию в новом окне, и следует знать, как его закрыть после ознакомления с его содержимым. Получение помощи Существует немало способов получить помощь о работе emacs. Однако лучше всего воспользоваться встроенным в редактор справочником, вызов которого осуществляется комбинацией клавиш <Ctrl>+<H> <t>. Выход из emacs Для того чтобы закрыть emacs и сохранить файл, используют комбинацию клавиш <Ctrl>+<X> <Ctrl>+<C>. Если файл не сохранен со времени его последнего изменения, появится запрос на подтверждение сохранения. Режимы emacs Редактор поддерживает несколько различных режимов для ввода текста, включая Fundamental, Lisp Interaction И С. Каждый режим имеет специальные функции для работы с конкретным видом текста. По умолчанию emacs запускается в режиме Fundamental. Рассмотрим именно этот режим. За информацией о других режимах обращайтесь ко встроенному справочнику.
Ввод текста Чтобы ввести текст, просто начинают печатать. Пример: There is no need for fear in the night, You know that your Mommy is there, To watch over her babies and hold them tight, When you are in her arms you can feel her sigh all night. --- Emacs: *scratch* (Fundamental)-----All------------ Общие функции редактирования Наиболее общие функции редактора emacs могут быть сгруппированы в следующие категории: □ перемещение курсора; □ удаление, вставка и отмена текста; □ поиск в тексте; □ поиск и замена текста; □ сохранение и загрузка файлов; □ разное. Далее мы рассмотрим эти функции на уже знакомом нам примере поэмы. Перемещение курсора Общие комбинации клавиш перемещения курсора описаны в табл. 2.25. Например, для того чтобы вставить слова worry or перед словом fear в первой строке, необходимо переместить курсор в первую строку файла, нажимая клавиши <Esc> «> и затем, передвинуться вперед на несколько слов, нажимая клавиши <Esc> <f>. После этого необходимо напечатать слова, которые будут автоматически вставлены в текущую позицию курсора. Таблица 2.25. Перемещение курсора в редакторе emacs Действие Ключевая последовательность Вверх на одну строку Вниз на одну строку <Ctrl>+<P> (предыдущий) <Ctrl>+<N> (следующий) Вправо на один символ <Ctrl>+<F> (вперед, переход на новую строку) Влево на один символ <Ctrl>+<E> (назад, переход на новую строку) К началу строки <Ctrl>+ <А> (а — это первая буква)
Таблица 2.25 (окончание) Действие Ключевая последовательность К концу строки Назад на одно слово <Ctrl>+<E> (end — конец) <Esc> <b> (back — назад) Вперед на одно слово Вниз на один экран Вверх на один экран В начало файла В конец файла <Esc> <f> (forward — вперед) <Ctrl>+<V> <Esc> <v> <Esc> «> <Esc> <» Удаление, вставка и отмена Всякий раз, когда удаляется элемент текста, emacs запоминает его в индивидуальном буфере уничтожения. Список буферов уничтожения поддерживается для того, чтобы удаленные элементы могли быть восстановлены после удаления с экрана. Чтобы восстановить последний стертый элемент, используйте комбинацию клавиш <Ctrl>+<Y>. После ее нажатия вы можете применить последовательность клавиш <Esc> <у>, чтобы заменить восстанавливаемый элемент предварительно удаленным. Каждый раз, когда вы нажимаете клавиши <Esc> <у>, восстанавливаемый элемент продвигается на одну позицию назад в списке буфера уничтожения. Вы можете добавить очередной удаляемый элемент в конец последнего буфера уничтожения, не создавая новый буфер, используя последовательность клавиш <Esc> <Ctrl>+<W> до того, как воспользуетесь командой удаления. Это может быть полезно, если необходимо сначала вырезать различные части файла, а потом вставить в одно место. В табл. 2.26 приведены комбинации клавиш, позволяющие удалять символы. Таблица 2.26. Удаление, вставка и отмена в редакторе emacs Элемент для удаления Ключевая последовательность Символ перед курсором <Delete> Символ после курсора <Ctrl>+<D> Слово пред курсором <Esc> <Delete> Слово после курсора <Esc> <d> До конца текущей строки <Ctrl>+<K> Предложение <Esc> <k>
Вы можете отменить сделанные изменения, нажимая клавиши <Ctrl>+<X> <u> для каждого отменяемого действия. В табл. 2.27 описаны комбинации клавиш работы с буфером. Таблица 2.27. Буфер уничтожения в редакторе emacs t Действие Ключевая последовательность Вставить последний буфер уничтожения <Ctrl>+<Y> Извлечь предыдущий удаленный фрагмент <Esc> <у> Добавить следующий удаляемый фрагмент <Esc> <Ctrl>+<W> Отменить последнее действие <Ctrl>+<X> <u> Поиск Работая в emacs, вы можете пользоваться инструментом, называемым инкрементным поиском. Для того чтобы найти конкретную последовательность символов вперед от текущего местонахождения курсора, нажмите комбинацию клавиш <Ctrl>+<S>. Внизу экрана появится подсказка "I-search:", после которой вы должны ввести искомую строку. По мере того, как вы будете вводить последовательность символов, редактор emacs станет искать ближайшую к текущему положению строку, совпадающую с введенной. То есть во время ввода поискового выражения подыскиваются подстроки, содержащие уже введенную последовательность. Для завершения поиска и остановки на текущей позиции следует нажать клавишу <Esc>. Стирая символы в поисковом выражении до нажатия клавиши <Esc>, вы передвигаете курсор к ближайшему совпадению с оставшимся набором символов поиска. Для повторения поиска не нажимайте клавишу <Esc>, а воспользуйтесь комбинацией клавиш <Ctrl>+<S> для поиска вперед от текущего положения курсора или <Ctrl>+<R> для поиска назад. В табл. 2.28 рассмотрены основные комбинации клавиш поиска. Таблица 2.28. Поиск в редакторе emacs Действие Ключевая последовательность Поиск вперед строки str <Ctrl>+<S> str Поиск назад строки str <Ctrl>+<R> str Повторить последний поиск вперед <Ctrl>+<S> Повторить последний поиск назад <Ctrl>+<R> Завершить режим поиска <Esc>
Поиск и замена Для того чтобы найти и заменить какие-либо выражения, нажмите клавиши <Esc> <х> и введите г epi s, а затем нажмите клавишу <Enter>. Далее emacs попросит ввести искомую строку, а затем заменяющую строку. После нажатия клавиши <Enter> будет выполнена замена по всему тексту. Сохранение и загрузка файлов Чтобы сохранить файл, нажмите комбинации клавиш <Ctrl>+<X> <Ctrl>+<S>. Если файл не имеет имени, вам будет предложено назвать его. Для редактирования файла нажмите комбинации клавиш <Ctrl>+<X> <Ctrl>+<F>. Появится запрос на ввод имени файла. Если файл уже существует, его содержимое загрузится в emacs; иначе файл будет создан. Для сохранения файла и выхода из emacs служат комбинации клавиш <Ctrl>+<X> <Ctrl>+<C>. В табл. 2.29 описаны основные комбинации клавиш для работы с emacs. Таблица 2.29. Основные команды работы с редактором emacs Действие Ключевая последовательность Сохранить текущую работу <Ctrl>+<X> <Ctrl>+<S> Редактировать другой файл <Ctrl>+<X> <Ctrl>+<F> Сохранить работу и затем выйти из редактора <Ctrl>+<X> <Ctrl>+<C> Дополнительные команды Для того чтобы обновить экран, нажмите комбинацию клавиш <Ctrl>+<L>. Для перехода в режим autowrap, который автоматически производит перенос слов на новую строку, когда достигается ее конец, нажмите последовательно клавиши <Esc> <х>, а затем клавишу <Enter>. Для выхода из этого режима повторите действие. Для дополнительной информации Для получения дополнительных сведений о emacs рекомендуется обратиться к книге [Roberts 1991].
Электронная почта: mail/mailx Последний раздел этой главы посвящен использованию электронной почты UNIX. Будет полезным как можно быстрее научиться работать с электронной почтой, потому что это весьма эффективный способ задать вопрос о работе UNIX системному администратору или другим, более опытным пользователям. Существуют, как минимум, две наиболее популярные почтовые программы. Одна из них называется mail, а другая maiix. Для упоминания обеих будем пользоваться термином "почта". Программа mail имеет большое количество функций, но мы с вами остановимся только на основных, тех — которые будут вам наиболее полезны. За дополнительной информацией обращайтесь к встроенному справочнику. Синтаксис mail -Н [-f имяФайла] [1р_пользователя]* Утилита mail позволяет посылать и получать почту. Если указан список пользователей, то программа отправляет им данные, полученные со стандартного входа, после чего завершается. Имя пользователя может быть задано следующим образом: • локальное имя пользователя (т. е. login name — имя входа в систему); • интернет-адрес в форме name@hostname.domain; • имя файла; • почтовая группа. Об использовании интернет-адресов мы поговорим в главе 9. Почтовые группы очень коротко мы рассмотрим сейчас. Если имя пользователя не определено, утилита mail предполагает, что вы собираетесь читать почту из каталога. Каталог /var/mail/ <имяПолъзователя>, где <имяПользователя> — собственное имя пользователя, читается по умолчанию, хотя это действие можно отменить через опцию -f. Тогда mail выдает приглашение & и ждет команды. Опция -н выводит заголовки содержимого вашего почтового каталога, но не входит в режим команды. Список наиболее полезных параметров командного режима представлен ниже. При запуске утилита mail читает конфигурационный файл .mailrc из вашего домашнего каталога, в котором содержатся параметры настройки почтовой программы. Имя файла конфигурации может быть изменено
путем установки соответствующего значения переменной окружения mailrc. Переменные окружения обсуждаются в главе 4. У программы существует большое количество разнообразных настроек. Наиболее важная — способность определить почтовые группы (также иногда называемые псевдоименами). Это переменные, обозначающие группу пользователей. Для задания почтовой группы разместите строку вида group имя {Ю_пользователя}+ в файле запуска почты. Вы сможете использовать это имя в качестве псевдонима заданной группы пользователей. В табл. 2.30 дано описание основных команд работы с утилитой mail. Таблица 2.30. Команды работы с утилитой mail Команда Описание 7 Выводит справку сору [списокСообщений] [имяФайла] Копирует сообщения в имяФайла, не помечая их как сохраненные delete [списокСообщений] Удаляет списокСообщений из системного почтового каталога file [имяФайла] Читает почту из почтового ящика имяФайла. Если никакое имяФайла не определено, показывает имя текущего почтового ящика вместе с размером и числом сообщений, в нем находящихся headers [сообщение] Выводит на экран заголовки сообщений, которые содержать в себе сообщение mail {10_пользователя}+ Посылает почту перечисленным пользователям print [списокСообщений] Выводит перечисленные сообщения с использованием утилиты more quit Осуществляет выход из утилиты mail reply [списокСообщений] Передает ответ отправителям списокСообщений save [списокСообщений] [имяФайла] Сохраняет указанные сообщения в имяФайла. Если никакое имяФайла не задано, сохраняет их в файле mbox пользовательского домашнего каталога В табл. 2.31 дано описание команд, используемых для работы с сообщениями.
Таблица 2.31. Работа с сообщениями в mail Синтаксис Описание Текущее сообщение nn Сообщение по номеру пп ' Первое неудаленное сообщение $ Последнее сообщение * Все сообщения nn-mm Сообщения, пронумерованные от пп до mm включительно user Все сообщения от пользователя Для вызова большинства команд в mail можно использовать первый символ их названия (например, р вместо print). Отправка почты Самый простой способ отправить почту состоит в том, чтобы ввести сообщение непосредственно с клавиатуры и закончить ввод, нажав комбинацию клавиш <Ctrl>+<D>: $ mail tim ...послать почту локальному пользователю tim. Subject: Mail Test ...ввести тему почты. Hi Tim,, How is Amanda doing? with best regards from Graham AD ...закончить ввод; стандартный вход посылается как почта. $ _ Мы уже немного обсудили создание почтовых групп, позволяющих посылать почту входящим в них людям. Теперь рассмотрим это на примере: group music jeff richard kelly bev $ mail music ...послать почту каждому члену группы. Subject: Music Hi guys How about a jam sometime? with best regards from Graham. AD $ ...конец ввода.
Для набора больших сообщений целесообразно будет воспользоваться каким-нибудь текстовым редактором и сохранить письмо в файл, который потом переадресовать на вход программы mail: $ mail music < jam.txt $ ...послать jam.txt по почте. Чтобы послать почту пользователям Интернета, используйте стандартную адресную схему Интернета, описанную в главе 9. $ mail glass@utdallas.edu < mesg.txt ...послать файл. Чтение почты Присланная вам почта сохраняется в файле /var/mai\/< ИмяПользователя>, где <ИмяПолъзователя> — это имя, с которым пользователь регистрируется в системе. Для чтения почтового каталога введите mail с необязательным именем каталога. Если в настоящее время почты нет, система уведомит вас об этом: $ mail ...попытаться прочитать мою почту из каталога по умолчанию. No mail for glass $ _ Если почта присутствует, утилита mail покажет список почтовых заголовков и выведет приглашение &. Следует нажать клавишу <Enter>, чтобы прочитать по порядку все сообщения, а затем — клавишу <q> (от англ, quit) для выхода из утилиты mail. Адресованная пользователю почта автоматически сохраняется в каталоге mbox его домашнего каталога, и ее можно прочитать позднее, введя следующую команду: $ mail -f mbox . . .читать почту, сохраненную в каталоге mbox. При чтении писем на экране будет отображено примерно следующее: $ Is -1 /var/mail/glass ...посмотреть, есть ли почта. -rw------- 1 glass 7 58 May 2 14:32 /var/mail/glass $ mail ...читать почту из каталога по умолчанию. Mail version SMI 4.0 Thu Oct 11 12:59:09 PDT 1990 Type ? for help. "/var/mail/glass": 2 messages 2 unread >U 1 tim@utdallas.edu Sat May 2 14:32 11/382 Mail test U 2 tim@utdallas.edu Sat May 2 14:32 11/376 Another & <Enter> ...нажал клавишу <Enter> для чтения сообщения 1. From tim@utdallas.edu Sat Mar 14 14:32:33 1998
То: glass@utdallas.edu Subject: Mail test hi there & <Enter> ...нажал <Enter> клавишу для чтения сообщения 2. From tim@utdallas.edu Sat Mar 14 14:32:33 1998 To: glass@utdallas.edu Subject: Another hi there again & <Enter> ...нажал клавишу <Enter> для чтения следующего сообщения. At EOF ...нет ни одного! & q ...покинуть mail. Saved 2 messages in /home/glass/mbox $ _ Для просмотра заголовков сообщений пользуйтесь опцией -н: $ mail -Н ...взглянуть на мой почтовый каталог. >U 1 tim@utdallas.edu Sat Мау 2 14:32 11/382 Mail test U 2 tim@utdallas.edu Sat May 2 14:32 11/376 Another $ _ Чтобы ответить на сообщение после его прочтения, используйте опцию г (от англ, reply). Для сохранения его в файл служит опция s (от англ. save). Если список сообщений не определен, выводится первое сообщение. Например: & 15 ...читать сообщение 15. From ssmith@utdallas.edu Tue Mar 17 23:27:11 1998 То: glass@utdallas.edu Subject: Re: come to a party The SIGGRAPH party begins Thursday NIGHT at 10:00 PM!! Hope you don’t have to teach Thursday night. & г ...ответить ssmith. To: ssmith@utdallas.edu Subject: Re: come to a party Thanks for the invitation. - see you there ... конец ввода. & s ssmith.party ...сохранить сообщение от ssmith. "ssmith.party" [New file] 27/1097 & q ...выйти из mail. $
В некоторых почтовых программах опция г применяется для ответа отправителю, а опция r — для ответа всем, в других — наоборот. Поэтому будьте внимательны и обратитесь за более подробной информацией к справочной системе. Вероятно, вам потребуется удалять некоторые сообщения, для этого используйте опцию d (от англ, delete)'. & dl-15 ...удалить сообщения с 1 по 15 включительно. & d* ...удалить все оставшиеся сообщения. Связь с системным администратором Как правило, почтовый адрес системного администратора — root или, возможно, sysadmin. Проблемы, связанные с работой электронной почты, чаще всего решает человек с псевдонимом postmaster. Обзор главы Перечень тем В этой главе мы научились: □ регистрироваться в системе UNIX; □ выходить из системы; П изменять пароль; □ работать с командами shell; □ запускать утилиты; □ работать со встроенной справочной системой; □ пользоваться специальными метасимволами терминала; □ работать с файлами; □ пользоваться двумя текстовыми редакторами; □ правильно конфигурировать терминал; П посылать электронную почту. Контрольные вопросы 1. Как можно нарушить безопасность UNIX? 2. Каков лучший вид пароля? 3. Какую команду UNIX надо использовать, чтобы изменить имя или местоположение файла?
4. Является ли ОС UNIX чувствительной к регистру клавиатуры? 5. Назовите четыре общих команды shell. 6. Почему командный интерпретатор shell лучше приспособлен для решения некоторых задач, чем С-программы? 7. Какая последовательность клавиш завершает процесс? 8. Какую комбинацию клавиш необходимо нажать для указания на конец ввода текста с клавиатуры? 9. Как вы заканчиваете работу с shell? 10. Как называется текущее расположение shell? 11. Какие атрибуты имеет файл? 12. Каково назначение групп? 13. Какие флаги права доступа существуют у каталогов? 14. Кто может изменять принадлежность файла? Упражнения 2.1. Отправьте письмо знакомому, проживающему в другой стране. Как вы думаете, за какое время оно дойдет до адресата? [Уровень: легкий.] 2.2. Почему процесс принадлежит только одной группе, в то время как запустивший его человек может быть членом нескольких? [Уровень: средний.] 2.3. Спроектируйте механизм файловой безопасности, который сможет исключить потребность в необходимости идентификации через команду set 10_пользователя. [Уровень: высокий.] 2.4. Многие даже весьма тривиальные изобретения защищены патентами. Как вы считаете, насколько необходим этот механизм защиты интеллектуальной собственности? [Уровень: высокий.] Проект Отправьте почту системному администратору и создайте две новых группы непосредственно для себя. Поэкспериментируйте с утилитами, используемыми для работы с системой полномочий файла. [Уровень: легкий.]

Глава 3 Утилиты UNIX для опытных пользователей Мотивация В дополнение к общим утилитам работы с файлами в UNIX-системах имеется немало программ, обрабатывающих текст, архивирующих и сортирующих файлы, выполняющих мониторинг системы. В этой главе дано описание утилит, помогающих сделать работу пользователя с операционной системой удобной и эффективной. Предпосылки Для понимания данной главы необходимо предварительно ознакомиться с предыдущими двумя. Желательно также, чтобы на вашем компьютере была установлена ОС UNIX, и вы могли закрепить на практике изученный материал. Задачи В этой главе мы научимся использовать более 30 утилит, способных облегчить работу в UNIX любому пользователю. Изложение Для лучшего понимания информация в данной главе представлена в виде нескольких UNIX-сессий.
Утилиты Ниже приведен список утилит, которые будут рассмотрены в данной главе. at crypt gzip tar awk diff In time biff dump mount tr cmp egrep od ul compress fgrep perl umount cpio find sed uncompress cron grep sort uniq crontab gunzip su whoami Кроме того, мы познакомимся с основами языка программирования Perl, ставшего неотъемлемой частью большинства UNIX-систем. Утилиты, которые мы будем обсуждать, могут быть логически сгруппированы, как показано в табл. 3.1. Далее мы рассмотрим каждую из групп поподробнее. Таблица 3.1. Утилиты UNIX Категория Утилиты Фильтрация файлов egrep, fgrep, grep, uniq Сортировка файлов sort Сравнение файлов cmp, diff Архивирование файлов tar, cpio, dump Поиск файлов find Команды планирования at, cron, crontab Программируемая обработка текста awk, perl Жесткие и символические связи In Переключение пользователей su Проверка почты biff Трансформация файлов compress, crypt, gunzip, gzip, sed, tr, ul, uncompress Поиск необработанного содержимого файла od Монтирование файловых систем mount, umount
Таблица 3.1 (окончание) Категория Утилиты Идентификация командных интерпретаторов whoami Подготовка документов nroff, spell, style, troff Выбор времени выполнения команды time Фильтрация файлов Часто бывает необходимо выбрать из файла только строки, отвечающие определенным критериям. Перечисленные ниже утилиты осуществляют такую обработку: □ утилиты egrep, fgrep и grep отфильтровывают все строки, которые не содержат установленный шаблон; □ утилита uniq выбирает одинаковые смежные строки. Шаблоны фильтрации: egrep/fgrep/grep Утилиты egrep, fgrep И grep Сканируют файл И отфильтровывают Все СТрО-ки, которые не соответствуют установленному шаблону. Перечисленные утилиты очень похожи, разница состоит в виде шаблонов, с помощью которых осуществляется поиск. Синтаксис grep -hilnvw шаблон {имяФайла}* fgrep -hilnvwx строка {имяФайла}* egrep -hilnvw шаблон {имяФайла}* Утилита grep (от англ. Global или Get Regular Expression or Print) позволяет находить соответствия заданному шаблону в списке файлов. Если файлы не определены, то поиск совпадения с искомой строкой проводится в стандартном входном потоке. Шаблоном может быть набор символов либо регулярное выражение. Все строки, соответствующие шаблону, отображаются как стандартный вывод. Если определено больше одного файла, то каждой строке предшествует имя файла, в котором она найдена, если определена опция -h. Опция -п нумерует найденные строки. Опция -i заставляет игнорировать регистр шаблонов. Опция -1 ото- 5 Зак. 786
Сражает список файлов, которые содержат определенный шаблон. Опция -v выводит все строки, не соответствующие заданной модели. Опция -w ограничивает соответствие только целыми словами. Утилита fgrep (от англ, fixed grep) осуществляет быстрый поиск, который производится только в указанных строках. Опция -х производит поиск по строкам. Утилита egrep (от англ, extended grep) использует в качестве шаблона регулярные выражения. В Приложении содержится информация о регулярных выражениях. Для получения всех строк, совпадающих с шаблоном, необходимо указать строку и имя файла, в котором следует производить поиск, непосредственно за командой grep: $ cat grepfile ...вывести файл, который следует отфильтровать. Well you know it’s your bedtime, So turn off the light, Say all your prayers and then, Oh you sleepy young heads dream of wonderful things, Beautiful mermaids will swim through the sea, And you will be swimming there too. $ grep the grepfile ...искать слово "the". So turn off the light, Say all your prayers and then, Beautiful mermaids will swim through the sea, And you will be swimming there too. $ _ Обратите внимание, что слова, которые содержат строку "the", также удовлетворяют соответствующему условию. Поэтому для вывода целых слов, совпадающих с моделью поиска, следует воспользоваться опцией -w. Опция -п нумерует строки: $ grep -wn the grepfile ...более частный случай! 2:So turn off the light, 5:Beautiful mermaids will swim through the sea, $ _ Для отображения слов, не совпавших с шаблоном, воспользуйтесь опцией -v: $ grep -wnv the grep file ...противоположный фильтр. l:Well you know it’s your bedtime, 3:Say all your prayers and then,
4:Oh you sleepy young heads dream of wonderful things, 6:And you will be swimming there too. $ _ При одновременном поиске в нескольких файлах найденные строки предваряются именем документа. В приведенном ниже примере был осуществлен поиск символа х в нескольких файлах одновременно: $ grep -w х *.с ...искать во всех файлах, заканчивающихся на .с. а.с:test (int х) fact2.с:long'factorial (х) fact2.c:int х; fact2.c: if ((x == 1) ,, (x == 0)) fact2.c: result = x * factorial (x-1); $ grep -wl x *.c ...перечислить имена соответствующих файлов. а. с fact2. с $ Утилиты fgrep, grep И egrep ПОДДерЖИВаюТ ОПЦИИ, КОТОрые МЫ ТОЛЬКО ЧТО описали. Отличие состоит в модели поиска, которую можно использовать в каждой из них. В табл. 3.2 приведены шаблоны, поддерживаемые конкретной утилитой. Таблица 3.2. Шаблоны различных утилит сортировки Утилита Вид шаблона, который может разыскиваться fgrep Только установленная строка grep Регулярное выражение egrep Расширенное регулярное выражение Регулярные выражения, используемые С утилитами grep И egrep, должны быть заключены в одиночные кавычки для отделения от других команд shell. Для лучшего понимания использования регулярных выражений с grep, egrep рассмотрим их на примере приведенного ниже текста: Well you know it’s your bedtime, So turn off the light, Say all your prayers and then, Oh you sleepy young heads dream of wonderful things, Beautiful mermaids will swim through the sea, And you will be swimming there too.
Шаблоны соответствия В табл. 3.3 и 3.4 строки, соответствующие регулярному выражению, выделены курсивом. Таблица 3.3. Шаблоны в grep grep-шаблон Строки, которые соответствуют . nd Say all your prayers and then, Oh you sleepy young heads dream of wonderful things, And you will be swimming there too. А. nd And you will be swimming there too. sw.*ng And you will be swimming there too. [А-D] Beautiful mermaids will swim through the sea, And you will be swimming there too. \ , And you will be swimming there too. а. Say all your prayers and then, Oh you sleepy young heads dream of wonderful things, Beautiful mermaids will swim through the sea, а. $ Beautiful mermaids will swim through the sea, [a-m]nd Say all your prayers and then, [Аа-т]nd • Oh you sleepy young heads dream of wonderful things, And you will be swimming there too. Таблица 3.4. Шаблоны в едгер едгер-шаблон Строки, которые соответствуют s. *w Oh you sleepy young heads dream of wonderful things, Beautiful mermaids will swim through the sea, And you will be swimming there too. s. +w Oh you sleepy young heads dream of wonderful things, Beautiful mermaids will swim through the sea, off I will So turn off the light, Beautiful mermaids will swim through the sea, And you will be swimming there too.
Таблица 3.4 (окончание) egrep-шаблон Строки, которые соответствуют im*ing And you will be swimming there too im?ing Нет совпадений Удаление одинаковых строк: uniq Утилита uniq сообщает о наличии в файле одинаковых строк. Синтаксис uniq -с -число [входнойФайл [ выходнойФайл] ] Утилита uniq выводит входной файл со всеми смежными одинаковыми строками, сокращенными до единственного вхождения повторенной строки. Если входной файл не определен, то производится чтение из стандартного ввода. Опция -с добавляет перед каждой строкой число вхождений, которые были найдены. Если определено число, то заданное число полей каждой строки игнорируется. Пример: $ cat animals ...рассмотрим тестовый файл, cat snake monkey snake dolphin elephant dolphin elephant goat elephant pig pig pig pig monkey pig $ uniq animals ...отфильтровать двойные смежные строки, cat snake monkey snake dolphin elephant goat elephant pig pig monkey pig
$ uniq -с animals ...отобразить строки с нумерацией. 1 cat snake 1 monkey snake 2 dolphin elephant 1 goat elephant 2 pig pig 1 monkey pig $ uniq -1 animals ...проигнорировать первое поле каждой строки, cat snake dolphin elephant pig pig $ Сортировка файлов: sort Утилита sort сортирует файл в лексикографическом или обратном порядке строк на основе одного или нескольких полей сортировки. Синтаксис sort -tc -г {полеСортировки-bfМп} * {имяФайла}* Утилита sort сортирует строки, отвечающие некоторому критерию, в одном или нескольких файлах. По умолчанию строки сортируются в порядке возрастания1. Опция -г устанавливает сортировку по убыванию. Строки разбиты на поля, отделенные пробелами или позициями табуляции. Для определения иного разделителя используйте опцию -t. По умолчанию сортировка производится по всем полям строки. Однако ее можно ограничить одним или несколькими полями путем задания одной или нескольких опций после команды. Опция -f заставляет утилиту sort игнорировать регистр поля. Опция -м обеспечивает сортировку поля по месяцам. Опция -п сортирует поле в числовом порядке. Опция -ь игнорирует предшествующие пробелы. Некоторые поля упорядочиваются лексикографически, это означает, что соответствующие символы сравниваются на основе их ASCII-кодов. (См. man ascii для получения списка всех символов и их соответствующих кодов.) Например, заглавная буква "меньше", чем ее строчный эквивалент, а 1 То есть в лексикографическом порядке символов этих строк. — Ред.
пробел имеет более низкий приоритет, чем какой-либо символ. Ниже приведен пример сортировки по возрастанию и убыванию: $ cat sortfile ...вывести файл, который нужно отсортировать. jan Start chapter 3 10th Jan Start chapter 1 30th Jan Start chapter 5 23rd Jan End chapter 3 23rd Mar Start chapter 7 27 may End chapter 7 17th Apr End Chapter 5 1 Feb End chapter 1 14 $ sort sortfile ...сортировать его. Feb End chapter 1 14 Jan End chapter 3 23rd Jan Start chapter 5 23rd may End chapter 7 17th Apr End Chapter 5 1 Jan Start chapter 1 30th Mar Start chapter 7 27 jan Start chapter 3 10th $ sort -r sortfile ...сортировать в обратном порядке. jan Start chapter 3 10th Mar Start chapter 7 27 Jan Start chapter 1 30th Apr End Chapter 5 1 may End chapter 7 17th Jan Start chapter 5 23rd Jan End chapter 3 23rd Feb End chapter 1 14 $ _ Для сортировки по конкретному полю необходимо задать диапазон, определив после префикса + номер стартового поля и после - номер конечного поля. Нумерация полей начинается с 0. Если не задано конечное поле, то сортируются все поля, следующие за стартовым. Сортировка по первому полю: $ sort +0 -1 sortfile ...сортировать только по первому полю. Feb End chapter 1 14 Jan End chapter 3 23rd
Jan Start chapter 5 23rd may End chapter 7 17th Apr End Chapter 5 1 Jan Start chapter 1 30th Mar Start chapter 7 27 jan Start chapter 3 10th $ Обратите внимание, что предшествующие пробелы были интерпретированы как часть первого поля, что привело к странным результатам. Логично, чтобы месяцы были отсортированы в правильном порядке — январь перед февралем и т. д. Для этого воспользуемся опцией -м, которая такую сортировку выполняет, и опцией -ь, игнорирующей лишние пробелы. $ sort +0 -1 —ЬМ sortfile ...сортировать по полю месяц. * Jan End chapter 3 23rd Jan Start chapter 5 23rd Jan Start chapter 1 30th jan Start chapter 3 10th Feb End chapter 1 14 Mar Start chapter 7 27 Apr End Chapter 5 1 may End chapter 7 17th $ _ Теперь наш файл правильно отсортирован по месяцам, однако даты все еще не в порядке. Для решения этой проблемы нужно определить несколько полей сортировки, т. к. утилита выбирает строки, отвечающие первому из заданных условий, а потом применяет к этой выборке следующие условия. Поэтому чтобы отсортировать текст по месяцу и дате, он сначала должен быть отсортирован по первому полю, а затем по пятому. Кроме того, к пятому полю должна быть применена числовая сортировка (опция -п). $ sort +0 -1 -ЬМ +4 -п sortfile jan Start chapter 3 10th Jan End chapter 3 23rd Jan Start chapter 5 23th Jan Start chapter 1 30th Feb End chapter 1 14 Mar Start chapter 7 27 Apr End Chapter 5 1 may End chapter 7 17th $
Очень часто поля отделяются друг от друга с помощью символов, отличных от пробела. Например, в файле /etc/passwd поля, содержащие информацию о пользователе, отделяются двоеточием. Для определения альтернативного разделителя воспользуйтесь опцией -t. Ниже приведен пример, разделителем полей в котором был символ двоеточие (:): $ cat sortfile2 ...посмотреть на тестовый файл. jan:Start chapter 3:10th Jan:Start chapter 1:30th Jan .-Start chapter 5:23 rd Jan:End chapter 3:23rd Mar:Start chapter 7:27 may:End chapter 7:17th Apr:End Chapter 5:1 Feb:End chapter 1:14 $ sort -t; +0 -1 -bM +2 —n sortfile2 ...двоеточие, как разделитель. jan:Start chapter 3:10th Jan:End chapter 3:23rd Jan:Start chapter 5:23rd Jan:Start chapter 1:30th Feb:End chapter 1:14 Mar:Start chapter 7:27 Apr:End Chapter 5:1 may:End chapter 7:17th $ _ Рассмотренная утилита имеет немало других опций, обсуждать которые мы не будем. Для получения информации о них пользуйтесь утилитой man. Сравнение файлов Следующие две утилиты позволяют сравнивать содержимое двух файлов: □ утилита стр ищет до нахождения первого отличающегося байта двух файлов; □ утилита diff отображает все различные и сходные элементы файлов. Тестирование на сходство: стр Утилита стр сравнивает файлы. В приведенном ниже примере сравниваются файлы ladyl, lady2, lady3: $ cat ladyl Lady of the night, ...посмотреть на первый тестовый файл.
I hold you close to me, And all those loving words you say are right. $ cat lady2 ...посмотреть на второй тестовый файл. Lady of the night, I hold you close to me, And everything you say to me is right. $ cat lady3 ...посмотреть на третий тестовый файл. Lady of the night, I hold you close to me, And everything you say to me is right. It makes me feel, I’m so in love with you. Even in the dark I see your light. $ cmp ladyl lady2 ...файлы различаются. ladyl lady 2 differ: char 48, line 3 $ cmp lady2 lady3 ...файл 2 — префикс файла 3. cmp: EOF on lady 2 $ cmp lady3 lady3 ...файлы одинаковые. $ Синтаксис cmp -Is имяФайла! имяФайла2 [смещение!] [смещение2] Утилита стр проверяет два файла на соответствие. Если имяФайла! и имяФайла2 равны, то утилита стр возвращает 0 и ничего не выводит; иначе возвращает 1 и показывает номер строки, начиная с первого несовпадающего байта. Если один файл является префиксом другого, то выводится сообщение EOF для файла, который короче. Опция -1 отображает смещение и значения всех несовпадающих байтов. Опция -s блокирует любой вывод. Дополнительные значения смещение! и смещение2 определяют стартовые значения В имяФайла! И имяФайла2, С КОТОРЫХ ДОЛЖНО начаться сравнение. Пример выполнения команды стр с опцией -1: $ стр -1 ladyl lady2 48 141 145 49 154 166 ...показывает байты, которые не совпадают.
81 145 56 82 40 12 cmp: EOF on lady2 $ ...lady2 меньше, чем ladyl. Различие файлов: diff Утилита diff сравнивает два файла и выводит на экран различия между ними. Существует три вида изменений: добавление, изменение и удаление строки. Синтаксис diff -i -Офлаг имяФайла! имя Файл а 2 Утилита diff сравнивает два файла и выводит описание их различий. Опция -i заставляет утилиту diff игнорировать регистр строк. Опция -D генерирует вывод, предназначенный для С-препроцессора (см. ниже). Результат работы утилиты выводится в зависимости от различий файлов в следующем виде. • Для добавления строки начало1 а начало2,конец2 > строки из второго файла, которые необходимо добавить к первому. Здесь начало1 — стартовая строка первого файла, начало2 — стартовая строка второго файла, конец2 — последняя строка второго файла. • Для удаления строки начало!,конец! d номерСтроки < строки первого файла, которые требуется удалить. Здесь начало 1 —- начало первого файла, конец1 — конец первого файла, номерСтроки — номер строки, начиная с которой, происходит сравнение. • Для изменения строки начало1,конец! с начало,конец2 < строки первого файла, которые должны быть заменены. > строки из второго файла, которые нужно использовать для замены Здесь начало! — стартовая строка первого файла, конец1 — конечная строка первого файла, начало2 — стартовая строка второго файла, конец2 — конечная строка второго файла.
Рассмотрим пример: $ cat ladyl ...посмотреть первый тестовый файл. Lady of the night, I hold you close to me, And all those loving words you say are right. $ cat lady2 ...посмотреть второй тестовый файл. Lady of the night, I hold you close to me, And everything you say to me is right. $ cat lady3 ...посмотреть третий тестовый файл. Lady of the night, I hold you close to me, And everything you say to me is right. It makes me feel, I’m so in love with you. Even in the dark I see your light. $ cat lady4 ...посмотреть четвертый тестовый файл. Lady of the night, I’m so in love with you. Even in the dark I see your light. $ diff ladyl lady2 ...сравнить ladyl и lady2. 3c3 < And all those loving words you say are right. > And everything you say to me is right. $ diff lady2 lady3 ...сравнись lady2 и lady3. 3a4,6 > It makes me feel, > I’m so in love with you. > Even in the dark I see your light. $ diff lady3 lady4 ...сравнить lady3 и lady4. 2,4dl < I hold you close to me, < And everything you say to me is right. < It makes me feel, $ _ Опция -d утилиты diff полезна для соединения двух файлов и записи их в отдельный файл, содержащий директивы препроцессора С. Каждая версия
файла может быть восстановлена с помощью компилятора сс с подходящими опциями и макроопределениями. Например: $ diff -Dflag lady3 lady4 ...посмотреть вывод. Lady of the night, ttifndef flag ...директива препроцессора. I hold you close to me, And everything you say to me is right. It makes me feel, ttendif flag ...директива препроцессора. I’m so in love with you. Even in the dark I see your light. $ diff -Dflag lady2 lady4 > lady.diff ...сохранить вывод. $ cc ~P lady.diff ...вызвать препроцессор. $ cat lady.i ...посмотреть вывод. Lady of the night, I hold you close to me, And everything you say to me is right. $ cc -Dflag -P lady.diff ...посмотреть другую версию. $ cat lady.i ...посмотреть вывод. Lady of the night, I’m so in love with you. Even in the dark I see your light. $ Поиск файлов: find Утилита find имеет гораздо больше возможностей, чем простой поиск заданного файла. Она выполняет действия над группой файлов, удовлетворяющих определенным условиям. Например, вы можете использовать утилиту find, чтобы удалить все файлы, принадлежащие пользователю tim, которые не изменялись в течение трех дней. Работа и синтаксис этой команды подробно описана в табл. 3.5. Синтаксис find списокПути выражение Утилита find рекурсивно проходит через списокПути И применяет выражение к каждому файлу.
Таблица 3.5. Синтаксис утилиты find Выражение Описание -name образец Возвращаемое значение равно 1, если имя файла соответствует образцу, который может включать метасимволы shell *, [,] и ? -perm oct Истинно, если восьмеричное описание флагов полномочий файла точно равно oct -тип ch Истинно, если тип файла — ch (b — блок, с — символ, и т. д.) -user Ю_пользователя Истинно, если владелец файла — Ю_пользователя -group 10_группы Истинно, если группа файла — 10_труппы -atime количествоДней Истинно, если к файлу обращались в течение количествоДней -mtime количествоДней Истинно, если содержимое файла изменялось в течение количествоДней -ctime количествоДней Истинно, если содержимое файла было изменено в течение количествоДней или если любой из атрибутов файла был изменен -exec команда Истинно, если код возврата от выполнения команда — 0. Команда должна заканчиваться \;. Если вы определяете {}, как аргумент строки команды, он заменяется именем текущего файла -print Распечатывает имя текущего файла и возвращает истину -Is Показывает атрибуты текущего файла и возвращает 1 -cpio устройство Пишет текущий файл в формате cpio на устройство и возвращает 1 !выражение Возвращает логическое отрицание выражение выражение1 [ - а ] выражение2 Если выражение! ложно, возвращает 0, и величину выражение2 не выполняется. Если выражение! истинно, возвращает величину выражение2 выражение 1 [-о] выражение2 Если выражение! истинно, возвращает истину. Если выражение! ложно, возвращает величину выражение2 Рассмотрим примеры работы утилиты find: $ find . -name r*.c' -print ...распечатать исходные С-файлы ...из текущего каталога или любого ...из его подкаталогов.
./proj/fall.89/play.с ./proj/fall.89/referee.c ./proj/fall.89/player.c ./госк/guess.c ./госк/play.c ./rock/player.c ./rock/referee.c $ find. . -mtime 14 -Is ...вывести файлы, модифицированные ...в течение последних 14 дней. -rw-r—г— 1 glass cs 14151 May 1 16:58 ./stty.txt -rw-r—г— 1 glass cs 48 May 1 14:02 ./myFile.doc -rw-r—г— 1 glass cs 10 May 1 14:02 ./rain.doc -rw-r—г— 1 glass cs 14855 May 1 16:58 ./tset.txt -rw-r—г— 1 glass cs 47794 May 2 10:56 . /mail.txt $ find . -name '*.bak' -Is -exec rm {} \; ...вывести и затем удалить все файлы, ...которые заканчиваются на .bak. -rw-r—г— 1 glass cs 9 May 16 12:01 ./a.bak -rw-r—r— 1 glass cs 9 May 16 12:01 ./b.bak -rw-r—r— 1 glass cs 15630 Jan 26 00:14 ./s6/gosh.bak -rw-r—r— 1 glass cs 18481 Jan 26 12:59 .7s6/gosh2.bak $ find . \f -name '*.c' -o -name txt' \) -print ...напечатать имена всех файлов, которые ...заканчиваются на .с или .txt. ./proj/fall.89/play.с ./proj/fall.89/referee.c ./proj/fall.89/player.c ./rock/guess.c ./rock/play.c ./rock/player.c ./rock/referee.c ./stty.txt ./tset.txt ./mail.txt $ Архивы Существует, как минимум, несколько причин, по которым необходимо сохранять файлы на дискеты или ленты: □ для ежедневного, еженедельного или ежемесячного резервирования (backup):
□ для переноса между несоединенными сетью UNIX-системами; П для будущих поколений. В UNIX существуют три утилиты, позволяющие архивировать файлы, каждая из которых имеет собственные сильные и слабые стороны. П Утилита cpio позволяет сохранять структуру каталога в одинарный резервный том. Удобна для сохранения небольших объемов данных, т. к. создание единственного тома делает его бесполезным для архивации больших массивов данных. □ Утилита tar предоставляет возможность сохранять структуры каталогов в одинарный резервный том. Специально разработана для сохранения файлов на ленту, поскольку она всегда архивирует файлы в конец носителя данных. Недостатком этой утилиты также является ограничение на создание одного тома. П Утилита dump обеспечивает сохранение файловой системы во множественные резервные тома. Специально разработана для выполнения полных и инкрементных резервных копирований, но восстановление отдельных файлов из архива с ее помощью достаточно трудоемко. Примечание Во многих системах, основанных на версии System V UNIX, существует программа uf sdump, эквивалентная утилите dump. Копирование файлов: cpio Утилита cpio позволяет создавать и восстанавливать из архивов файлы специального cpio-формата. Она очень эффективна для создания небольших архивов. К сожалению, утилита cpio не может разбивать файлы на несколько томов, поэтому весь архив должен помещаться на носитель данных. Если ЭТО НевОЗМОЖНО, ВОСПОЛЬЗуЙТеСЬ УТИЛИТОЙ dump. Синтаксис cpio -ov cpio -idtu шаблоны cpio -pl каталог Утилита cpio позволяет архивировать файлы. Опция -о берет список имен файлов со стандартного входа и создает файл формата cpio, который содержит резервную копию файлов с этими именами. Опция -v предписывает выводить имя каждого файла после копирования. Опция -i
читает файл cpio-формата из стандартного входа и воссоздает все файлы из входного канала, имена которых соответствуют указанному образцу. По умолчанию старые файлы не переписываются вместо более новых. Опция -и вызывает безоговорочное копирование. Опция -d создает каталоги, если они необходимы в течение процесса копирования. Опция -t показывает оглавление вместо выполнения копирования. Опция -р берет список имен файлов со стандартного входа и копирует содержимое файлов в указанный каталог. Данная опция полезна для копирования подкаталогов в другое место, хотя в большинстве случаев проще это сделать воспользовавшись утилитой ср с опцией -г. Опция -1 создает связи вместо создания физических копий. Чтобы продемонстрировать опции -о и -i, была создана резервная версия всех исходных С-файлов в рабочем каталоге и удалены исходные файлы, а затем восстановлены из архива. Действия, необходимые для выполнения этой задачи: $ Is -1 *.с ...вывести файлы, которые должны быть сохранены. -rw-r—r— 1 glass 172 Jan 5 19:44 mainl.c -rw-r—r— 1 glass 198 Jan 5 19:44 main2.c -rw-r—r— 1 glass 224 Jan 5 19:44 paliridrome.c -rw-r—r— 1 glass 266 Jan 5 23:46 reverse.c $ Is * .C / cpio -ov > backup ...сохранить в backup. 'ma ini.с main2.с palindrome.с reverse.с 3 blocks $ Is -1 backup ...просмотреть backup. -rw-r—г— 1 glass 1536 Jan 9 18:34 backup $ rm * .c ...удалить исходные файлы. $ cpio -it < backup ...восстановить файлы, mainl.c main2.c palindrome.c reverse.c 3 blocks $ Is -1 *.c ...подтвердить их восстановление, -rw-r—г— 1 glass 172 Jan 5 19:44 mainl.c -rw-r—r— 1 glass 198 Jan 5 19:44 main2.c
-rw-r—г— 1 glass 224 Jan 5 19:44 palindrome.с -rw-r—г— 1 glass 266 Jan 5 23:46 reverse.c $ _ Чтобы создать резервную копию всех файлов, включая подкаталоги, которые соответствуют образцу *.с, используют выход утилиты find как вход для утилиты cpio. Опция -depth утилиты find рекурсивно ищет соответствие шаблонам. В представленном ниже примере обратите внимание на символ обратной косой черты перед * в аргументе опции name. Это сделано для того, чтобы он не был воспринят shell как символ расширения: $ find. . -name \*.с -depth -print / cpio -ov > backup2 ma ini. c main2. c palindrome.c reverse.c tmp/b.c tmp/a. c 3 blocks $ rm -г *.c ...удалить исходные файлы. $ rm tmp/*.c ...удалить файлы нижнего уровня. $ cpio -it < backup2 . . .восстановить файлы. maini.с main2.с palindrome.с reverse.с tmp/b.с tmp/a. с 3 blocks $ _ Чтобы ПОНЯТЬ работу ОПЦИИ -р, воспользуемся УТИЛИТОЙ find для получения списка всех файлов текущего каталога, которые были изменены в последние два дня, и затем скопируем эти файлы в родительский каталог. Без использования опции -1 файлы будут физически скопированы, что увеличит объем занятого дискового пространства на 153 блока. Однако использование опции -1 создало ссылки на файлы и никак не отразилось на размере свободного пространства. Рассмотрим пример: $ find . -mtime -2 -print / cpio -p.........скопировать 153 блоков. $ Is -1 ../reverse.с ...посмотреть скопированные файлы. -rw-r—г— 1 glass 266 Jan 9 18:42 ../reverse.с $ find . -mtime -2 -print / cpio -pl........связать 0 блоков.
$ Is -1 ../reverse.с ...посмотреть связанные файлы. -rw-r—г— 2 glass 266 Jan 7 15:26 ../reverse.с $ _ Архивация на ленту: tar Утилита tar была специально разработана для создания архивов файлов на магнитной ленте. При добавлении файла к файлу архива с использованием утилиты tar файл всегда помещается в конце файла архива, поскольку нет возможности изменять середину файла, сохраненного на ленте. Если вы не архивируете файлы на ленту, лучше вместо утилиты tar использовать утилиту cpio. Синтаксис tar -cfrtuvx [Ёаг_имяФайла] списокФашюв Утилита tar позволяет создавать и получать доступ к специальным файлам архива в формате tar. Опция -с создает файл tar-формата. По умолчанию имя файла tar-формата — /dev/rmtO. (Оно может измениться в различных версиях UNIX.) Однако значение по умолчанию разрешено переопределить путем установки переменной окружающей среды $таре или с помощью опции -f, сопровождаемой необходимым именем файла. Опция -v вызывает многословный вывод. Опция -х позволяет извлекать указанные файлы, а опция -t генерирует оглавление. Опция -г безусловно добавляет перечисленные файлы к файлу архива. Опция —и добавляет последние версии имеющихся в архиве файлов. Если в аргументе списокФайлов указаны имена каталогов, содержимое каталогов добавляется или извлекается рекурсивно. В следующем примере показано, что все файлы из текущего каталога сохраняются в файле архива tarfile: $ Is ...просмотреть текущий каталог. mainl* main2 palindrome.с reverse.h mainl. c main2.c palindrome.h tarfile mainl.make main2.make reverse.c tmp/ $ Is tmp ...посмотреть каталог tmp. a.c b.c $ tar -cvf tarfile . ...архивировать текущий каталог. a ./mainl.с 1 blocks
а ./main2.с 1 blocks а ./main2 48 blocks a ./tmp/b.c 1 blocks а ./tmp/а.с 1 blocks $ Is -1 tarfile ...посмотреть архивный файл tarfile. -rw-r—г— 1 glass 65536 Jan 10 12:44 tarfile $ _ Чтобы получить оглавление tar-архива, используйте опцию -t, как показано в следующем примере: $ tar -tvf tarfile ...посмотреть оглавление. rwxr-xr-x 496/62 0 Jan 10 12:44 1998 , / rw-r—r— 496/62 172 Jan 10 12:41 1998 ./mainl.c rw-r—r— 496/62 198 Jan 9 18:36 1998 ./main2.c rw-r—r— 496/62 24576 Jan 7 15:26 1998 . /main2 rwxr-xr-x 496/62 0 Jan 10 12:42 1998 ./tmp/ rw-r—r— 496/62 9 Jan 10 12:42 1998 ./tmp/b.c rw-r—r— 496/62 9 Jan 10 12:42 1998 ./tmp/а.c $ _ Для безусловного добавления файла в конец tar-архива используйте опцию -г, сопровождаемую списком файлов или каталогов. Заметьте, что в следующем примере tar-архив содержит в конце две копии reverse.c: $ tar -rvf tarfile reverse.c a reverse.c 1 blocks ...безусловное добавление. $ tar -tvf tarfile ...посмотреть оглавление. rwxr-xr-x 496/62 0 Jan 10 12:44 1998 , / rw-r—r— 496/62 172 Jan 10 12:41 1998 ./mainl.с rw-r—r— 496/62 266 Jan 9 18:36 1998 ./reverse.c rw-r—r— 496/62 266 Jan 10 12:46 1998 reverse.с $ _ Чтобы добавить файл только тогда, когда он отсутствует в архиве или был изменен со времени последнего архивирования, используйте опцию -и вместо -г. В следующем примере обратите внимание, что файл reverse.c не был заархивирован, потому что не изменялся: $ tar -rvf tarfile reverse.c ...безусловное добавление. a reverse.c 1 bloc.ks $ tar -uvf tarfile reverse.c ...условное добавление. $
Чтобы извлечь файл из файла архива, используйте опцию -х, сопровождаемую списком файлов или каталогов. Если имя каталога определено, он рекурсивно извлекается, как показано в следующем примере: $ rm tmp/* ...удалить все файлы из tmp. $ tar -vxf tarfile ./tmp ...извлечь архивированные tmp-файлы. x ./tmp/b.с, 9 bytes, 1 tape blocks x ./tmp/а.c, 9 bytes, 1 tape blocks $ Is tmp ...подтвердить восстановление. a. c b. с $ _ К сожалению, утилита tar не поддерживает соответствие шаблону списка имен. Таким образом, чтобы извлечь файлы, которые соответствуют конкретному шаблону, используют утилиту grep, как часть командной последовательности: $ tar -xvf tarfile 'tar -tf tarfile / grep x ./mainl.c, 172 bytes, 1 tape blocks x ./main2.c, 198 bytes, 1 tape blocks x ./palindrome.c, 224 bytes, 1 tape blocks x ./reverse.c, 266 bytes, 1 tape blocks x ./tmp/b.c, 9 bytes, 1 tape blocks x ./tmp/а.c, 9 bytes, 1 tape blocks $ Если вы перемещаетесь в другой каталог, а затем извлекаете файлы, которые были сохранены, используя относительные имена пути, имена интерпретируются относительно текущего каталога. В следующем примере восстанавливается файл reverse.c из предварительно созданного tar-файла в новый каталог tmp2: $ mkdir tmp2 ...создать новый каталог. $ cd tmp2 ...переместиться туда. $ tar -vxf ../tarfile reverse.c ...восстановить один файл. х reverse.c, 266 bytes, 1 tape blocks x reverse.c, 266 bytes, 1 tape blocks $ is -1 . ..подтвердить восстановление, total 1 -rw-r—r— 1 glass 266 Jan 10 12:48 reverse.c $ Обратите внимание, что каждая копия файла reverse.c записалась, поверх предыдущей, поэтому самая последняя версия была оставлена неповрежденной.
Инкрементальные резервные копирования: dump и restore Утилиты dump и restore пришли из версии Berkeley UNIX, но были добавлены в большинство других версий. (Во многих системах, базирующихся на версии System V UNIX, они называются ufsdump и ufsrestore.) Вот типичная стратегия системного администратора для резервного копирования: □ выполнять еженедельное резервное копирование всей файловой системы; □ выполнять ежедневное инкрементное резервное копирование, сохраняя только те файлы, которые были изменены со времени последнего резервного копирования. Этот вид резервной стратегии точно поддержан утилитами dump и restore. Синтаксис dump [уровень] [f дампФайл] [v] [w] файловаяСистема dump [уровень] [f дампФайл] [v] [w] {имяФайла} + Утилита dump имеет две формы. Первая форма копирует файлы из указанной файловой системы в дампФаил, которым по умолчанию является /dev/rmtO. (Имя может изменяться в различных версиях UNIX.) Если параметр уровень определен как п, то копируются все файлы с более низким уровнем, чем л, при условии, что они были изменены после последнего дампа. Например, уровень дампа 0 всегда обеспечивает выполнение дампа всех файлов, тогда как уровень дампа 2 выполнит дамп всех измененных файлов, начиная с последнего дампа уровня 0 или уровня 1. Если никакой уровень дампа не определен, уровень дампа равен 9. Опция v предписывает утилите dump проверять каждый том носителя после того, как он записан. Опция w обеспечивает демонстрацию списка всех файловых систем, над которыми должен быть выполнен дамп вместо выполнения резервного копирования. Вторая форма утилиты dump позволяет задать имена файлов, которые нужно сохранить. Обе формы напоминают пользователю, когда необходимо вставить или удалить носитель дампа. Например, большой дамп системы на ленточное устройство часто требует, чтобы оператор удалил заполненную ленту и заменил ее пустой. Когда дамп выполнен, информация о нем записывается в файл /etc/dumpdates для использования в будущем при вызове утилиты dump.
Приведем пример, который выполняет дамп с проверкой уровня 0 файловой системы /dev/daO на ленточный накопитель /dev/rmtO: $ dump 0 fv /dev/rmtO /dev/daO Утилита restore позволяет восстанавливать файлы из резервной копии, выполненной утилитой dump. Синтаксис restore -irtx [f дампФайл] {имяФайла}* Утилита restore позволяет восстанавливать набор файлов из предыдущего дампФайла. Если дампФайл не определен, по умолчанию используется /dev/rtmO. (Имя может быть иным в других версиях UNIX.) Опция -г заставляет каждый файл из дампФайла восстанавливаться в текущий каталог, поэтому используйте эту опцию осмотрительно. Опция -t вместо восстановления файлов осуществляет ВЫВОД оглавления дампФайла. Опции -х служит для восстановления только файлов с указанными имена-миФайлов ИЗ дампФайла. ЕСЛИ имяФайла — ЭТО ИМЯ Каталога, еГО СОДерЖИ-мое восстанавливается рекурсивно. Опция -i предписывает утилите restore читать оглавление дампФайла и затем входить в диалоговый режим, который позволяет пользователю выбирать файлы для восстановления. Для получения дополнительной информации об этом диалоговом режиме обращайтесь за справкой — man restore. В следующем примере используется утилита restore, чтобы извлечь пару предварительно сохраненных файлов с дампа устройства /dev/rmtO: $ restore -х f /dev/rmtO wine.с hacking.с Планирование выполнения команд Представленные ниже две утилиты позволяют планировать команды, которые будут выполнены в более позднее время. □ Утилита crontab позволяет создать расписание, описывающее ряд работ, которые будут выполняться периодически. □ Утилита at предоставляет возможность планировать работы, которые будут выполнены однократно.
Периодическое выполнение: cron/crontab Утилита crontab позволяет запланировать ряд работ, которые будут выполняться периодически. Синтаксис crontab сгопЬаЬИмя crontab -ler [имяПользователя] Утилита crontab обеспечивает пользовательский интерфейс в системе UNIX. Когда она указывается без опций, crontab-файл cront-аьимя регистрируется, и его команды выполняются согласно указанным правилам выбора времени. Опция -1 выводит содержимое зарегистрированного crontab-файла. Опция -е редактирует и затем регистрирует crontab-файл. Опция -г отменяет регистрацию зарегистрированного crontab-файла. Опции -1, -е и -г может использовать привилегированный пользователь (root), чтобы получить доступ к crontab-файлу другого пользователя, добавляя имя пользователя как дополнительный аргумент. Содержимое crontab-файла описан ниже. Итак, ЧТОбы ИСПОЛЬЗОВаТЬ УТИЛИТУ crontab, вы должны подготовить входной crontab-файл, который содержит строки в формате: Минута Час День Месяц День_недели Команда Таблица 3.6. Значения полей для входного файла утилиты cron tab Поле Допустимое значение Минута 0-59 Час 0-23 День 1-31 Месяц 1-12 День_недели 1—7 (1 — понедельник, 2 — вторник, 3 — среда, 4 — четверг, 5 — пятница, 6 — суббота, 7 — воскресенье) Команда Любая команда UNIX Всякий раз, когда текущее время совпадает с описанным в строке, shell, указанный в переменной окружающей среды shell, выполняет ассоциированную команду. Если эта переменная не установлена, то используется
Bourne shell. Если любое из первых пяти полей содержит звездочку (*) вместо числа, то значение этих полей считается произвольным. Стандартный вывод команды автоматически посылается пользователю через утилиту mail. Любые символы после символа % копируются во временный файл и используются как стандартный вход команды. Ниже представлен образец crontab-файла с именем crontab.cron, который создан в пользовательском домашнем каталоге: $ cat cron tab. cron 0 8**1 Jr ★ Jr ★ Jr 30 14 1 * 1 $ ...вывод crontab-файла. echo Радостного утра понедельника echo Одна минута прошла > /dev/ttyl mail users % Jan Meeting At 3pm Первая строка отправляет сообщение "Радостного утра понедельника" в 8:00 каждый понедельник. Следующая строка выводит каждую минуту строку "Одна минута прошла" на устройство /dev/ttyl, которое играет роль терминала. Последняя строка посылает почту всем пользователям 1 января в 14:30, чтобы напомнить им о предстоящей встрече. Отдельный процесс, называемый cron, ответствен за своевременное выполнение команд в зарегистрированных crontab-файлах. Процесс запускается, когда UNIX-система загружается, и не останавливается, пока с ОС UNIX не будет завершена работа. Копии всех зарегистрированных crontab-файлов сохраняются в каталоге /var/spool/cron/crontabs. Чтобы зарегистрировать crontab-файл, используйте утилиту cron tab с именем crontab-файла в качестве единственного аргумента: $ crontab cron tab.cron ...зарегистрировать crontab файл. $ _ Если у вас уже есть зарегистрированный crontab-файл, новый регистрируется вместо старого. Чтобы просмотреть содержимое вашего зарегистрированного crontab-файла, используйте опцию -1. Чтобы посмотреть чей-нибудь еще зарегистрированный crontab-файл, добавьте имя пользователя в качестве аргумента. Эту опцию может использовать только привилегированный пользователь (root). В представленном ниже примере один из предварительно зарегистрированных crontab-файлов был вызван по совпадению времени после запуска ути- ЛИТЫ crontab: $ crontab -1 ...вывод содержимого текущего crontab-файла. 08**1 echo Радостного утра понедельника * * * * * echo Одна минута прошла > /dev/ttyl 30 14 1 * 1 mail users % Jan Meeting At 3pm
$ Одна минута прошла ...вывод одной из crontab-команд. $ _ Для редактирования crontab-файла и его сохранения используют опцию -е. Чтобы отменить регистрацию crontab-файла, используйте опцию -г: $ crontab -г ... отменить регистрацию crontab-файла. $ _ Привилегированный пользователь (root) может создавать файлы cron.allow и cron.deny в каталоге /var/spool/cron, чтобы разрешить и запретить индивидуальным пользователям применять crontab-средства. Каждый файл состоит из списка пользовательских имен: один пользователь на одной строке. Если этих файлов нет, то только привилегированный пользователь может запускать утилиту crontab. Если файл cron.deny пуст, а файл cron.allow не существует, все пользователи могут работать с утилитой crontab. Однократное выполнение: at Утилита at позволяет запланировать однократные команды или скрипты. Синтаксис at -csm время [дата [, под]][+ приращение] [скрипт] at -г {ID_задания} + at -1 {ID—задания} ★ Утилита at позволяет запланировать однократные команды или скрипты. Она поддерживает гибкий формат для задания времени. Опции -с и -s указывают, что команды будут выполняться соответственно С shell или Bourne shell. Опция -m предписывает утилите at послать вам почту, когда задание будет закончено. Если имя скрипта не определено, утилита at воспринимает список команд со стандартного входа. Опция -г удаляет указанные задания из очереди, а опция -1 выводит список заданий, находящихся в списке. Задание удаляется из очереди после ее выполнения. Аргумет время имеет формат нн или ннмм с необязательным спецификатором до полудня — дм, после полудня — рм, а дата записывается с указанием первых трех символов дня или месяца. Ключевое слово now (сейчас) может применяться вместо задания времени. Ключевые слова today (сегодня) и tomorrow (завтра) могут использоваться вместо даты. Если дата не определена, то вступают в силу следующие правила: • если время больше текущего времени, то предполагается дата today; • если время установлено меньше текущего времени, то предполагается дата — tomorrow.
Заявленное время может быть увеличено приращением — числом, следующим за аргументами время, дата, год. Скрипт выполняется командным интерпретатором shell, указанным в переменной окружающей среды shell, или Bourne shell, если эта переменная не установлена. Весь стандартный вывод от скрипта отправляется по почте пользователю. В следующем примере предусмотрено выполнение скрипта для передачи сообщения на терминал /dev/ttyl: $ cat at.csh ...посмотреть скрипт, который будет выполняться. #! /bin/csh echo at done > /dev/ttyl ...echo-вывод на терминал. $ date ...посмотреть текущее время. Sat Jan 10 17:27:42 CST 1998 $ at now + 2 minutes at.csh ...включить в расписание скрипт ...для выполнения через 2 минуты job 2519 at Sat Jan 10 17:30:00 1998 $ at -1 ...посмотреть расписание. 2519 a Sat Jan 10 17:30:00 1998 $ _ at done ...вывод выполненного скрипта. $ at 17:35 at.csh ...снова внести скрипт в расписание, job 2520 at Sat Jan 10 17:35:00 1998 $ at -г 2520 ...исключить из расписания. $ at -1 ...посмотреть расписание. $ _ Приведем несколько примеров правильных форматов времени для утилиты at: 0934am Sep 18 at.csh 9:34 Sep 18 , 1994 at.csh 11:00pm tomorrow at.csh now + 1 day at.csh 9pm Jan 13 at.csh 10pm Wed at.csh Если имя команды пропускается, утилита at выводит подсказку и ждет список команд, которые должны быть введены со стандартного входа. Для того чтобы закончить список команд, нажмите комбинацию клавиш <Ctrl>+<D>. Пример: $ at 8pm ...ввод команд для внесения в расписание с клавиатуры. at> echo at done > /dev/ttypl
at> ... конец ввода. job 2530 at Sat Jan 10 17:35:00 1998 $ _ Вы можете запрограммировать скрипт, чтобы он сам себя перепланировал путем вызова утилиты at внутри скрипта: $ cat at.csh ...скрипт, который перепланирует сам себя. #! /bin/csh date > /dev/ttyl # Reschedule script at now + 2 minutes at.csh $ _ Привилегированный пользователь (root) может создавать файлы at.allo и at.deny в каталоге /var/spool/cron, чтобы разрешить и запретить индивидуальным пользователем применять at-средства. Каждый файл состоит из списка пользовательских имен: один пользователь на одной строке. Если этих файлов нет, то только привилегированный пользователь может запускать утилиту at. Если файл at.den пуст, а файл at.allow не существует, все пользователи могут работать с утилитой at. Программируемая обработка текста: awk Утилита awk просматривает один или несколько файлов и исполняет действие на всех строках, которые соответствуют конкретному условию. Действия и условия описаны в программе awk и расположены от простого к сложному. Утилита awk получила свое имя от объединения первых символов фамилий его авторов: Ахо (Aho), Венбергер (Weinberger) и Керниган (Kernighan). Она заимствует свои структуры управления и синтаксис выражений из языка С. Если вы уже знаете С, то изучение awk не вызовет затруднений. awk — это комплексная утилита, настолько всеобъемлющая, что фактически существует книга, посвященная ей! Поэтому в данной главе описаны лишь главные особенности и опции awk. Однако хочется надеяться, что приведенный в этом разделе материал позволит вам писать большое количество полезных awk-приложений. Синтаксис awk -Fc [-f имяФайла] программа {переменная=значение} * {имяФайла}* awk — программируемая утилита обработки текста, которая просматривает строки своего входа и исполняет действия на каждой строке, соответст
вующей определенному критерию. Программа awk может быть включена в командную строку. В этом случае она должна быть окружена апострофами. Альтернативно она может быть задана с использованием опции -f, а ее вызов сохранен в файле. Начальные значения переменных могут быть заданы в командной строке. По умолчанию разделители полей — это символы табуляции и пробел. Чтобы переопределить значения по умолчанию, используйте опцию -г, сопровождаемую новым разделителем полей. Если имяФайла не определено, утилита awk читает со стандартного входа. awk-программы awk-программа может быть задана в командной строке. Но более общий способ состоит в том, чтобы поместить ее вызов в текстовый файл и специфицировать файл, используя опцию -г. Если вы решили разместить awk-программу в командной строке, окружите ее апострофами. Когда утилита awk читает строку, она разбивает ее на поля, которые разделены символами табуляции или пробелами. Разделитель полей может быть переопределен путем использования опции -f, как вы увидите позже в этом разделе, awk-программа — это список из одной или нескольких команд в формате [ условие ] [ \ {действие\} ] где условие — это: □ либо специальная лексема begin или end; П либо выражение, включающее любую комбинацию логических операторов, операторов отношений и регулярных выражений, а действие — это список из одного или большего количества С-подобных операторов, заканчивающихся точкой с запятой и имеющих следующий вид: П if (условие) оператор [else оператор] □ while (условие) оператор Л for (выражение; условие; выражение) оператор П break О continue П переменная=выражение О print [список выражений] [> выражение] П printf формат [,список выражений] [> выражение] □ next (перескакивает оставшиеся шаблоны на текущей строке ввода) П exit (перескакивает остаток текущей строки) П {список операторов}
Действие выполняется для строк, которые соответствует условию. Если условие отсутствует, действие выполняется на каждой строке. Если действие отсутствует, то все строки, соответствующие условию, просто посылаются на стандартный вывод. Операторы в awk-программе могут иметь отступ и быть отформатированы с использованием пробелов, символов табуляции и перевода строки. Доступ к отдельным полям К первому полю текущей строки можно обращаться, указав $1, второй $2, и т. д. $о обозначает строку целиком. Встроенная переменная nf равна числу полей в текущей строке. В следующем примере выполняется простая awk-программа на текстовом файле float, чтобы вставить число полей в каждую строку: $ cat float ...посмотреть оригинальный файл. Wish I was floating in blue across the sky, My imagination is strong, And I often visit the days When everything seemed so clear. Now I wonder what I’m doing here at all... $ awk '{print NF, $0}' float ...выполнить команду. 9 Wish I was floating in blue across the sky, 4 My imagination is strong, 6 And I often visit the days 5 When everything seemed so clear. 9 Now I wonder what I’m doing here at all... $ В EG IN и END Специальная конструкция begin вызывается прежде, чем читается первая строка, а специальная конструкция end — после того, как последняя строка была прочитана. Когда выражения перечисляются в операторе печати, между ними не выводятся пробелы, а по умолчанию печатается символ перевода строки. Встроенная переменная filename равна имени входного файла. В следующем примере представлено управление программой, которая выводила первое, третье и последнее поля каждой строки: $ cat awk2 ...посмотреть скрипт awk. BEGIN { print "Start of file:’’, FILENAME } { print $1 $3 $NF } ...печатать 1-е, 3-е и последнее поля. END { print "End of file" }
$ awk -f awk float ...выполнить скрипт. Start of file: float Wishwassky, Myisstrong, Andof tendays Whenseemedclear. Nowwonderall... End of file $ Операторы Когда в операторе печати между выражениями помещаются запятые, пробел печатается. Все обычные операторы С доступны в awk. Встроенная переменная nr содержит номер текущей строки. В следующем примере должна выполняться программа, которая выводит первые, третьи и последние поля строк 2 и 3 из файла float: $ cat awk3 ...посмотреть скрипт awk. NR > 1 && NR < 4 { print NR, $1, $3, $NF } $ awk -f awk3 float ...выполнить скрипт. My is strong, And often days $ Переменные Утилита awk поддерживает определенные пользователем переменные. Нет необходимости объявлять переменную. Ее начальное значение — это пустая строка или ноль, в зависимости от того, как вы используете переменную. В представленном ниже примере программа должна подсчитывать число строк и слов в файле по мере того, как она будет выводить строки на стандартный вывод: $ cat awk4 ...посмотреть скрипт awk. BEGIN { print "Scanning file" } printf "line %d: %s\n", NR, $0; lineCount++; wordCount += NF; END { printf "lines = %d, words = %d\n", lineCount, wordCount }
$ awk -f awk4 float ...выполнить скрипт. Scanning file line 1: Wish I was floating in blue across the sky, line 2: My imagination is strong, line 3: And I often visit the days line 4: When everything seemed so clear. line 5: Now I wonder what I’m doing here at all... lines = 5, words = 33 $ Структуры управления Утилита awk поддерживает большинство стандартных структур управления С. В следующем примере печатаются поля каждой строки в обратном порядке: $ cat awk5 ...посмотреть скрипт awk. { for (i = NF; i >= 1; i—) printf "%s ", $i; printf "\n"; } $ awk -f awk5 float ...выполнить скрипт, sky, the across blue in floating was I Wish strong, is imagination My days the visit often I And clear, so seemed everything When all... at here doing I’m what wonder I Now $ Расширенные регулярные выражения Условия для соответствия строкам могут быть расширенными регулярными выражениями, которые определяются в Приложении. Допустимые выражения должны быть помещены между косыми чертами (/). В следующем примере происходит вывод всех строк, которые содержат строки, начинающиеся с буквы t и заканчивающиеся буквой е, с любым числом символов между ними (для ясности последовательность символов выходных строк, которые удовлетворили условию, выделена курсивом): $ cat awk6 /t.*e/ { print $0 } ...посмотреть скрипт.
$ awk -f awk6 float ...выполнить скрипт. Wish I was floating in blue across the sky, And I often visit the days When everything seemed so clear. Now I wonder what I'm doing here at all... $ _ Цепочки условий Условием могут быть два выражения, разделенные запятой. В этом случае awk исполняет действие на каждой строке от первой строки, которая соответствует первому условию, до строки, удовлетворяющей второму условию, как показано в следующем примере: $ cat awk7 ...посмотреть скрипт. /strong/ , /clear/ { print $0 } $ awk -f awk7 float ...выполнить скрипт. My imagination is strong, And I often visit the days When everything seemed so clear. $ _ Разделители полей Если разделители полей — не пробелы, используют опцию -F, чтобы задать символ-разделитель. В следующем примере обрабатывается файл, поля которого разделялись двоеточиями: $ cat awk3 ...посмотреть скрипт awk. NR > 1 && NR < 4 {print $1, $3, $NF} $ cat float2 ...посмотреть входной файл. Wish:I:was:floating:in:blue:across:the:sky, My: imagination:is:strong, And:I:often:visit:the:days When:everything:seemed:so:clear. Now:I:wonder:what:I’m:doing:here:at:all... $ awk -F: -f awk3 float2 ...выполнить скрипт. My is strong, And often days $ 6 Зак. 786
Встроенные функции Утилита awk поддерживает несколько встроенных функций, включая expo, logo, sqrt о, into и substr о. Первые четыре функции работают точно так же как их стандартные двойники С. Функция substr (str, х, у) возвращает подстроку строки str, начиная от символа в позиции от х, длиной у символов. Ниже приведен пример работы и вывод этих функций: $ cat test ...посмотреть входной файл. 1.1 а 2.2 at 3.3 eat 4.4 beat $ cat awk8 ... посмотреть скрипт awk. printf "$1 = %g ", $1; printf "exp = %.2g ", exp ($1); printf "log = %.2g ", log ($1); printf "sqrt = %.2g ", sqrt ($1); printf "int = %d ", int ($1); printf "substr (%s, 1, 2) = %s\n", $2, substr($2, 1, 2); $ awk -f awk8 test ...выполнить скрипт. $1 = 1.1 exp = 3 log = = 0.095 sqrt = 1 int = 1 substr (a, 1, 2) = a $1 = 2.2 exp - 9 log = = 0.79 sqrt = 1.5 int = 2 substr (at, 1, 2} I = at $1 = 3.3 exp = 27 log =1.2 sqrt = 1.8 int = 3 substr (eat, It 2) = ea $1 = 4.4 exp =81 log =1.5 sqrt =2.1 int = 4 substr (beat, 1, 2) = be $ Жесткие и символические связи: In Утилита in позволяет создавать как жесткие связи, так и символические связи между файлами. Синтаксис In -sf оригинал [новаяСвязь] In -sf {оригинал} + каталог Утилита in позволяет создавать жесткие или символические связи к существующим файлам.
Чтобы создать жесткую связь между двумя нормальными файлами, определите существующую метку файла, как оригинал имени файла, и новую метку файла как новаяСвязь. Обе метки будут ссылаться на один физический файл, и эта структура отразится в счетчике жестких связей, показываемых утилитой is. Тогда к файлу можно обращаться через любую метку, а он удаляется из файловой системы, лишь когда все его ассоциированные метки будут удалены. Если аргумент новаяСвязь опущен, то предполагается последний компонент оригинала. Если последний аргумент — имя каталога, то жесткие связи создаются от этого каталога к указанным оригинальным именам файлов. Жесткие связи не могут охватывать файловые системы. Опция -s предписывает утилите in формировать символические связи, приводящие к созданию нового файла, который содержит указатель (по имени) на другой файл. Символическая связь может охватывать файловые системы, поскольку нет никакой явной связи с адресуемым файлом кроме имени. Обратите внимание, если указанный символической связью файл удален, а символический файл связи все еще существует, то обращение через него приведет к ошибке. Опция -f позволяет привилегированному пользователю (root) создавать жесткую связь к каталогу. Для дополнительной информации о том, как жесткие связи представлены в файловой системе, обсуждение файловой системы UNIX см. в главе 14. В представленном ниже примере добавляется новая метка hold к файлу, имеющему метку hold.3 (обратите внимание, что поле счетчика жестких связей было увеличено с 1 до 2, когда жесткая связь была добавлена, а затем значение снова вернулось к 1, когда жесткая связь была удалена): $ Is -1 ...посмотреть содержимое текущего каталога. total 3 -rw-r—г— 1 glass 124 Jan 12 17:32 hold.l -rw-r—г— 1 glass 89 Jan 12 17:34 hold.2 -rw-r—r— 1 glass 91 Jan 12 17:34 hold.3 $ In hold.3 hold ...создать новую жесткую связь. 3 Is -1 ...посмотреть новое содержимое каталога. total 4 -rw-r—r— 2 glass 91 Jan 12 17:34 hold -rw-r—r— 1 glass 124 Jan 12 17:32 hold.l -rw-r—r— 1 glass 89 Jan 12 17:34 hold.2 -rw-r—r— 2 glass 91 Jan 12 17:34 hold.3 3 rm hold ...удалить одну из связей.
$ Is -1 ...посмотреть обновленное содержимое каталога. total 3 -rw-r—r— 1 glass 124 Jan 12 17:32 hold.l -rw-r—r— 1 glass 89 Jan 12 17:34 hold.2 -rw-r—r— 1 glass 91 Jan 12 17:34 hold.3 Серия жестких связей может быть добавлена к существующему каталогу, если имя каталога определено в качестве второго аргумента утилиты in. В следующем примере создаются связи в каталоге tmp ко всем файлам, удовлетворяющим шаблону hold. *: $ mkdir tmp ...создать новый каталог. $ In hold.* tmp ...создать серию связей в tmp. $ Is -1 tmp ...посмотреть содержимое tmp. total 3 -rw-r—г— 2 glass 124 Jan 12 17:32 hold.l -rw-r—r— 2 glass 89 Jan 12 17:34 hold.2 -rw-r—r— 2 glass 91 Jan 12 17:34 hold.3 $ Жесткая связь не может быть создана от файла в одной файловой системе к файлу в другой файловой системе. Чтобы обойти эту проблему, создайте символическую связь, которая может охватывать файловые системы. Для этого используйте опцию -s утилиты in. В приведенном ниже примере осуществляется попытка создать жесткую связь из пользовательского домашнего каталога к файлу /usr/include/stdio.h. Но файл находится в другой файловой системе, по этой причине утилита in не создала связи. Однако запуск утилиты in с опцией -s достиг цели. Когда утилита is используется с опцией -F, символическим связям предшествует символ @. По умолчанию утилита is показывает содержимое символической связи. Для того чтобы получить информацию о файле, на который ссылается связь, используйте опцию -L. $ In /usr/include/stdio.h stdio.h ...жесткая связь. In: stdio.h: Cross-device link $ In -s /usr/include/stdio.h stdio.h ...символическая связь. $ Is -1 stdio.h ...проверить файл. Irwxrwxrwx 1 glass 20 Jan 12 17:58 stdio.h -> /usr/include/stdio.h $ Is -F ' ...@ указывает символическую связь. stdio.h@ $ Is -IL stdio.h ...посмотреть связь. -г—г—г— 1 root 1732 Oct 13 1998 stdio.h $ cat stdio.h ...посмотреть файл.
# ifndef FILE #define BUFSIZ ttdefine SBFSIZ 8 extern struct 1024 iobuf { $ Идентификация shell: whoami Предположим, что вы случайно натолкнулись на свободный терминал и на экране находится приглашение shell. Очевидно, что кто-то работал в системе UNIX и забыл выйти из нее. Вы задаетесь вопросом: любопытно, кто это был? Чтобы раскрыть тайну, можете использовать утилиту whoami, которая показывает имя владельца shell. Например, запустив whoami на терминале пользователя glass, можно увидеть: $ whoami glass $ Синтаксис whoami Показывает имя владельца shell. Замена пользователя: su Многие думают, что su — это сокращение от англ, superuser (привилегированный пользователь). Но это не так. Данная аббревиатура означает substitute user (заменить пользователя) и позволяет создать новый shell, принадлежащий другому пользователю. Синтаксис su [-] [имяПолъзователя] [аргументы] Утилита su создает временный shell с реальным и эффективным пользовательским и групповым идентификаторами. Если имя пользователя не определено, предполагается root, и новая подсказка shell как напомина
ние устанавливается на знак #. Работая в новом shell, вы воспринимаетесь как новый пользователь. Завершая сеанс shell нажатием комбинации клавиш <Ctrl>+<D>, вы возвращаетесь в свой первоначальный shell. Конечно, чтобы использовать эту утилиту, следует знать пароль другого пользователя. Переменные окружения shell и номе задаются из файла пароля имяПользователя. Если имяПользователя — не root, устанавливаются пользовательские переменные окружающей среды. Новый shell не проходит через последовательность регистрации, если не задана опция Все другие параметры передаются, как аргументы командной строки новому shell. Пример использования su: $ whoami ...выяснить текущий ID пользователя. glass $ SU ...заменить пользователя. Password: <ввел пароль привилегированного пользователя> $ whoami ...подтвердить, что мой текущий ID пользователя изменился. root $ ...выполнить задачи привилегированного пользователя здесь. $ ...прекратить дочерний shell. $ whoami ...подтвердить восстановление текущего ID пользователя. glass $ Проверка почты: biff Командные интерпретаторы UNIX периодически осуществляют проверку наличия поступающей почты. Это означает, что может пройти несколько минут между поступлением почты в ваш почтовый ящик и уведомлением shell на вашем терминале. Чтобы избежать подобной задержки, вы можете разрешить мгновенное уведомление о почте, используя утилиту biff. Синтаксис biff [у|п] Утилита biff разрешает или запрещает мгновенное уведомление о получении почты. Чтобы увидеть текущую установку biff, используйте утилиту без параметров. Укажите у, чтобы позволить вывод мгновенного уведомления, и п, чтобы запретить его. Почему эта утилита называется
biff? Разработчица из Калифорнийского университета в Беркли, которая написал утилиту для BSD UNIX, назвала ее в честь своей собаки Biff, которая всегда лаяла, когда почтальон приносил почту. Пример: $ biff biff is n $ biff у $ biff biff is у $ ...вывести текущую установку biff. ...разрешить моментальное уведомление о почте. ...подтвердить новую установку biff. Преобразование файлов Перечисленные ниже утилиты, в числе других, осуществляют преобразование над содержимым файлов. □ Утилиты compress/uncompress и gzip/gunzip конвертируют файл в пространственно-эффективный промежуточный формат и обратно. Полезны для экономии дискового пространства. □ Утилита crypt кодирует файл. □ Утилита sed — программируемый потоковый редактор общего назначения, который редактирует файл согласно предварительно подготовленному набору инструкций. □ Утилита tr связывает символы из одного набора с другим. Полезна для выполнения простого связывания типа преобразования файла из прописных букв в строчные. □ Утилита ul конвертирует встроенные подчеркнутые последовательности символов в файл подходящей для конкретного терминала формы. Сжатие файлов: compress/uncompress и gzip/gunzip Утилита compress кодирует файл в более компактный формат, который может быть декодирован позже с использованием утилиты uncompress. Синтаксис compress -cv {имяФайла}+ uncompress -cv {имяФайл}+
Утилита compress заменяет файл его сжатой версией, добавляя в конец суффикс ".Z". Опция -с посылает сжатую версию на стандартный вывод, а не перезаписывает первоначальный файл. Опция -v показывает величину сжатия, которое имеет место. Утилита uncompress инвертирует файл, созданный compress, воссоздавая первоначальный вид из его сжатой версии. Утилита compress полезна для уменьшения места на диске, занимаемого файлами,'и упаковки большего количества файлов в архивированный файл. Пример: $ Is -1 palindrome.с reverse.с ...проверить оригиналы. -rw-r—г— 1 glass 224 Jan 10 13:05 palindrome.с -rw-r—г— 1 glass 266 Jan 10 13:05 reverse.с $ compress -v palindrome.c reverse.с ...сжать их. palindrome.c: Compression: 20.08% — replaced with palindrome.c.Z reverse, c: Compression: 22.93% — replaced with reverse.c.Z $ Is -1 palindrome, c. Z reverse.c.Z -rw-r—r— 1 glass 179 Jan 10 13:05 palindrome.c.Z -rw-r—r— 1 glass 205 Jan 10 13:05 reverse.c.Z $ uncompress -v *.Z ...восстановить оригиналы. palindrome.c.Z: — replaced with palindrome.c reverse.c.Z: — replaced with reverse.c $ Is -1 palindrome.c reverse.с ...подтвердить. -rw-r—r— 1 glass 224 Jan 10 13:05 palindrome.c -rw-r—r— 1 glass 266 Jan 10 13:05 reverse.c $ _ Алгоритм, который реализуют утилиты compress и uncompress, был запатентован уже после их написания (хотя многие не знали этот факт). Когда их владелец начал процедуру получения патента, выяснилось, что либо должны были быть оплачены лицензионные отчисления за использование обеих утилит, либо они должны быть удалены из системы. Поэтому многие продавцы UNIX выбрали утилиту GNU, известную как gzip, которая работает почти таким же образом, как compress, но использует другой, не имеющий лицензионных ограничений алгоритм. Следующий пример их применения фактически Идентичен Показанному ранее ДЛЯ compress И uncompress: $ Is -1 palindrome.с reverse.с -rw-r—г— 1 ables 224 Jul 1 14:14 palindrome, с -rw-r—r— 1 ables 266 Jul 1 14:14 reverse, c $ gzip -v palindrome, c reverse, c
palindrome.с: 34.3% — replaced with palindrome.с.gz reverse.c: 39.4% — replaced with reverse.c.gz $ Is -1 palindrome.c.gz reverse.c.gz -rw-r—r— 1 ables 178 Jul 1 14:14 palindrome.c.gz -rw-r—r— 1 ables 189 Jul 1 14:14 reverse.c.gz $ gunzip -v ★ .gz palindrome.c.gz: 34.3% — replaced with palindrome.c reverse.c.gz: 39.4% — replaced with reverse.c $ Is -1 palindrome.c reverse.c -rw-r—r— 1 ables 224 Jul 1 14:14 palindrome, c -rw-r—r— 1 ables 266 Jul 1 14:14 reverse.c $ Синтаксис gzip -cv {имяФайла}+ gun z ip - cv {имяФайла} + Утилита gzip заменяет файл его сжатой версией, добавляя в конец суффикс ".gz". Опция -с посылает сжатую версию на стандартный вывод, а не перезаписывает первоначальный файл. Опция -v показывает величину сжатия, которое имеет место. Утилита gunzip может восстановить файл, созданный как gzip, так и compress. Утилиты gzip и gunzip доступны с Web-сайта GNU по адресу http://www.gnu.org/software/gzip/gzip.html. Вы можете загрузить их, если они отсутствуют в вашей системе. Шифрование файла: crypt Утилита crypt создает кодируемую ключом версию текстового файла. Единственный способ восстановить первоначальный текст из закодированного файла — выполнить crypt с тем же самым ключом. Синтаксис crypt [ ключ] Утилита crypt выполняет одно из действий: • если на стандартном входе текст допустимого вида, кодируемая версия текста посылается на стандартный вывод, используя параметр ключ как ключ шифрования;
• если на стандартном входе закодированный текст, декодированная версия текста посылается на стандартный вывод, используя параметр ключ как ключ для расшифровки. Если ключ не определен, утилита crypt напоминает, что вы должны ввести его со своего терминала. Вводимый ключ не отображается. Если ключ указан в командной строке, имейте в виду, что вывод листинга при помощи утилиты ps покажет значение ключа. Утилита crypt использует алгоритм кодирования, подобный тому, который использовался в немецкой шифровальной машине Enigma. Пример использования утилиты crypt: $ cat sample.txt Here’s a file that will be encrypted. $ crypt agatha < sample., txt > sample.crypt $ rm sample.txt $ crypt agatha < sample.crypt > sample.txt $ cat sample, txt Here’s a file that will be encrypted. $ ...вывести оригинал. ...agatha — это ключ. ...удалить оригинал. ...декодировать. ...вывести оригинал. Потоковое редактирование: sed Утилита потокового редактирования sed просматривает один или несколько файлов и осуществляет редактирование всех строк, которые соответствуют конкретному условию. Действия и условия могут быть заблаговременно сохранены в sed-скрипте. Утилита полезна для выполнения простых повторяющихся задач редактирования. Утилита sed имеет много параметров и опций. Из-за этого здесь описаны только ее главные особенности и опции. Однако хочется надеяться, что представленный в этом разделе материал позволит вам писать большое количество полезных sed-скриптов. Синтаксис sed [-е скрипт] [-f скриптФайл] {имяФайла}^ Утилита sed редактирует входной поток согласно скрипту, который содержит команды редактирования. Каждая команда редактирования отделяется символом перевода строки и содержит действие, строку или диапазон строк для выполнения действия, sed-скрипт может быть сохранен
в файле и выполнен с помощью указания опции -f. Если текст срипта помещается непосредственно в командную строку, он должен быть окружен апострофами. Если файлы не определены, утилита sed читает из стандартного входа. Команды sed sed-скрипт — это список из одной или более команд, разделенных символом перевода строки. Существуют правила применения команд утилиты sed (табл. 3.7). □ Адрес должен быть или номером строки или регулярным выражением. Регулярное выражение выбирает все строки, которые соответствуют выражению. Вы можете использовать символ $, чтобы выбрать последнюю строку. П диапазонАдреса может быть единственным адресом или парой адресов, отделенных запятыми. Если определены два адреса, то выбираются все строки между первой строкой, которая соответствует первому адресу, и первой строкой, которая соответствует второму адресу. □ Если адрес не определен, то команда применяется ко всем строкам. Таблица 3.7. Команды редактирования в sed Синтаксис команды Описание адрес а\ текст Добавляет текст после строки, указанной адресом диапазонАдреса с\ текст Заменяет текст, указанный диапазономАдреса текстом диапазонАдреса d Удаляет текст, указанный диапазономАдреса адрес i\ текст Вставляет текст после строки, укзанной адресом адрес г имя Добавляет содержимое файла имя после строки, указанной адресом диапазонАдреса s/выражение/строка/ Заменяет первое появление регулярного выражения выражение строкой строка диапазонАдреса а/выражение/строка/д Заменяет каждое появление регулярного выражения выражение строкой строка Замена текста В приведенном ниже примере sed-скрипт вводится в командной строке. Скрипт вставляет пару пробелов в начало каждой строки. $ cat arms .•.посмотреть оригинальный файл. People just like me,
Are all around the world, Waiting for the loved ones that they need. And with my heart, I make a simple wish, Plain enough for anyone to see. $ sed. 's/^/ /' arms > arms, indent ...отступ в файле. $ cat arms.indent ...посмотреть результат. People just like me, Are all around the world, Waiting for the loved ones that they need. And with my heart, I make a simple wish, Plain enough for anyone to see. $ _ Чтобы удалить все ведущие пробелы из файла, используйте оператор замены обратным способом, как показано в следующем примере: $ sed ’s/" *//' arms.indent ...удалить ведущие пробелы. People just like me, Are all around the world, Waiting for the loved ones that they need. And with my heart, I make a simple wish, Plain enough for anyone to see. $ _ Удаление текста Следующий пример иллюстрирует скрипт, который удаляет все строки, содержащие регулярное выражение ' а' в качестве отдельного символа: $ sed '/а/d' arms ...удалить все строки, содержащие ’а' People just like me, $ _ Чтобы удалить только те строки, которые содержат слово 'а1, пришлось окружить регулярное выражение скобками (\< и \>): $ sed '/\<a\>/d' arms People just like me, Are all around the world, Waiting for the loved ones that they need.
And with my heart, Plain enough for anyone to see. $ Вставка текста Рассмотрим пример, в котором вставлено предупреждение об авторском праве в начале файла с помощью команды вставки. Заметьте, sed-скрипт сохранен в файле и выполнялся с использованием опции -f: $ cat sed5 ...посмотреть sed-скрипт. Copyright 1992, 1998, & 2002 by Graham GlassX All rights reservedX $ sed. -f sed5 arms ...вставить предупреждение об авторском праве. Copyright 1992, 1998, & 2002 by Graham Glass All rights reserved People just like me, Are all around the world, Waiting for the loved ones that they need. And with my heart, I make a simple wish, Plain enough for anyone to see. $ Замена текста В приведенном ниже примере группа строк 1—3 заменяется сообщением о том, что они были подвергнуты цензуре: $ cat sed6 ...посмотреть sed-скрипт. 1,3с\ Lines 1-3 are censored. $ sed -f sed6 arms ...выполнить скрипт. Lines 1-3 are censored. And with my heart, I make a simple wish, Plain enough for anyone to see. $ _ Чтобы заменить сообщением отдельные строки, а не группу, создайте команды для каждой строки: $ cat sed7 ...посмотреть sed-скрипт. 1с\
Line 1 is censored. 2c\ Line 2 is censored. 3c\ Line 3 is censored. $ sed -f sed7 arms ...выполнить скрипт. Line 1 is censored. Line 2 is censored. Line 3 is censored. And with my heart, I make a simple wish, Plain enough for anyone to see. $ _ Вставка файлов В следующем примере вставлено сообщение за последней строкой файла: $ cat insert ...посмотреть файл, который будет вставлен. The End $ sed '$r insert' arms ...выполнить скрипт. People just like me, Are all around the world, Waiting for the loved ones that they need. And with my heart, I make a simple wish, Plain enough for anyone to see. The End $ Составные команды sed Приведенный ниже пример иллюстрирует использование составных команд sed. В начало каждой строки вставлена последовательность «, а вконец строк — последовательность >>: $ sed — 'з/л/« /' -е 's/$/ »/' arms « People just like me, » « Are all around the world, » « Waiting for the loved ones that they need. » « And with my heart, »
« I make a simple wish, » « Plain enough for anyone to see. » $ Преобразование символов: tr Утилита tr ставит в соответствие символы в файле из одного набора символам из другого набора.2 Синтаксис tr -cds строка! строка2 Утилита tr связывает все символы набора строка! на своем стандартном входе с набором символов строка2. Если длина строки2 меньше, чем длина строки!, строка2 дополняется, повторяя свой последний символ; другими словами, команда tr abc de является эквивалентной команде tr abc dee. Набор символов может быть определен с помощью системы обозначений shell: • чтобы определить набор из символов a, d, и f, просто пишут их, как отдельную строку: adf; • чтобы определить набор символов от а до z, отделяют начальный и конечный символ дефисом: a-z. По умолчанию утилита tr заменяет каждый символ стандартного входа строки! соответствующим ему СИМВОЛОМ строки2. Опция -с предписывает дополнить строку! прежде, чем будет выполнено связывание. Дополнение строки означает, что она заменяется строкой, которая содержит все символы ASCII кроме тех, которые имеются в первоначальной строке. В результате такого действия заменяется каждый символ стандартного входа, которого нет в строке!. Опция -d удаляет каждый символ, имеющийся в строке!, из стандартного входа. Опция -s заменяет последовательность повторяющихся символов единственным экземпляром символа. 2 Фактически создается таблица символов. — Ред.
Вот некоторые примеры утилиты tr в действии: $ cat до.cart go cart racing ...посмотреть пример входного файла. $ tr a-z A-Z < до.cart ...преобразовать прописные буквы в строчные. GO CART RACING $ tr a-c D-E < go.cart ...заменить abc на DEE. go EDrt rDEing $ tr -с a X < go. cart ...заменить все символы, кроме а, на X. ХХХХаХХХХХаХХХХХ$ ...даже последний перевод строки заменен. $ tr -с a-z *\012* < до.cart ...заменить не буквы go ...ASCII 12 (перевод строки). cart racing $ tr -cs a-z '\012* < go. cart ...повторить, но сжать go ...повторяющиеся переводы строк. cart racing $ tr -d a-c < go.cart ...удалить все символы a-c. go rt ring $ Преобразование подчеркнутых последовательностей: ul Утилита ul преобразует файл, который содержит подчеркнутые символы так, чтобы он правильно выводился на конкретном типе терминала. Она полезна с командами, подобными man, которая генерирует подчеркнутый текст. Синтаксис ul -t терминал {имяФайла}* Утилита ul преобразовывает подчеркнутые символы на своем входе так, чтобы они корректно отображались на указанном терминале. Если терминал не определен, то предполагается, что он определяется переменной
окружающей среды term. Файл /etc/termcap используется утилитой ui для определения правильной последовательности. Рассмотрим пример совместного использования утилит ui и man. Предположим, что вы хотите использовать утилиту man для создания документа, который желаете печатать на простом ASCII-принтере (принтер при этом не выводит подчеркнутых символов). Утилита man генерирует подчеркнутые символы для текущего терминала, поэтому нужно отфильтровать выходные данные, чтобы сделать их подходящими для "немого” принтера. Создадим конвейер с выхода-утилиты man через утилиту ui с установкой терминала dumb. $ man who | ul -tdumb > man.txt $ head man.txt ...посмотреть первые десять строк. WHO(l) USER COMMANDS WHO(l) NAME who — who is logged in on the system SYNOPSIS who [who-file] [am i] $ Просмотр необработанного содержимого файла: od Утилита восьмеричного дампа od позволяет увидеть содержимое нетекстового файла в различных форматах. Синтаксис od -acbcdfhilosx имяФайла [смещение[.][Ь]] Утилита od показывает содержимое имяФайла в форме, указанной одной из следующих опций. Опция Описание -а Интерпретирует байты, как символы, и печатает как имена ASCII (т. е. 0 соответствует NULL) -Ь Интерпретирует байты, как восьмеричное значение без знака -с Интерпретирует байты, как символы, и печатает в нотации С (т. е. 0 соответствует \0)
(окончание) Опция Описание -d Интерпретирует пары байтов, как десятичные без знака -f Интерпретирует пары байтов, как значения с плавающей запятой -h Интерпретирует пары байтов, как шестнадцатеричное без знака —i Интерпретирует пары байтов, как десятичные со знаком -1 Интерпретирует четыре байта, как десятичные со знаком -о Интерпретирует пары байтов, как восьмеричное без знака -s [n] Ищет строки минимальной длины п (по умолчанию 3), завершающиеся символом NULL -x Интерпретирует пары байтов, как шестнадцатеричное значение По умолчанию содержимое отображается как ряд восьмеричных чисел. Параметр смещение определяет, где должен начаться вывод. Если смещение заканчивается на ь, то это интерпретируется как число блоков. Иначе — как восьмеричное число. Чтобы определить шестнадцатеричное число, укажите перед ним х. Для определения десятичного числа поставьте в конце его точку. В следующем примере содержимое исполняемого файла /bin/od отображается в виде восьмеричных чисел, а затем в виде символов, начиная с позиции 1000 (восьмеричный): $ od /bin/od ...восьмеричный дамп । файла /bin/od. 0000000 100002 000410 000000 017250 000000 003630 000000 006320 0000020 000000 000000 000000 020000 000000 000000 000000 000000 0000040 046770 000000 022027 043757 000004 021002 162601 044763 0000060 014004 021714 000002 000410 045271 000000 020746 063400 0000100 000006 060400 000052 044124 044123 027402 047271 000000 0000120 021170 047271 000000 021200 157374 000014 027400 047271 0000140 000002 000150 054217 027400 047271 000002 000160 047126 $ od -с /bin/od 1000 ...символьный дамп файла /bin/od. 0001000 Н х \0 । 001 N @ \0 002 \0 \0 / u s г / 1 0001020 i b / 1 d s о \0 / d е v / z е 0001040 г о \0 ' \0 \0 \0 \0 030 с г t 0 : п о 0001060 / и S г / 1 i ь / 1 d . s о \п
0001100 \0 \0 \0 % c r t 0 • / u s r / 1 0001120 i b / 1 d • s о m a p P i n g 0001140 f a i 1 u r e \n \0 \0 \0 \o 023 c r 0001160 t 0 • n о / d e v / z e г о 0001200 \n \0 200 \0 \0 002 200 \0 \0 022 \0 \0 \0 007 \0 \0 $ _ Вы можете производить поиск строки минимальной длины, используя опцию -s. Любой ряд символов, сопровождаемых ASCII-символом NULL, рассматривается в качестве строки. Пример: $ od -s7 /bin/od ...поиск строк длиной от 7 символов. 0000665 \fNANu о 0001012 /usr/lib/ld. so 0001031 /dev/zero 0001050 crtO: no /usr/lib/ld.so\n 0001103 %crt0: /usr/lj.b/ld. so mapping failure\n Монтирование файловых систем: mount/umount Привилегированный пользователь (root) может расширять файловую систему, используя утилиту mount. Синтаксис mount -оопции [имяУстройства каталог] umount имяУстройства Утилита mount позволяет соединять файловую систему устройства с корневой иерархией. При использовании без аргументов утилита mount показывает список смонтированных в настоящее время устройств. Чтобы определить специальные опции, за опцией -о указывают список адекватных кодов, среди которых rw монтирует файловую систему для чте-ния/записи, а го монтирует файловую систему только для чтения. Утилита umount размонтирует предварительно смонтированную файловую систему. В следующем примере объединяются файловая система, содержащаяся на устройстве /dev/dsk2, с каталогом /usr. Обратите внимание, что перед вы
полнением монтирования каталог /usr был пуст. После монтирования файлы, хранящиеся на устройстве /dev/dsk2, появились внутри этого каталога. $ mount ‘...посмотреть текущие смонтированные устройства, /dev/dskl on / (rw) $ Is /usr .../usr is currently empty. $ mount /dev/dsk2 /usr ...монтировать устройство /dev/dsk2. $ mount ...посмотреть текущие смонтированные устройства, /dev/dskl on / (rw) /dev/dsk2 on /usr (rw) $ Is /usr ...посмотреть содержимое смонтированного устройства. bin/ etc/ .include/ lost+found/ sre/ ueb/ demo/ game lib/ pub/ sys/ ueblib/ diet/ hosts/ local/ spool/ tmp/ $ _ Чтобы размонтировать устройство, используйте утилиту umount. В следующем примере размонтируется устройство /dev/dsk2, а* затем происходит просмотр каталога /usr: $ umount /dev/dsk2 ...размонтировать устройство. $ mount ...посмотреть текущие смонтированные устройства, /dev/dskl on / (rw) $ Is /usr ...заметьте, что каталог /usr снова пустой. $ _ Файлы больше не доступны. Идентификация терминалов: tty Утилита tty идентифицирует имя рабочего терминала. Синтаксис tty Утилита tty показывает путевое имя вашего терминала. Возвращает О, если ее стандартный вход — терминал; иначе возвращает 1. В следующем примере входным терминалом является специальный файл /dev/ttypO: $ tty ...вывести путевое имя терминала. /dev/ttypO $
Форматирование текста: nroff/troff/style/spell Одной из первых применяемых функций UNIX должна была стать поддержка обработки текста в Bell Laboratories. Несколько утилит, включая nroff, troff, style и spell, были созданы специально для форматирования текста. В настоящее время они фактически устарели из-за использования более сложных инструментов, поддерживающих принцип "What You See Is What You Get" (WYSIWYG, "Что видите, то и получаете"). Например, утилита nroff требует ручного размещения специальных команд типа ,ра внутри текстового документа, чтобы отформатировать его правильно, тогда как современные инструменты позволяют вам делать это с помощью графического интерфейса. Для получения дополнительной информации об утилитах обработки текста в "старинном стиле" см. [Sobell 1994]. Измерение времени выполнения: time Иногда полезно знать, сколько потребуется времени для выполнения определенной команды или программы (или как долго они выполняются относительно времени выполнения чего-то еще). Утилита time может использоваться, чтобы получить отчет о времени выполнения любой указанной команды UNIX. Синтаксис time команднаяСтрока Утилита time служит для получения сведений о времени выполнения любой команды UNIX, указанной параметром команднаяСтрока. Время сообщается и в виде общего затраченного времени и времени ЦП. (Время ЦП выражается в виде двух значений: пользовательское время и системное время.) Пример: $ time sort allnames.txt >sortednames. txt real Om 4.18s user Om 1.85s sys Om 0.14s $ Эта команда сообщает нам, что требуется почти 4,2 секунды астрономического времени, чтобы отсортировать наш файл, тогда как общее время использования ЦП было 1,99 секунды.
Утилита time особенно полезна в определении времени работы программ или скриптов, обрабатывающих маленькие порции данных, когда невозможно "почувствовать" разницу в требуемом времени из-за слишком быстрого их выполнения. Создание собственных программ: Perl Мы выяснили, что при возникновении сложных задач обработки данных, когда требовалось объединение двух или нескольких утилит UNIX, необходимо было писать скрипты shell на одном из языков shell. Скрипты shell медленнее, чем С-программы, т. к. они интерпретируются вместо компиляции. С другой стороны, они намного более легки для написания и отладки. С-программы предоставляют возможность использования большего количества функций UNIX, но, как правило, требуют большего времени для написания и изменения. В 1986 г. Ларри Уолл (Larry Wall) выяснил, что shell-скриптов недостаточно, а С-программы оказались ’’убийственны” для многих намерений. Он собирался написать скриптовый язык, который должен был стать лучше shell-скриптов и С-программ. Результатом стал Perl (Practical Extraction Report Language, Практический Язык Извлечения Сообщений). Perl разрешил многие проблемы, с которыми Ларри Уолл сталкивался при генерации отчетов и применении других ориентируемых на текст функций, хотя язык также обеспечил свободный доступ к функциям UNIX, чего не делали shell-скрипты. Синтаксис языка Perl покажется знакомым для shell- и С-программистов, т. к. многое было заимствовано от элементов обоих языков. Хочется надеяться, что в этой книге нам удалось дать высокоуровневое представление о Perl. Подобно программе awk, о Perl написаны целые книги (см., например, [Medinets 1996] и [Wall 1996].) Детализация такого уровня находится за пределами возможностей этой книги, но, несмотря на первое знакомство, мы уверены, что вы захотите выяснить больше о Perl. Получение Perl Хотя Perl используется в большинстве сред UNIX, система программирования на языке часто не поставляется вместе с этой ОС, поскольку не является частью UNIX. Если ваш продавец UNIX не поставляет Perl, вы должны будете загрузить и установить его самостоятельно. Лучший источник — http://www.perl.com. Этот узел сети содержит рассылки Perl для различных платформ в секции downloads (загрузка), а также документацию и ссылки на многие другие полезные ресурсы.
Огромное преимущество реализации инструментов на Perl — это наличие языка на основных платформах, включая большинство версий UNIX, Windows и MacOS. Следует остерегаться несовместимости в системных запросах и системном расположении файлов данных. Однако ваш код потребует очень мало изменений для того, чтобы работать должным образом на различных платформах. Не менее важное преимущество Perl состоит в том, что он бесплатный. Perl лицензирован разновидностью GNU Public License (Общедоступной лицензией GNU), известной как Artistic License (Художественная лицензия). Она не затрагивает никакого кода, который вы пишете на Perl. Вы можете использовать и распространять собственный код любым пригодным для вас способом. Печать текста Без возможности печатать большинство программ не могли бы выполнить многого. Итак, согласно традиции UNIX, начнем наши примеры скриптов Perl с демонстрации печати единственной строки: print "hello world.\n”; Именно из этого простого примера вы можете сделать вывод, что каждая строка в Perl должна заканчиваться точкой с запятой (;). Также обратите внимание, что \п используется (так же как в языке программирования С) для печати символа перевода строки. Переменные, строки и целые Для программирования, конечно, необходимо иметь возможность присваивать и изменять значения. Perl поддерживает немало переменных, как, например, это делают интерпретаторы командной строки. Переменные могут иметь любой тип. Perl позволяет визуально определить тип переменных по специальным символам. Главное различие между Perl-переменными и переменными shell заключается в том, что в Perl символ $ сам по себе не используется. Он указывается в имени переменной: $i = 3; Это различие следует уяснить закаленным программистам shell. В дополнение ко всем "типичным" математическим операторам (сложение, вычитание и т. д.), целые числа также поддерживают оператор диапазона "..который служит для указания диапазона целых чисел. Он полезен для создания цикла на диапазоне значений.
Как и в большинстве языков программирования, строки в Perl определяются текстом в кавычках. Строки также поддерживают оператор конкатенации, который соединяет строки вместе. Пример: print 1, 2, 3..15, "\п"; # оператор диапазона print "А”, "В", "С”, "\п"; # строки $i = "А" . "В"; # оператор конкатенации print "$i", "\n"; Эти строки генерируют следующие выходные данные: 123456789101112131415 АВС АВ Вы можете видеть, что печатается каждое значение, предоставляя контроль над всеми промежутками. Массивы Большинство языков программирования поддерживает работу с массивами, которые являются списками значений данных. Массивы в Perl весьма просты в использовании, поскольку они распределяются динамически. (Программист не должен определять, насколько большими они будут. И если применяется больший по размеру массив, чем определен, Perl выделит больше памяти и увеличит массив.) Массив обозначается знаком @ следующим образом: @агг = (1, 2,3, 4,5) ; Эта строка объявляет массив агг и помещает в него пять значений. Можно определить тот же самый массив строкой кода @arr = (1..5); которая использует оператор диапазона с целыми. Доступ к отдельному индексированному элементу осуществляется так: print @arr[0],”\n"; Как в большинстве реализаций массивов, первый элемент нумеруется нулем. Таким образом, указанная строка печатала бы 1, т. к. это первое значение массива. Если указать массив без индексов, выведутся все определенные значения. Если используется имя массива без индекса в месте, где ожидается скалярное значение3, оно будет интерпретировано, как количество элементов этого массива. / 3 То есть имя переменной. — Ред.
Пример: @al = (1); # массив из 1 элемента @а2 - (1,2,3,4,5); # массив из 5 элементов @аЗ = (1..10); # массив из 10 элементов print @al, " ", @а2, " ", @аЗ, "\п"; print @al[0], " ", @а2[1], " ", @аЗ[2], "\п"; # Используется, как скаляр, выдаст число элементов print @а2 + @аЗ, "\п"; Когда код выполнится, пользователь увидит следующее: 1 12345 12345678910 123 15 В Perl предусмотрен специальный тип массива — ассоциативный массив. В обычном массиве индекс элемента определяется целым числом между 0 и максимальным размером массива. Ассоциативный массив может иметь индексы в произвольном порядке и любых значений. Рассмотрим, например, массив названий месяцев. Определим массив $month с 12 значениями "Январь", "Февраль" и т. д. (Так как массивы начинаются с индекса 0, вы или должны помнить о вычитании 1 из индекса, или определить множество из 13 значений и игнорировать $month[0], начиная вместо этого с $month[l] = "Январь"). Но что делать, если происходит чтение названия месяца со входа, и нужно посмотреть числовое значение. Можно использовать цикл для поиска в массиве, но это требует дополнительного кода. Было бы лучше, если бы можно было просто индексировать массив названием? В ассоциативном массиве вы можете это сделать следующим образом: @month{’January’} = 1; @month{’February'} = 2; Тогда можно читать название месяца и получать доступ к его числовому значению через код $monthnum = $month {$monthname) ; без применения цикла.
Вместо того чтобы вводить в массив элементы по одному, как мы делали в предыдущем примере, можно определить массив в начале Perl-программы: %month = ("January", 1, "February", 2, "March", 3, "April", 4, "May", 5, "June", 6, "July", 7, "August", 8, "September", 9, "October", 10, "November", 11, "December", 12); Набор значений, которые могут использоваться в ассоциативном массиве (также называемый ключами к массиву), возвращается, как и в нормальном массиве, вызовом функции Perl keys (): Omonthnames = keys (%month) ; Если вы попытаетесь использовать недопустимое значение как ключ, будет возвращен пустой указатель или ноль (в зависимости от того, как вы используете значение). Математические и логические операторы Следующий шаг после объявления переменной — изменение ее значения. Большинство действий над величинами знакомо из С-программирования. Типичные операторы для целых и вещественных чисел — это сложение (+), вычитание (-), умножение (*) и деление (/). Целые числа также поддерживают С-конструкции пре- и постинкремента и пре- и постдекремента. Кроме того, к ним применимы логические операторы and и or. В приведенном ниже примере указана обратная косая черта перед знаком $, используемым в качестве текста в операторе печати, поскольку в этом месте выводится не значение переменной, а ее имя с добавленным к нему символом $ как приставки: $п = 2; print ( "\$П=", $n, "\n"); $п = 2; print ("increment after \$n=", $n++, "\n"); $п = 2; print ("increment before \$n=", ++$n, "\n") $п = 2; print ("decrement after \$n=", $n—, "\n"); $п = 2; print ("decrement before \$n=", —$n, "\n") $п = 2; # сброс print ( "\$n+2=" , $n + 2, "\n"); print ( "\$n-2=" , $n - 2, "\n"); print ( "\$n*2=" , $n * 2, "\n"); print ( "\$n/2=" , $n / 2, "\n"); $г = 3.14; # вещественное число
print ("\$r=", $r, "\n"); print ("\$r*2=", $r * 2, "\n"); # удвоить print ("\$r/2=", $r / 2, "\n"); # поделить пополам print ("1 && 1 -> ”, 1 && 1, "\n"); print ("1 && 0 -> ", 1 && 0, "\n"); print ("1 || 1 -> ", 1 |I 1, "\n"); print ("1 j | 0 -> ", 1 | | 0, "\n"); Этот скрипт генерирует следующие выходные данные: $п=2 increment after $n=2 increment before $n=3 decrement after $n=2 decrement before $n=l $n+2=4 $n-2=0 $n*2=4 $n/2=l $r=3.14 $r*2=6.28 $r/2=1.57 1 && 1 -> 1 1 && 0 -> 0 1 II 1 -> 1 1 || 0 -> 1 Строковые операторы Действия над строковыми типами более сложны, чем над целыми числами, и обычно требуют использования строковых функций. Единственная простая операция, которая имеет смысл для строк, — это конкатенация. Строки конкатенируются оператором "Л Пример: $firstname = "Graham"; $lastname = "Glass"; $fullname = $firstname . " " . $lastname; print "$ fullname\n"; Результат работы кода: Graham Glass
Однако несколько простых операторов сопоставления доступны для строк: if ($value =~ /abc/) {print "contains 'abc'\n"}; $value =~ s/abc/def/; # изменить 'abc1 на 'def' $value =~ tr/a-z/A-Z/; # перевести в прописные Опытный пользователь UNIX признает синтаксис замены от редактора vi и утилиты sed, а также синтаксис перевода, основанный на UNIX-утилите tr. Операторы сравнения Наверняка вам потребуется выполнить сравнение значений. Операторы сравнения, как показано в табл. 3.8, являются обычными. В случае сравнения строк на "больше, чем" или "меньше, чем" эти операторы выясняют порядок сортировки строк. Таблица 3.8. Операторы сравнения в Perl Операция Числовые величины Строковые величины Равно eq Не равно ! = пе Больше, чем > gt Больше, чем или равно >= де Меньше, чем < It Меньше, чем или равно <= 1е Конструкции if, while, for и foreach Существенная часть любого языка программирования — это способность выполнять различные операторы в зависимости от значения переменной и организовывать циклы для повторяющихся задач или индексирования значений массива. Оператор if и цикл while в Perl подобны операторам в языке С. В конструкции if оператор сравнения используется для сопоставления двух значений, а различные наборы операторов исполняются в зависимости от результата сравнения (истина или ложь): $i = 0; if ( $i = 0 ) { print "it's true\n";
} else { print "it’s false\n”; } Этот скрипт выводит на печать строку it’s true Можно организовать цикл с помощью оператора while, например, для печати текста до тех пор, пока оператор сравнения возвращает истину: while ( $i = 0 ) { print "it’s true\n"; Конечно, сравнение возвратит ложь на следующем же цикле, т. к. $i был увеличен. Perl также работает, как с циклами for из С, так и с циклами foreach из С shell. Пример: for ($i = 0 ; $i < 10 ; $i++ ) { print $i, " ’’; print "\n"; Этот скрипт считает от 0 до 9, печатает значение (без символа перевода строки) и генерирует следующие выходные данные: 0123456789 Пример цикла foreach: foreach $n (1..15) { print $n, " "; } print ”\n"; Этот скрипт производит то, что вы могли ожидать: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Ввод/вывод файла Одно весомое усовершенствование Perl перед shell-скриптами — это способность направлять ввод и вывод к определенным файлам и использовать не только стандартный ввод, вывод или каналы ошибки. Вы можете получить доступ к стандартному вводу и выводу следующим образом: while (@line=<stdin>) { foreach $i (@line) {
print $i; # также читает символ EOL (конец строки) } } Этот скрипт будет читать каждую строку из стандартного входа и печатать ее. Но вы можете определить файл данных, из которого захотите выполнить чтение. Вот как это сделать: $FILE= "info.dat"; open (FILE); # имя переменной, не вычисляется @array = <FILE>; close (FILE); foreach $line (@array) { print "$line"; } Этот Perl-скрипт открывает файл info.dat и читает все его строки в массив array. (Остроумное имя, что вы скажете?) Затем он делает то же самое, что и предыдущий скрипт — распечатывает каждую строку. Функции Для реализации одних и тех же алгоритмов в разных программах язык должен предусмотреть возможности использования функций или подпрограмм. Korn shell обеспечивает слабый тип функций, реализованных через командный интерфейс, и это единственный основной shell, который предусматривает функции вообще. Конечно, язык С обеспечивает функции, но авторы скриптов имели много проблем с ним прежде, чем появился Perl. Функции Perl использовать достаточно просто, хотя синтаксис может показаться замысловатым. Следующий простой пример функции Perl даст вам интересную идею: sub pounds2dollars { $EXCHANGE_RATE =1.54; # изменить в случае необходимости $pounds = $_[0] ; return ($EXCHANGE_RATE * $pounds); ) Данная функция заменяет значение, указанное для фунта стерлингов на американские доллары (заданный обменный курс $1.54 к фунту, который может быть изменен по мере необходимости). Специальная переменная $_ [ о ] ссылается на первый аргумент функции.
Чтобы вызвать функцию, в Perl-скрипт надо добавить строки: $book =3.0; # цена в британских фунтах $value = pounds2dollars($book); print "Value in dollars = $value\n"; Когда мы запустим этот скрипт (который включает функцию Perl в конец), то получим Value in dollars = 4.62 Библиотека функций В противовес shell-скриптам Perl обладает способностью выполнять системные вызовы UNIX. Кроме того, Perl обеспечивает интерфейс ко многим системным вызовам UNIX. Интерфейс осуществляется через функции библиотеки Perl, а не прямо через библиотеку системных вызовов. Поэтому использование языка зависит от его реализации и версии, и вы должны обратиться к документации имеющейся у вас версии для получения конкретной информации. Когда интерфейс доступен, он обычно очень похож на библиотеку С. Мы уже рассмотрели несколько функций Perl в предыдущих разделах, когда видели применение системных вызовов open (), close () и print (). Другой простой пример полезной системной функции exit(1); использующейся для выхода из Perl-программы и передачи заданного кода возврата shell. Perl также имеет специальную функцию выхода для печати сообщения на стандартный выход stdout и выхода с текущим кодом ошибки: open(FILE) or die("Cannot open file."); Таким образом, если вызов функции open () завершается ошибкой, функция die о будет выполнена, генерирует вывод сообщения об ошибке на stdout, и Perl-программа завершается с кодом ошибки. Существуют некоторые строковые функции, позволяющие манипулировать значениями строк: length о, index о и split о . Команда $len = length($fullname); присваивает переменной $1еп длину текста, хранящегося в строковой переменной $fullname. Для того чтобы расположить одну строку внутри другой, используйте конструкцию $i = index($fullname, "Glass");
Значение $i будет равно 0, если строка начинается с текста, указанного в строке поиска во втором аргументе. Для того чтобы разбить строку на основе разделительного символа (например, если нужно разбить признаки из файла пароля UNIX на части), используйте ($username, $password, $uid, $gid, $name, $home, $shell) = split(/:/, $line) В этом случае функция split о возвращает массив значений, найденных в строке, обозначенной $iine и отделенной двоеточием. В данной строке кода определены отдельные переменные для сохранения каждого элемента в массиве так, чтобы можно было использовать их значения более простым способом, чем индексация в массиве. Следующая общая функция позволяет манипулировать в Perl-программе временем и датой: ($s, $m, $h, $dy, $mo, $yr, $wd, $yd, $dst) = gmtime(); $mo++; # отсчет месяцев начинается с нуля. $уг+= 1900; # Perl возвращает значение года, начиная с 1900. print "The date is $mo/$dy/$yr.\n"; print "The time is $h:$m:$s.\n"; Предыдущий код выдает результат: The date is 4/25/2002. The time is 13:40:27. Обратите внимание, что функция gmtimeO возвращает 9 значений. Синтаксис языка Perl обязывает определить эти величины в круглых скобках (как если бы вы присваивали многочисленные значения массиву). Аргументы командной строки Еще одна полезная возможность состоит в том, что можно передавать аргументы командной строки Perl-скрипту. Скрипты shell предусматривают очень простой интерфейс к аргументам командной строки, в то время как программы С обеспечивают более сложный (но и более гибкий) интерфейс. Perl-интерфейс находится где-то между ними, как показано в следующем примере: $n = $#ARGV+1; # количество аргументов (начиная с нуля). print $n, " args: \п" ; for ( $i = 0 ; $i < $n ; $i++ ) { print " @ARGV[$i]\n"; }
Этот Perl-скрипт выводит число аргументов, которые были переданы программе peri (после имени Perl-скрипта) и затем распечатывает каждый аргумент на отдельной строке. Мы можем изменить рассмотренный ранее скрипт "фунты в доллары", чтобы позволить значению британских фунтов быть определенным в командной строке следующим образом: if ( $#ARGV < 0 ) { # если аргументы не заданы. print "Specify value in to convert to dollars\n"; exit $poundvalue = @ARGV[0]; # получить значения из командной строки. $dollarvalue = pounds2doliars($poundvalue); print "Value in dollars = $dollarvalue\n"; sub pounds2doliars { $EXCHANGE_RATE =1.54; # из $pounds = $_[0]; return ($EXCHANGE_RATE * $pounds); # изменить, когда необходимо. Пример из реального мира Все краткие предыдущие примеры должны были дать вам представление о том, как работает Perl. Но пока мы не сделали ничего действительно очень полезного. Поэтому давайте, воспользовавшись уже имеющимися у нас сведениями, напишем Perl-скрипт для печати таблицы о ссуде. Определим еще одну команду. Синтаксис loan -а величина -р платеж -г норма Программа loan печатает таблицу, заданный размер ссуды, норму процента и платеж, который должен быть сделан ежемесячно. Таблица показывает необходимое количество месяцев для выплаты ссуды, а также сколько процентов и какая основная сумма будут оплачены каждый месяц. Все аргументы необходимы. 7 Зак. 786
Perl-скрипт loan.pl доступен в сети (см. Введение) и похож на код: # show loan interest $i=0; while ( $i < $#ARGV) { # аргументы процесса if ( @ARGV[$i] eq ”-r" ) { $RATE=@ARGV[++$i]; # норма процента } else { if ( @ARGV[$i] eq "-a” ) { $AMOUNT=@ARGV[++$i]; # размер ссуда } else { if ( @ARGV[$i] eq "-p" ) { $PAYMEOT=@ARGV[++$i]; # размер платежа } else { print "Unknown argument (@ARGV[$i])\n"; exit } } } if ($AMOUNT == 0 || $RATE == 0 || $PAYMENT ==0) { print "Specify -r rate -a amount -p payment\n"; exit } print "Original balance: \$$AMOUNT\n"; print "Interest rate: ${RATE}%\n"; print "Monthly payment : \$$PAYMENT\n"; print "\n"; print "Month\tPayment\tInterest\tPrincipal\tBalance\n\n"; $month=l; $rate=$RATE/12/100; # получить фактическую ежемесячную норму процента $balance=$AMOUNT; $payment=$ PAYMENT; while ($balance > 0) { # цикл для нормы процента $interest=roundUpAmount($rate * $balance); $principal=roundUpAmount($payment — $interest);
if ( $balance < $principal ) { # последний платеж $principdl=$balance; # не платить слишком много! $payment=$principal + $interest; } $balance = roundUpAmount($balance — $principal); print "$month\t\$$payment\t\$$interest\t\t\$$principal\t\t\$$balance\n"; $month++; } sub roundUpAmount { # # in: floating point monetary value # out: value rounded (and truncated) to the nearest cent # $value=$_[0] ; $newvalue = ( int ( ( $value * 100 ) + .5 ) ) / 100; return ($newvalue); Если предполагается платить по $30 в месяц при балансе кредитной карточки в $300 и учитывать норму процента, как 12.9% годовой процентной ставки, то график оплаты напоминает следующее: Original balance: $300 Interest rate: 12.5% Monthly payment: $30 9 Month Payment Interest Principal Balance 1 $30 $3.13 $26.87 $273.13 2 $30 $2.85 $27.15 $245.98 3 $30 $2.56 $27.44 $218.54 4 $30 $2.28 $27.72 $190.82 5 $30 $1.99 $28.01 $162.81 6 $30 $1.7 $28.3 $134.51 7 $30 $1.4 $28.6 $105.91 8 $30 $1.1 $28.9 $77.01 9 $30 $0.8 $29.2 $47.81 10 $30 $0.5 $29.5 $18.31 11 $18.5 $0.19 $18.31 $0
Таким образом, потребуется 11 месяцев, чтобы оплатить баланс при платеже по $30 в месяц, но последний платеж будет только $18.31. Если есть желание погасить ссуду быстрее, чем за 11 месяцев, нужно поднять ежемесячную оплату! Обзор главы Перечень тем В этой главе вы познакомились с утилитами, которые: □ фильтруют файлы; П сортируют файлы; □ сравнивают файлы; □ архивируют файлы; □ производят поиск файлов; □ планируют команды; □ поддерживают программируемую обработку текста; П создают жесткие и символические связи; □ заменяют пользователей; П проверяют наличие почты; □ изменяют файлы; □ просматривают необработанное содержимое файла; П монтируют файловые системы; П подготавливают документы. Также было рассмотрено написание скриптов Perl. Контрольные вопросы 1. При каких условиях вы архивировали бы файлы, используя утилиту tar? 2. Как вы преобразовали бы содержание файла к прописным буквам? 3. В чем разница между утилитами стр и diff? 4. Опишите что, означает "монтирование” файловой системы. 5. Какой процесс обслуживает утилита crontab? 6. Какие дополнительные функциональные возможности имеет расширенное регулярное выражение? 7. В чем состоят главные отличия между утилитами sed и awk?
8. Как утилита awk получила свое имя? 9. При каких условиях вы использовали бы символическую связь вместо жесткой связи? 10. В чем заключаются недостатки использования символической связи? 11. Для чего предназначено инкрементное резервное копирование, и как бы вы выполнили его? 12. Какими способами Perl делает программирование скриптов более легким по сравнению с обычными скриптами shell? Упражнения 3.1. Выполните тесты измерения времени для утилит grep и fgrep, чтобы определить преимущество использования быстродействия fgrep. [Уровень: легкий.] 3.2. Попросите системного администратора продемонстрировать использование утилиты tar для выполнения резервного копирования ваших файлов на ленту. [Уровень: легкий.] 3.3. Используйте утилиту crontab, чтобы включить в расписание скрипт, который в начале каждого дня удаляет ваши старые базовые файлы. [Уровень: средний.] Проекты 1. Напишите командный конвейер, который сжимает содержание файла и затем шифрует его, используя известный ключ, а результат записывает в новый файл. Какой соответствующий командный конвейер должен принимать этот зашифрованный файл для дешифрования и разархивирования его, чтобы получить первоначальный файл? [Уровень: легкий.] 2. Напишите командный конвейер, который находит и сжимает файлы в иерархии каталогов (например, в вашем домашнем каталоге), к которым не было обращений в течение 30 дней. [Уровень: средний.] 3. Измените Perl-скрипт loan так, чтобы вы могли передавать ему список платежей, а не использовать каждый месяц один и тот же размер платежа. [Уровень: средний.]

Глава 4 Командные интерпретаторы shell Мотивация Shell — это программа-посредник между пользователем и ядром операционной системы. Существуют четыре shell, которые, как правило, входят в стандартную поставку UNIX: Bourne shell (sh), Korn shell (ksh), C shell (csh) и Bourne Again shell (bash). Все перечисленные оболочки поддерживают базовый набор возможностей, позволяющих управлять UNIX. Так, например, все командные интерпретаторы позволяют сохранять вывод процесса в файл или перенаправлять его на вход другого. В этой главе мы рассмотрим базовые функции командной оболочки, а в главах 5—8 обсудим особенности каждой из них. Предпосылки Для понимания этой главы вам необходимо усвоить материал первых двух глав. Кроме того, некоторые из упоминаемых утилит были рассмотрены в главе 3. Поэтому, в случае необходимости, прочитайте ее еще раз. Большим преимуществом для изучения материала будет наличие UNIX на вашем компьютере. Задачи В данной главе мы научимся использовать базовые возможности shell, такие как перенаправление ввода/вывода, конвейеризацию, управление заданиями. Изложение по сложившейся уже традиции в этой главе проиллюстрировано примерами UNIX-сессий, которые вы можете повторить на своем компьютере для более глубокого усвоения материала.
Утилиты Нам предстоит познакомиться со следующими утилитами: chsh nohup tee echo ps kill sleep Команды shell Вы научитесь пользоваться следующими командами: echo kill umask eval login wait exec shift exit Общие сведения о shell Shell — это программа-интерфейс между пользователем и операционной системой. Она позволяет работать с файлами, осуществлять перенаправление данных и выполняет немало других полезных функций. Существуют четыре основных командных интерпретатора: П Bourne shell (sh); П Korn shell (ksh); □ C shell (csh); □ Bourne Again shell (bash). Выбор командной оболочки — это, прежде всего, вопрос вкуса. Хотя у каждой оболочки есть свои особенности, например, С shell лучше приспособлен для диалоговой работы, чем Bourne shell, но в некотором отношении хуже для написания скриптов. Korn shell совмещает в себе положительные черты Bourne shell и С shell, а также поддерживает дополнительные полезные функции. Bash впитал в себя лучшие черты остальных программных оболочек. Bourne shell имеется в каждой версии UNIX. Другие командные интерпретаторы не обязательно будут присутствовать в вашей ОС. В главе 8 содержится немало информации о том, что делать, если ваша любимая оболочка не входит в стандартную поставку системы.
Функциональные возможности shell Рассмотрим более подробно, какие функциональные возможности присущи всем командным оболочкам. На рис. 4.1 изображена взаимосвязь различных командных интерпретаторов, а на рис. 4.2 представлена иерархия базовых функциональных возможностей shell. Рис. 4.1. Взаимосвязь функциональных возможностей различных shell Локальные Окружения Условные Безусловные Рис. 4.2. Базовые функциональные возможности shell Выбор shell Когда вам предоставляют имя для регистрации в UNIX, системный администратор определяет программную оболочку, которой вы будете пользоваться. Для того чтобы узнать, какая оболочка вам досталась, просмотрите на приглашение shell. Если вы видите приглашение %, то, скорее всего, вы пользуетесь С shell. Другие оболочки используют символ $ в качестве приглашения по умолчанию. Для изменения установленного по умолча
нию shell воспользуйтесь утилитой chsh. При этом необходимо знать месторасположение всех оболочек. В табл. 4.1 указано стандартное местоположение различных оболочек. Таблица 4.1. Местоположение shell Командный интерпретатор Полное имя Bourne shell /bin/sh Korn shell /bln/ksh C shell /bin/csh Bash /bin/bash Синтаксис chsh Утилита chsh позволяет изменить установленный по умолчанию входной shell. Необходимо указать местоположение командного интерпретатора, который будет использоваться во время ваших последующих входов в систему. Рассмотрим пример замены установленного по умолчанию Bourne shell на Korn shell: % chsh ...изменить входной shell c sh на ksh. Changing login shell for glass ...замена входного shell для glass Old shell: /bin/sh ...вывод путевого имени старого shell. New shell: /bin/ksh ...ввод полного путевого имени нового shell. % "D ...завершить входной shell. login: glass Password: ...войти в систему снова. ...секрет $ . ...в этот раз я в Korn shell. Для того чтобы определить месторасположение shell, воспользуйтесь следующим способом: $ echo $SHELL /bin/ksh $ ...выводит имя моего входного shell. ...полное путевое имя Korn shell.
Эти строки с помощью команды echo выводят место расположения оболочки, указанное в переменной окружения shell. Вывод данных с помощью echo и использование переменных окружения будет рассматриваться чуть позже. Функционирование shell При вызове shell, который либо инициируется автоматически во время входа в систему, либо запускается вручную из скрипта или с клавиатуры, выполняется следующая последовательность действий: 1. Оболочка читает специальный файл запуска, обычно расположенный в домашнем каталоге пользователя. Этот файл содержит некоторую инициализирующую информацию. Последовательность запуска каждого shell различна, поэтому пока не будем останавливаться на конкретных деталях. 2. Выводится приглашение и ожидается пользовательская команда. 3. Если пользователь нажал комбинацию клавиш <Ctrl>+<D>, это интерпретируется shell, как "конец ввода", после чего командный интерпретатор завершает работу. Иначе shell выполняет команду пользователя и возвращается к шагу 2. Команды могут представлять собой как простой вызов отдельной утилиты, например: $ 1S так и сложный конвейер последовательно выполняющихся команд: $ ps -ef I sort ul -tdumb I Ip При необходимости ввести команду, которая превышает размер строки, воспользуйтесь символом обратной косой черты (\), а затем продолжите набор на следующей строке: $ echo это - очень длинная команда shell, и поэтому необходимо \ пользоваться специальным символом для продолжения набора \ на другой строке. \ Обратите внимание, что команда может занимать несколько строк. \ это - очень длинная команда shell, и поэтому необходимо пользоваться специальным символом для продолжения набора на другой строке. Обратите внимание, что команда может занимать несколько строк. $ _ Исполняемые файлы и встроенные команды Большинство команд UNIX вызывает утилиты, которые хранятся в каталогах. Код утилит находится в исполняемых файлах. Например, когда вы печатаете $ 1S
командная оболочка определяет местоположение исполняемой программы, по имени is, которая обычно находится в каталоге /bin, и выполняет ее. (Алгоритм поиска нужной утилиты будет рассмотрен чуть позже.) Кроме способности определять месторасположение утилиты shell имеет несколько встроенных команд, которые выполняются непосредственно оболочкой. Сейчас мы рассмотрим наиболее полезные из них — echo и cd. Вывод информации на экран: echo Встроенная команда echo выводит свои данные, указанные в качестве аргументов, на стандартный вывод. Все командные интерпретаторы имеют эту встроенную функцию, но кроме нее может быть использована и утилита echo (которая по умолчанию находится в каталоге /bin). Если вы пишете скрипты для различных shell, использование утилиты оправданно, т. к. в разных командных оболочках встроенные команды могут вести себя по-разному и требовать различных аргументов. Синтаксис echo {аргументы} ★ Встроенная команда shell echo (эхо) выводит следующие за ней аргументы на стандартный выход. По умолчанию форматирует данные, используя символ перевода строки. Смена каталогов: cd Со встроенной командой cd, изменяющей текущий рабочий каталог, мы познакомились в главе 2. Метасимволы Некоторые знаки обрабатываются shell специальным образом и называются метасимволами. Все командные интерпретаторы поддерживают основной набор метасимволов, представленных в табл. 4.2. После ввода команды shell анализирует ее на наличие метасимволов и обрабатывает их специальным образом. Таблица 4.2. Метасимволы shell Символ Описание Перенаправление вывода; записывает стандартный вывод в файл Перенаправление вывода; добавляет стандартный вывод в файл
Таблица 4.2 (окончание) Символ Описание < Перенаправление ввода; читает стандартный ввод из файла ★ Групповой символ замены файла; соответствует нулю или большему количеству символов 9 Групповой символ замены файла; соответствует любому единственному символу [. .] Групповой символ замены файла; соответствует любому символу между скобками 'команда' Замещение команды; заменяется выводом команды I Символ конвейера; посылает вывод одного процесса на ввод другого г Используется в последовательности команд I Условное выполнение; выполняет команду, если предыдущая завершилась с ошибкой && Условное выполнение; выполняет команду, если предыдущая команда была успешной ( • • ) Группирует команды & Выполняет команду в фоновом режиме # Все символы, которые следуют за #, до символа перевода строки, игнорируются shell и программами (т. е. символизирует комментарий) $ Раскрывает значение переменной \ Предотвращает специальную интерпретацию следующего символа << tok Переназначение ввода; читает стандартный ввод из скрипта до tok После обработки метасимволов выполняется сама команда. Для того чтобы отменить интерпретацию символа, как специального, используйте перед ним косую черту (\). Например: $ echo hi > file $ cat file hi $ echo hi \> file hi > file $ ...сохранить вывод echo в file. ...посмотреть содержимое file. ...запретить метасимвол >. ...> интерпретируется подобно другим символам. ...и вывод идет на терминал вместо файла.
Перенаправление ввода/вывода Средство перенаправления позволяет: □ сохранить вывод процесса в файл (перенаправление вывода)} П использовать содержимое файла как входные данные процесса (переназначение ввода). Рассмотрим эти задачи подробнее. Перенаправление вывода Перенаправление вывода удобно, т. к. дает возможность сохранить вывод процесса в файл, который может быть просмотрен, напечатан, отредактирован или использован как вход для другого процесса. Чтобы перенаправить вывод, используйте метасимволы > или ». Последовательность $ команда > имяФайла посылает стандартный вывод команды в файл с именем имяФайла. Командный интерпретатор создает файл с именем имяФайла, если тот еще не существует, или перезаписывает его предыдущее содержимое. Если файл существует и не имеет разрешения на запись, выводится сообщение об ошибке. Создадим файл alice.txt, в который перенаправим вывод утилиты cat. Вызываемая без параметров утилита cat просто записывает данные, полученные со стандартного входа (в данном случае с клавиатуры) на свой стандартный вывод: $ cat > alice.txt ...создать текстовый файл. In ту dreams that fill the night, I see your eyes, ... конец ввода. $ cat alice.txt ...посмотреть его содержимое. In my dreams that fill the night, I see your eyes, $ _ Последовательность $ команда » имяФайла добавляет стандартный ВЫВОД команды В файл С именем имяФайла. Командный интерпретатор создает файл с именем имяФайла, если тот еще не существует. Добавим какой-нибудь текст к созданному ранее файлу alice.txt: $ cat » alice.txt ...добавить к файлу. And I fall into them, Like Alice fell into Wonderland.
..конец ввода. $ cat alice.txt ...посмотреть новое содержимое. In my dreams that fill the night, I see your eyes, And I fall into them, Like Alice fell into Wonderland. $ _ По умолчанию обе формы перенаправления выводят на терминал сообщение об ошибке в случае сбоя. В С shell, Korn shell и Bash также предусмотрена защита против случайного переписывания файла из-за переназначения вывода. (Эти возможности подробно описаны в следующих главах.) Переназначение ввода Переназначение ввода полезно, поскольку исходные данные для выполнения команды можно взять из файла, созданного ранее. Чтобы переназначить ввод, используйте метасимволы < или «. Последовательность $ команда < имяФайла выполняет команду, используя содержимое файла имяФайла, как стандартный ввод. Если файл не существует или не имеет разрешения на чтение, выводится сообщение об ошибке. Для примера перешлем содержимое созданного нами файла alice.txt, используя УТИЛИТУ mail: $ mail glass < alice.txt ...послать почту самому себе. $ mail ...посмотреть свою почту. Mail version SMI 4.0 Sat Oct 13 20:32:29 PDT 1990 Type ? for help. >N 1 glass@utdallas.edu Mon Feb 2 13:29 17/550 & 1 ...прочитать сообщение #1. From: Graham Glass <glass@utdallas.edu> To: glass@utdallas.edu In my dreams that fill the night, I see your eyes, And I fall into them, Like Alice fell into Wonderland & q ... завершить работу c mail. $ _ Последовательность $ команда « слово
позволяет скопировать в буфер входные данные до слова, а затем выполняет команду, используя буфер. Чуть позже мы рассмотрим эту возможность, которая используется в основном для передачи потока данных другим командам. Групповые символы поиска файлов Все командные оболочки поддерживают возможность поиска по шаблону. Любое слово в командной строке, которое содержит, по крайней мере, один метасимвол, рассматривается как шаблон и заменяется отсортированным в алфавитном порядке списком всех соответствующих ему имен файлов. Эта процедура называется globbing (универсализация файловых имен). В табл. 4.3 приведены такие символы и их значения. Таблица 4.3. Символы поиска в shell Групповой символ Описание * Соответствует любой строке, включая пустую строку ? Соответствует любому единственному символу [ • - ] Соответствует любому из символов в скобках. Диапазон символов может быть определен, разделением пары символов чертой Вы можете запретить командному интерпретатору обрабатывать шаблоны в строке, заключив их в апострофы или двойные кавычки. Вот несколько примеров использования шаблонов: $ Is -FR ...рекурсивно выводит мой текущий каталог, а.с Ь.с сс.с dirl/ dir2/ dirl: d.c e.e dir2: f.d g. c $ 1s *. с ...любой текст с последующим .с. а. с Ь.с сс.с $ 1s ?.с . ...один символ с последующим .с. а. с Ь >. с $ Is /ас] * ...любая строка, начинающаяся с "а" или "с" а. с сс.с $ Is [A-Za-z]* ...любая строка, начинающаяся с буквы.
а. с Ь. с сс. с $ Is dir*/*.с ...все .с-файлы в каталоге dir*. dirl/d.c dir2/g.c $ Is */*.c ...все .с-файлы в любом подкаталоге. dirl/d.c dir2/g.c $ Is *2/?. ? ?.? а.с Ь.с dir2/f.d dir2/g.c $ _ Программные оболочки по-разному обрабатывают случаи, когда не найдено ни одного соответствия шаблону. Конвейеры Командный интерпретатор позволяет использовать стандартный вывод одного процесса как стандартный ввод другого путем их соединения через конвейер с помощью метасимвола |. Последовательность $ команда! | команда2 направляет стандартный вывод команды! на стандартный ввод команды2. Конвейером (pipeline) может быть связано любое количество команд. Конвейеры реализуют основную философию UNIX, исходя из которой большие задачи должны состоять из цепочки более мелких, решаемых предназначенными для этого утилитами. Стандартный канал вывода ошибок передается через стандартный конвейер, хотя некоторые shell поддерживают эту возможность. В приведенном ниже примере перенаправим вывод утилиты 1s на вход утилиты wc (рис. 4.3), чтобы посчитать количество файлов в текущем каталоге (сл/. главу 2 для получения информации о wc): $ Is . ..посмотреть текущий каталог. а.с Ь.с сс.с dirl dir2 $ Is I wc -w ... считать элементы 5 $ Рис. 4.3. Пример конвейера
В следующем примере перенаправим содержимое файла etc/passwd в утилиту awk для того, чтобы извлечь первое поле каждой строки. Вывод awk после этого перенаправим утилите sort, которая отсортирует строки в алфавитном порядке (рис. 4.4). В результате получим отсортированный список всех пользователей системы. $ head -4 /etc/passwd ...просмотреть файл password. root:eJ2S10rVe8mCg:0:1:Operator:/:/bin/csh nobody:*:65534:65534::/: daemon:*:1:1::/: sys:*:2:2::/:/bin/csh $ cat /etc/passwd | awk -F: '{print $1}' I sort audit bin daemon glass ingres news nobody root sync sys tim uucp $ Терминал Рис. 4.4. Сортирующий конвейер Есть очень удобная утилита tee, позволяющая копировать вывод конвейера в файл и в то же время передавать эти данные дальше по конвейеру. Название этой утилиты навеяно Т-соединением. Синтаксис tee -ia {имяФайла} + Утилита tee записывает данные, которые получает на стандартный вход, в файл и одновременно передает их по конвейеру другим утили
там. Опция -а дописывает данные в конец файла. Опция -i игнорирует прерывания. Скопируем вывод утилиты who в файл who.capture и одновременно передадим информацию дальше к утилите sort: $ who I tee who.capture I sort ables ttyp6 May 3 17:54 (gw.Waterloo.com) glass ttypO May 3 18:49 (bridgeOS.utdalla) posey ttyp2 Apr 23 17:44 (blackfoot.utdall) posey ttyp4 Apr 23 17:44 (blackfoot.utdall) $ cat who.capture ...посмотреть захваченные данные. glass ttypO May 3 18:49 (bridgeOS.utdalla) posey ttyp2 Apr 23 17:44 (blackfoot.utdall) posey ttyp4 Apr 23 17:44 (blackfoot.utdall) ables ttyp6 May 3 17:54 (gw.Waterloo.com) $ . Замещение команды Команда, окруженная обратными штрихами ('), выполняется, после чего замещается результатом своей работы. Любой перевод строки в выводе данных заменяется пробелами, как в следующих примерах: $ echo the date today is 'date' the date today is Mon Feb 2 00:41:55 CST 1998 $ _ Это дает возможность применять хитрости, передавая, таким образом, результат выполнения команды в конвейер. Например, утилита who (о которой рассказывается в главе 9) выводит список всех пользователей в системе, а утилита wc (описанная в главе 2) подсчитывает число слов или строк в данных со стандартного входа. Объединяя конвейером вывод утилиты who с утилитой wc, можно сосчитать количество пользователей на системе: $ who posey ttypO Jan 22 15:31 (blackfoot:0.0) glass ttyp3 Feb 3 00:41 (bridge05.utdalla) huynh ttyp5 Jan 10 10:39 (atlas.utdallas.e) $ echo there are who I wc -1' users on the system there are 3 users on the system $
Вывод результатов выполнения одной команды может использоваться, как часть другой. Например, утилита vi позволяет указать в командной строке список файлов, которые будут отредактированы. В этом случае они открываются редактором один за другим. Утилита grep, вызываемая с опцией -1, описанная в главе 3, выводит в командной строке список всех файлов, соответствующих указанному шаблону. С помощью замещения команды (вывод результатов ее работы) можно одной строкой заставить редактор vi отобразить список всех файлов, заканчивающихся на .с и соответствующих шаблону debug: $ vi 'grep -1 debug *.c' Последовательности Если пользователь вводит серию простых команд или конвейеров, отделенных точкой с запятой (;), shell будет выполнять их последовательно, слева направо. Эту возможность можно применять для ’’опережающего ввода с клавиатуры" тем пользователям, которые любят определять всю последовательность действий сразу. Например: $ date; pwd; Is ...выполнить три команды в последовательности. Mon Feb 2 00:11:10 CST 1998 /home/glass/wild а. с Ь.с сс.с dirl dir2 $ _ Каждая команда в представленной последовательности может иметь индивидуально переадресованный ввод/вывод, как показано в следующем примере: $ date > date.txt; Is; pwd > pwd. txt a.c b.c cc.c date.txt dirl dir2 $ cat date.txt ...посмотреть вывод date. Mon Feb 2 00:12:16 CST 1998 $ cat pwd. txt ...посмотреть вывод pwd. /home/glass $ _ Условные последовательности Каждый UNIX-процесс возвращает определенное значение при завершении. Если процесс возвращает 0, это значит, что ошибок не было, и процесс завершился успешно. В противном случае возвращается 1. Все встроенные
команды shell возвращают 1, если в процессе выполнения произошел сбой. Можно использовать эту информацию следующим образом: □ если вы задаете последовательность команд, отделенных символами &&, следующая команда выполняется только в случае, если предыдущая команда возвращает 0; П если вы задаете последовательность команд, отделенных символами | |, следующая команда выполняется в случае, если предыдущая команда возвращает 1. Метасимволы && и | | эквивалентны соответствующим операторам С и обозначают логическое and и or. Например, если в процессе компиляции программы в сс (С-компилятор) не обнаружено фатальных ошибок, создается выполняемая программа a.out и возвращается 0. В противном случае возвращается значение, отличное от 0. Приведенная ниже строка компилирует программу с именем myprog.c и выполняет файл a.out в случае, если компиляция прошла успешно: $ cc myprog.c && a.out Следующий пример в случае неудачи выводит сообщение об ошибке: $ cc myprog.c || echo compilation failed. Группирование команд Команды могут быть сгруппированы путем заключения их в круглые скобки, что заставляет дочерний shell (subshell) выполнить их. Этим командам доступны те же возможности, что и обычным: перенаправление и конвейеризация, использование стандартного ввода и вывода, канала сообщения об ошибках: $ date; Is; pwd > out. txt Mon Feb 2 00:33:12 CSTxl998 a. c b. c $ cat out.txt /home/glass $ (date; Is; pwd) > out. txt Background Processing 159 $ cat out.txt Mon Feb 2 00:33:28 CST 1998. ...выполнить последовательность ...вывод утилиты date. ...вывод утилиты Is. ...только pwd была перенаправлена. ...сгруппировать и затем перенаправить. ...все выводы были перенаправлены. а. с Ь. с /home/glass $
Фоновое выполнение Если вы завершаете простую команду, конвейер, последовательность конвейеров или группу команд метасимволом &, создается дочерний shell для выполнения команды в фоновом режиме, который работает одновременно с родительским shell и не взаимодействует с клавиатурой. Режим очень полезен для выполнения нескольких задач одновременно, если они не требуют ввода с клавиатуры. В системах с графическим интерфейсом принято выполнять каждую команду в отдельном окне, а не использовать для этого возможность фоновой обработки. Когда создается фоновый процесс, shell выводит информацию, которая может применяться в дальнейшем для управления этим процессом. Формат такой информации различен для каждого shell. Для того чтобы найти файл с именем а.с, вызовем утилиту find в приоритетном режиме. Она выполняется достаточно долго, поэтому запустим еще раз find в фоновом режиме. В этом случае shell выведет ID (уникальный номер) фонового процесса и приглашение, предлагая тем самым продолжить работу. Вывод результатов работы фонового процесса будет появляться на основном терминале, что, согласитесь, неудобно. Мы научимся использовать ID для управления процессом и подавления вывода результатов на основной терминал в следующих разделах этой главы. Приведенный ниже пример иллюстрирует поиск файла а.с: $ find . -пате а.с -print /wild/а.с /reverse/tmp/а.с $ find . -name Ь.с -print & 27174 $ date /wild/Ь.с Mon Feb 2 18:10:42 CST 1998 $ ./reverse/tmp/b.c ...появился после ...поиск а.с. ...поиск в фоновом режиме. ...ID процесса. ...запуск date в приоритетном режиме. вывод произведен фоновой утилитой find, вывод утилиты date. еще от фоновой утилиты find. того, как мы получили приглашение shell, ...поэтому мы не увидели нового приглашения. Вы можете задать несколько фоновых вызовов в одной строке, отделяя их друг от друга амперсантом, как показано в следующем примере: $ date & pwd & 27310 27311 Mon Feb 2 18:37:22 CST 1998 /home/glass $ ...создать два фоновых процесса. ...ID процесса для date. ...ID процесса для pwd. ...вывод утилиты date. . . . вывод утилиты pwd.
Перенаправление фоновых процессов Перенаправление вывода Чтобы воспрепятствовать отображению фонового процесса на терминале, перенаправьте его вывод в файл. В следующем примере показана переадресация стандартного вывода утилиты find в файл find.txt. По мере выполнения команды можно наблюдать увеличение занимаемого им объема, исполь зуя утилиту is: $ find. . -name а. с 27188 $ Is -1 find.txt -rw-r—r— 1 glass $ Is -1 find.txt -rw-r—r— 1 glass $ cat find.txt ./wild/а.c -print > find-, txt & ...ID процесса для find. ...посмотреть find.txt. 0 Feb 3 18:11 find.txt ...наблюдать его увеличение. 29 Feb 3 18:11 find.txt ...просмотреть find.txt. ./reverse/tmp/а.c $ Другой альтернативой является отправка вывода по почте самому себе, как показано в приведенном ниже примере: $ find . -name а. с -print I mail glass & 27193 $ сс program.с ...выполнять другую полезную работу. $ mail ...читать свою почту. Mail version SMI 4.0 Sat Oct 13 20:32:29 PDT 1990 Type ? for help. >N 1 glass@utdallas.edu Mon Feb 3 18:12 10/346 & 1 From: Graham Glass <glass@utdallas.edu> To: glass@utdallas.edu ./wild/a.c ...вывод утилиты find. ./reverse/tmp/а.c & g $ _ Некоторые утилиты также осуществляют вывод в стандартный канал ошибок, который должен быть перенаправлен в дополнение к стандартному выводу. В следующей главе подробно описано, как это делается, а сейчас просто приведем пример реализации этой возможности в Bourne Korn shell: $ man ps > ps.txt & ...сохранить документацию в фоновом режиме. 27203
$ Reformatting page. Wait done man ps > ps.txt 2>&1 & 27212 $ ...приглашение shell появилось здесь. ...стандартное сообщение об ошибке. ...перенаправление канала ошибок. ...все выводы перенаправлены. Перенаправление ввода Когда фоновый процесс пытается читать данные с терминала, последний автоматически посылает ему сигнал ошибки, который приводит к завершению процесса. Представленный ниже пример иллюстрирует запуск утилиты chsh в фоновом режиме. Сразу после запуска появляется сообщение, что терминал не был изменен. Если же мы запустим фоновое выполнение утилиты mail, на нашем экране отобразится строка "No message !?!" ("Нет сообщения!?!"): $ chsh & ...запуск chsh, как фонового процесса. 27201 $ Changing NTS login shell for glass on csservrl. Old shell: /bin/sh New shell: Login shell unchanged. ...не ожидает ввода. mail glass & ...запуск mail, как фонового процесса. 27202 $ No message !?! ...не ожидает ввода с клавиатуры. Программы shell: скрипты Любая последовательность команд shell может быть сохранена в обычном текстовом файле и выполнена позднее. Файл, который содержит команды shell, называется скриптом. Прежде чем выполнить скрипт, необходимо установить разрешение на его выполнение с помощью утилиты chmod. Далее для запуска скрипта потребуется лишь указать его имя. Скрипты полезны для хранения часто используемых последовательностей команд. Могут состоять как из одной, так и из нескольких сотен строк. Структуры управления, встроенные в shell, достаточно мощны, чтобы решать широкий диапазон задач. Скрипты значительно облегчают работу системного администратора, автоматизируя такие задачи, как предупреждение пользователей о превышении объема дискового пространства, мониторинг системы и т. д. При запуске скрипта система определяет, для какого командного интерпретатора он был написан, и затем запускает оболочку, используя содержимое файла скрипта как стандартный ввод. Чтобы определить оболочку, для ко
торой написан скрипт, программа анализирует его первую строку, используя следующие правила: П если первая строка содержит только символ #, то скрипт интерпретируется тем shell, из которого он был вызван; П если первая строка имеет формат ?#.' путевоеИмя, тогда для интерпретации используется программа, месторасположение которой указано в параметре путевоеИмя', □ если ни одно из двух первых правил не применимо, то скрипт интерпретируется Bourne shell. Если символ # появляется на любой строке кроме первой, все символы до конца этой строки рассматриваются как комментарий. Комментирование скриптов является хорошим тоном программирования, облегчающим работу с кодом. Для указания оболочки, интерпретирующей скрипт, лучше всего использовать формат #!, т. к. он понятен всем командным интерпретаторам. Приведенный ниже пример иллюстрирует содержимое и выполнение скриптов для С shell и Korn shell: $ cat > script.csh #l/bin/csh ...создать скрипт для C shell. # Это пример скрипта для С shell. echo -n the date today is date # в csh,, -n опускает перевод строки # вывести сегодняшнюю дату. ... конец ввода. $ cat > script.ksh ...создать скрипт для Korn shell. #/ /bin/ksh # Это пример скрипта для Korn shell. echo "the date today is \c" Ив ksh, \c опускает перевод строки date # вывести сегодняшнюю дату. ... конец ввода. $ chmod +х script.csh script.ksh ...сделать их исполняемыми. $ Is -IF script.csh script.ksh ...посмотреть атрибуты. -rwxr-xr-x 1 glass 138 Feb 1 19:46 script.csh* -rwxr-xr-x 1 glass 142 Feb 1 19:47 script.ksh* $ script.csh ...выполнить скрипт C shell. the date today is Sun Feb 1 19:50:00 CST 1998 $ script.ksh ... выполнить. скрипт Korn shell. the date today is Sun Feb 1 19:50:05 CST 1998
Расширения csh и ksh в данном примере используются только для ясности; скрипты могут называться как угодно и даже не нуждаются в расширении. Обратите внимание на использование \с и -п в качестве аргументов утилиты echo. Вид символа запрещения перевода строки способен варьироваться в зависимости от версии утилиты. Это может зависеть также от используемого shell: если оболочка имеет встроенную функцию echo, то специфические особенности утилиты не имеют значения. Дочерние shell Когда вы регистрируетесь в системе UNIX, запускается командный интерпретатор. Этот shell выполняет любые вводимые вами команды. Однако в некоторых случаях ваш текущий (родительский) shell создает новый (дочерний) для выполнения некоторых задач: □ родительский shell создает дочерний shell, чтобы выполнить сгруппированные утилиты, такие как is, pwd, date. Если команда выполняется не в фоновом режиме, то родительский shell бездействует до тех пор, пока дочерний не завершит работу; П при выполнении скрипта родительский shell создает дочерний, чтобы его выполнить; П если задание выполняется в фоновом режиме, родительский shell также создает дочерний shell и продолжает работать одновременно с ним. Дочерний shell называется subshell. Точно так же как любой другой процесс UNIX, subshell имеет свой собственный текущий рабочий каталог, так что перемещение при помощи команды cd, выполненное в subshell, не затрагивает родительской оболочки. Рассмотрим пример: $ pwd ...вывести текущий каталог моего входного shell. /home/glass $ (cd /; pwd) ...subshell перемещает и выполняет pwd. / ...вывод исходит от subshell. $ pwd ...мой входной shell никогда не перемещался, /home/glass $ _ Каждый shell содержит две области данных: пространство переменных окружающей среды и пространство локальных переменных. Дочерний shell наследует копию пространства переменных окружающей среды своего родителя и получает чистое пространство локальных переменных, как показано на рис. 4.5. '
Дочерний shell Рис. 4.5. Области данных subshell Переменные Командный интерпретатор поддерживает два вида переменных: переменные окружения и локальные. Оба типа являются строковыми. Основное различие между ними в том, что переменные окружения наследуются при запуске дочернего shell, в то время как локальные переменные не передаются. В переменных окружения хранится информация, передаваемая между родительским и дочерним shell. Каждый shell имеет набор предопределенных переменных окружения, которые обычно инициализируются файлами запуска, описанными в следующих главах. Аналогично, каждый shell имеет набор предустановленных локальных переменных. Однако и те, и другие могут быть созданы в случае необходимости, что очень удобно для написания скриптов. В табл. 4.4 перечислены предопределенные переменные окружения, общие для всех shell. Таблица 4.4. Предопределенные переменные окружения Имя Описание $НОМЕ Полное путевое имя пользовательского домашнего каталога $РАТН Список каталогов для поиска команд $MAIL Полное путевое имя пользовательского почтового ящика $USER Ваше имя пользователя $SHELL Полное путевое имя пользовательского входного shell $TERM Тип пользовательского терминала
Синтаксис назначения переменных отличается в разных shell, но способ, которым вы получаете доступ к переменным, один и тот же: при добавлении приставки $ к имени переменной эта символическая последовательность заменяется значением указанной переменной. Чтобы создать переменную, просто присваивают ей значение: variableName=value ...не ставьте пробелы вокруг =. В следующем примере выводятся значения некоторых общих переменных окружающей среды shell: $ echo HOME = $НСМЕ, PATH = $РАТН . . .вывести две переменных. НОМЕ = /home/glass, PATH = /bin:/usr/bin:/usr/sbin $ echo MAIL = $MAIL ...вывести другую. MAIL = /var/mail/glass $ echo USER = $USER, SHELL = $SHELL, TERM=$TERM USER = glass, SHELL = /bin/sh, TERM=vtlOO $ _ Приведенный ниже пример иллюстрирует различие между локальными переменными и переменными окружающей среды. Присвоим значение двум локальным переменным и затем сделаем одну из них переменной окружающей среды, используя команду export Bourne shell (подробно описанную главе 5). Затем создадим дочерний Bourne shell и выведем значения переменных, для которых было выполнено присвоение в родительском shell. Обратите внимание, что значение переменной окружающей среды было скопировано в дочерний shell, а значение локальной переменной нет. В конце нажмем комбинацию клавиш <Ctrl>+<D>, чтобы завершить работу дочернего shell и возобновить выполнение родительского, а потом выведем первоначальные переменные: $ firstname=Graham ...присвоить значение локальной переменной. $ lastname=Glass ...присвоить значение другой локальной переменной. $ echo $firstname $lastname ...вывести их значения. Graham Glass $ export lastname ...сделать lastname переменной окружающей среды. $ sh ...запустить дочерний shell; родительский приостановлен. $ echo $firstname $lastname ...вывести значения снова. Glass ...заметьте, что firstname не было скопировано. $ ...завершить дочерний; родительский возобновлен. $ echo $firstname $lastname ...они остались неизменными. Graham Glass $
В табл. 4.5 приведено несколько общих встроенных переменных, имеющих специальное значение. Первая специальная переменная особенно полезна для создания временных имен файлов, а остальные — для доступа к аргументам командной строки в скриптах shell. Ниже в примере были использованы все специальные переменные: $ cat script.sh ...вывести скрипт. echo the name of this script is $0 echo the first argument is $1 echo a list of all the arguments is $* echo this script places the date into a temporary file ecAo called $1.$$ date >$1.$$ # перенаправить вывод date. Is $1.$$ # посмотреть файл. rm $1.$$ # удалить файл. $ script.sh paul ringo george john ...выполнить его. the name of this script is script.sh the first argument is paul a list of all the arguments is paul ringo george john this script places the date into a temporary file called paul.24321 paul.24321 $ Таблица 4.5. Специальные встроенные переменные shell Имя Описание $$ ID процесса shell Имя скрипта shell (если применимо) $1. . $ 9 ссылается на n-й аргумент командной строки (если применимо) $ * Список всех аргументов командной строки Использование кавычек Часто бывает необходимо заместить групповой символ переменной или использовать механизмы замещения команд. Система расстановки кавычек shell позволяет сделать именно это.
Существуют правила их расстановки: □ одинарные кавычки1 (’) подавляют замещение группового символа, переменной и команды; П двойные кавычки (") подавляют замещение только группового символа; □ если кавычки вложены, то внешние кавычки не вызывают замещение. Следующий пример иллюстрирует различие между двумя видами кавычек: $ echo 3*4 =12 ...помните, * — это групповой символ. 3 а.с Ь.с с.с 4 = 12 $ echo "3 * 4 = 12" ...двойные кавычки подавляют групповые символы. 3 * 4 = 12 $ echo '3 * 4 = 12' ...одинарные кавычки подавляют групповые символы. 3 * 4 = 12 $ name=Graham Заключая текст в одинарные кавычки, мы подавляем подстановку группового символа, переменной и команды: $ echo 'ту name is $пате - date is 'date'' my name is $name - date is 'date' Заключая текст в двойные кавычки, мы подавляем подстановку группового символа, но разрешаем замещение переменной и команды: $ echo "ту name is $пате - date is 'date'" my name is Graham - date is Mon Feb 2 23:14:56 CST 1998 $ _ Перенаправление ввода в буфер shell Ранее в этой главе мы уже упомянули метасимвол «, и теперь пришло время поговорить о нем подробнее. Когда shell сталкивается с последовательностью вида $ команда « слово он копирует собственный стандартный ввод до строки, начинающейся со слова, в буфер shell и затем выполняет команду, используя содержимое буфера в качестве своего стандартного ввода. Если слово не встречается в тексте, Bourne shell и Korn shell прекращают копировать ввод, когда они достигают конца скрипта, а С shell выводит сообщение об ошибке. Все ссылки на переменные shell в скопированном тексте заменяются их значениями. 1 В книге также встречается название "апострофы". — Ред.
Чаще всего метасимвол « используется при передаче данных из скрипта на стандартный ввод других команд без применения вспомогательных файлов. Пример: $ cat here.sh ...посмотреть пример. mail $1 « ENDOFTEXT Dear $1, Please see me regarding some exciting news! - $USER ENDOFTEXT echo mail sent to $1 $ here.sh glass ...послать почту самому себе, используя скрипт. • I mail sent to glass $ mail ...посмотреть свою почту. Mail version SMI 4.0 Sat Oct 13 20:32:29 PDT 1990 Type ? for help. >N 1 glass@utdallas.edu Mon Feb 2 13:34 12/384 & 1 ...прочитать сообщение #1. From: Graham Glass <glass@utdallas.edu> To: glass@utdallas.edu Dear glass, Please see me regarding some exciting news! glass & q ...завершить работу утилиты mail. $ Управление работой Поддержка многозадачности — одна из привлекательнейших особенностей UNIX, и чтобы использовать ее в полной мере, важно иметь возможность управлять процессами. Помогут в этом деле две утилиты и одна встроенная команда: □ утилита ps генерирует список процессов и их атрибуты, такие как имена, ID процессов, управляющие терминалы и имена входа владельцев; □ утилита/команда kill завершает процесс, используя его ID; □ команда wait указывает shell на необходимость подождать завершения одного из дочерних процессов.
Статус процесса: ps Утилита ps позволяет осуществлять контроль статуса текущих процессов. Используем утилиту sleep, чтобы задержать работу команды echo и выполнить ее в фоновом режиме. Далее запустим утилиту ps, чтобы получить список текущих процессов. Все процессы принадлежат sh — Bourne shell: $ (sleep 10; echo done) & 27387 $ ps PID TTY TIME CMD 27355 pts/3 0:00 -sh 27387 pts/3 0:00 -sh 27388 pts/3 0:00 sleep 10 27389 pts/3 0:00 PS $ done ...задержать echo в фоновом режиме. ...ID процесса. ...получить список статуса процессов. ...входной shell. ...subshell. ...утилита sleep. ...сама команда ps! ...вывод из фонового процесса. Синтаксис ps -efl Утилита ps выводит информацию о статусе процесса. По умолчанию вывод ограничен процессами, созданными текущим пользовательским shell. Опция -е указывает ps на необходимость включить в список все процессы, которые в настоящее время выполняются. Опция -f выводит полный список. Опция -1 генерирует расширенный список. Синтаксис sleep секунды Утилита sleep выставляет таймер на указанное количество секунд, после чего завершается. В табл. 4.6 описаны значения полей утилиты ps. Таблица 4.6. Значения полей вывода утилиты ps Поле Описание S Состояние процесса UID Эффективный пользовательский ID процесса
Таблица 4.6 (окончание) Поле Описание PID ID процесса PPID ID родительского процесса С Процент времени ЦП, что использовал процесс в последнюю минуту PRI Приоритет процесса SZ Размер данных и стека процесса в килобайтах STIME Время создания процесса или дата, если процесс был создан не сегодня TTY Управляющий терминал TIME Время ЦП, использованное до настоящего момента (в формате ММ: ss) CMD Имя команды Табл. 4.7 иллюстрирует значения данных в поле s, описывающем состояние процесса. Таблица 4.7. Коды состояния процесса, сообщаемые утилитой ps Значение Описание 0 Работает на процессоре R Работоспособный S Спящий т Приостановленный Z "Убитый" процесс Значения большинства этих параметров будут описаны позже. Однако сейчас необходимо остановиться на значении двух полей - r и s: $ (sleep 10; echo done) & 27462 $ ps -f ...запрос ориентированного на пользователя вывода. UID PID PPID C STIME TTY TIME CMD glass 731 728 0 21:48:46 pts/5 0:01 -ksh glass 831 830 1 22:27:06 pts/5 0:00 sleep 10 glass 830 731 0 22:27:06 pts/5 0:00 -ksh $ done ...вывод предыдущей команды 8 Зак. 786
Если вас интересует работа других пользователей, воспользуйтесь опциями -е и -f утилиты ps: $ ps -ef ...вывести все пользовательские процессы. UID PID PPID С STIME TTY TIME CMD root 0 0 0 18:58:16 ? 0:01 sched root 1 0 0 18:58:19 9 0:01 /etc/init - root 2 0 0 18:58:19 9 0:00 pageout root 3 0 1 18:58:19 9 0:53 fsflush root 198 1 0 18:59:38 ? 0:00 /usr/sbin/nscd root 178 1 0 18:59:35 ? 0:00 /usr/sbin/syslogd root 302 1 0 18:59:58 9 0:00 /usr/lib/saf/sac root 125 1 0 18:59:14 9 0:00 /us r/sbin/rpcbind root 152 1 0 18:59:29 9 0:01 /usr/sbin/inetd -s root 115 1 0 18:59:13 9 0:00 /usr/sbin/in.routed -q root 127 1 0 18:59:15 9 0:00 /usr/sbin/keyserv root 174 1 0 18:59:34 9 0:00 /etc/automountd glass 731 728 0 21:48:46 p5 0:01 -ksh $ _ В главе 5 мы рассмотрим программу track, которая использует эти опции для осуществления текущего контроля за другими пользователями. Bourne shell и Korn shell автоматически заканчивают фоновые процессы, когда пользователь выходит из системы, в то время как С shell и Bash продолжают их выполнение. Если вы работаете с Bourne shell или Korn shell и хотите завершить фоновые процессы после выхода из системы, используйте утилиту nohup. Синтаксис nohup команда Утилита nohup выполняет команду и делает ее устойчивой к сигналу отбоя (hup) и завершения (term). Стандартный вывод и канал сообщений об ошибках автоматически переадресовываются в файл nohup.out, а значение приоритета процесса увеличивается на 5, таким образом снижая его приоритет2. Если команда выполняется с вызовом утилиты nohup, а затем происходит выход из системы, после чего пользователь вновь регистрируется, использо 2 Чем больше значение, тем ниже приоритет. — Ред.
ванная команда не появится в листинге утилиты ps. Это происходит потому, что при выходе из системы процесс теряет свой управляющий терминал и выполняется без него. Для включения в листинг всех процессов без управляющих терминалов следует запустить утилиту ps с опцией -х: $ nohup sleep 10000 & ...фоновый nohup-процесс 27406 Sending output to ’nohup.out ’ ... сообщение от nohup. $ ps ...посмотреть процессы. PID TT STAT TIME COMMAND 27399 p3 S 0:00 -sh (sh) 27406 p3 S N 0:00 sleep 10000 27407 p3 R 0:00 PS $ • • .выйти из системы. UNIX(r) System l V Release 4.0 login: < jlass • • .войти в систему. Password: • • .секрет. $ ps • • . фоновый процесс не виден. PID TT STAT TIME COMMAND 27409 p3 S 0:00 -sh (sh) 27411 p3 R 0:00 PS $ ps -x . . . фоновый процесс может быть виден. PID TT STAT TIME COMMAND 27406 IN 0:00 sleep 10000 27409 p3 S 0:00 -sh (sh) 27412 p3 R 0:00 ps -x $ _ Для дополнительной информации об управляющих терминалах см. главу 13. Процессы передачи сигналов: kill Если возникла необходимость завершить процесс прежде, чем он закончится, используйте команду kill. Korn shell и С shell содержат встроенную -команду kill, тогда как Bourne shell вместо этого вызывает стандартную утилиту kill. Представленный ниже пример иллюстрирует создание фонового процесса и завершение его командой kill: $ (sleep 10; echo done) && ...создать фоновый процесс. 27390 ...ID процесса. $ kill 27390 ..."убить" процесс.
$ ps ... он ушел PID тт STAT TIME COMMAND 27355 рЗ S 0:00 -sh (sh) 27394 рЗ R 0:00 PS $ Синтаксис kill [ -сигналЮ ] {Ю_процесса} + kill -1 Утилита/команда kill посылает сигнал с параметром сигнал_ю списку пронумерованных процессов, сигналю может быть номером или названием сигнала. По умолчанию kill посылает сигнал term (номер 15), получая который, процесс завершается. Чтобы вывести список допустимых названий сигналов, используйте опцию -1. Для передачи сигнала процессу пользователю необходимо быть его владельцем или привилегированным пользователем (для получения более подробной информации о сигналах см. главу 13). Процессы могут игнорировать все сигналы, кроме kill (номер которого 9). Поэтому, чтобы гарантированно завершить процесс, пошлите сигнал номер 9. (Обратите внимание, что отправка сигнала kill не позволяет процессу произвести очистку и закончиться обычным образом, как это делают многие программы при получении сигнала term.) Утилита kill (в противоположность встроенной команде в Korn shell и С shell) имеет параметр pid, равный 0. В главе 6 подробно описано использование команды kill. Представленный ниже пример иллюстрирует использование опции -1 и идентификаторов сигналов, которые выведены в порядке возрастания: $ kill -1 ...вывести имен^ сигналов. HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH LOST USR1 USR2 $ (sleep 10; echo done) & 27490 ...ID процесса. $ kill -KILL 27490 ..."убить" процесс с сигналом номер 9. $
Данный пример иллюстрирует завершение всех процессов, связанных с текущим терминалом: $ sleep 30 & sleep 30 & sleep 30 & ...создать три. 27429 27430 27431 $ kill 0 ..."убить" их все. 27431 Terminated 27430 Terminated 27429 Terminated $ Ожидание дочернего процесса: wait Командный интерпретатор shell может ожидать завершение дочерних процессов, выполняя встроенную команду wait. Синтаксис wait [ Ю_процесса ] Команда wait предписывает командному интерпретатору приостановить работу, пока дочерний процесс с указанным ID в качестве аргумента не завершится. Если аргумент не указан, shell ждет завершения всех дочерних процессов. В следующем примере shell перед продолжением своей работы ожидает завершения двух дочерних процессов, работающих в фоновом режиме: $ (sleep 30; echo done 1) & ...создать дочерний процесс. 24193 $ (sleep 30; echo done 2) & ...создать дочерний процесс. 24195 $ echo done 3; wait; echo done 4 ...ждать дочерние процессы. done 3 done 1 ... вывод первого дочернего процесса. done 2 ... вывод второго дочернего процесса. done 4
Поиск команды: $РАТН При обработке команды shell в первую очередь проверяет, не является ли она встроенной. Если это так, команда выполняется непосредственно shell: $ echo Некоторые команды выполняются shell непосредственно Некоторые команды выполняются shell непосредственно $ _ Если команда не встроенная, shell проверяет, начинается ли она с символа /. Если это так, shell интерпретирует его, как первый символ абсолютного пути, и пытается запустить соответствующий файл. Если система не находит данный файл по указанному адресу, возникает ошибка: $ /bin/Is ...полное путевое имя утилиты 1s. < script.csh script.ksh $ /bin/nsx ...несуществующее имя файла. /bin/nsx: not found $ /etc/passwd ...имя файла password. /etc/passwd: Permission denied ...он не исполняемый. $ _ Если введенная последовательность не является ни встроенной командой, ни путем к файлу, shell ищет каталоги, указанные в переменной path. После чего каждый каталог просматривается на предмет наличия в нем заданного файла, и если таковой находится, он выполняется. Если файл не является исполняемым или просто не найден, выводится сообщение об ошибке. Если переменная path не установлена или равна пустой строке, то просматривается только текущий каталог. Значение переменной path может быть изменено, но это будет обсуждаться в следующих главах. Первоначально путь поиска инициализируется файлом запуска shell и обычно включает все стандартные каталоги UNIX, содержащие выполняемые утилиты. Вот некоторые примеры: $ echo $РАТН /bin:/usr/bin:/usr/sbin ...просматриваемые каталоги. $ Is ...расположена в /bin. script.csh script.ksh $ nsx ...отсутствует. nsx: not found
Подмена стандартных утилит Пользователи часто создают каталог bin в своем домашнем каталоге и размещают его перед основным каталогом bin в переменной path. Такой способ позволяет им опередить загрузку установленных по умолчанию утилит UNIX собственными версиями, т. к. поиск в персональных каталогах будет производиться прежде, чем в стандартных. Однако необходимо использовать данную возможность с осторожностью, потому как shell может неправильно интерпретировать нестандартные утилиты. Рассмотрим пример. Создадим собственный каталог bin, пропишем его в переменной path, после чего поместим в него скрипт is: $ mkdir bin $ cd bin $ cat > Is echo my Is $ chmod +x Is $ echo $PATH . ..создать персональный каталог bin. ...перейти в новый каталог. ...создать скрипт 1s. ...конец ввода. ...сделать его исполняемым. ...посмотреть текущую установку PATH. /bin:/usr/bin:/usr/sbin $ echo $HOME ...получить путевое имя моего домашнего каталога, /home/glass $ РАТН= /home/glass/bin:$РАТН ...обновить. $ 1s ... вызов 1s. my Is ... версия подменяет /bin/Is. $ Внимание Только этот shell и его дочерние shell находятся под влиянием изменения path. Все другие shell при этом не затрагиваются. Завершение и коды выхода Завершаясь, каждый процесс возвращает числовое значение — код выхода. В соответствии с соглашением, значение кода выхода 0 означает, что процесс завершился успешно, в то время как любое значение, отличное от нуля, — выполнение закончилось неудачей. Все встроенные команды возвращают 1 в случае неудачи. В Bourne shell, Korn shell и Bash специальная переменная $? всегда содержит значение кода выхода предыдущей команды. В С shell это значение содержится в переменной $ status. В представленном
ниже примере утилита date завершилась успешно, тогда как утилиты сс и awk — С ошибкой: $ date ...date завершилась успешно. Sat Feb 2 22:13:38 CST 2002 $ echo $? ...вывести ее выходное значение. 0 ...указывает на успех. $ cc prog, с ...компилировать несуществующую программу. cpp: Unable to open source file ’prog.с’. $ echo $? ...вывести ее выходное значение. 1 ...указывает на неудачу. $ awk ...использовать awk неправильно. awk: Usage: awk . [-Fc] [-f source ’cmds’] [files] $ echo $? ...вывести ее выходное значение. 2 ...указывает на неудачу. $ _ Любой создаваемый пользователем скрипт должен возвращать код выхода. Чтобы завершить скрипт, используйте встроенную команду exit. Если оператор exit не указан в скрипте, по умолчанию возвращается значение выхода последней команды. Скрипт в представленном ниже примере возвратил значение 3: $ cat script, sh ...просмотреть скрипт. echo this script returns an exit code of 3 exit 3 $ script.sh ...выполнить скрипт. this script returns an exit code of 3 $ echo $? . ...посмотреть выходное значение. 3 $ Синтаксис exit номер Команда exit заканчивает выполнение и возвращает значение выхода родительскому процессу. Если аргумент номер опущен, то используется значение выхода предыдущей команды. В следующей главе представлено несколько примеров скриптов, использующих значения выхода.
Основные встроенные команды Большое число встроенных команд поддерживается четырьмя командными интерпретаторами, но только несколько команд являются общими для всех. Этот раздел описывает наиболее полезные общие команды. eval Команда eval выполняет вывод команды, как обычной команды shell. Синтаксис eval команда Команда eval выполняет вывод команды, как обычную команду shell. Она полезна при обработке вывода утилит, которые генерируют команды shell (например, tset). В представленном примере переменная х была установлена в результате выполнения команды echo: $ echo х=5 ...первое выполнение echo напрямую. х=5 $ eval 'echo х=5' ...выполнить результат echo. $ echo $х ...подтвердить, что х было присвоено 5. 5 $ ехес Команда ехес замещает заданной командой образ shell. Синтаксис ехес команда Команда ехес предписывать заместить образ shell командой в пространстве памяти процесса. Если команда выполнена успешно, выполняющий команду ехес shell завершается. Если этот shell был входным, то сессия работы с системой заканчивается после завершения выполнения команды.
В следующем примере командой ехес была запущена утилита date: $ exec date ...заместить процесс shell процессом date. Sun Feb 1 18:55:01 CDT 1998 ...вывод от date. login: _ ...входной shell завершился. shift Синтаксис встроенной команды указан ниже. Синтаксис shift Команда shift изменяет порядковые номера 2, 3, ..., п аргументов, указанных в командной строке на номера 1, 2, п — 1. При этом первый аргумент (с номером 1) теряется. Это особенно удобно в shell-скриптах, когда они циклически обрабатывают ряд параметров командной строки. Если нет никаких позиционных аргументов, оставленных для сдвига, выводится сообщение об ошибке. Следующий пример содержит скрипт С shell, в котором демонстрируются аргументы команды перед и после сдвига. $ cat shift.csh ...посмотреть скрипт. #!/bin/csh echo first argument is $1, all args* are $* shift echo first argument is $1, all args are $* $ shift, csh abed ...выполнить с четырьмя аргументами. first argument is a, all args are abed first argument is b, all args are bed $ shift, csh а ...выполнить с одним аргументом. . first argument is a, all args are a first argument is , all args are . $ shift.csh ' ...выполнить без аргументов. first argument is f all args are shift: No more words ...сообщение об ошибке.
umask Когда С-программа создает файл, первоначальная установка параметров полномочий задается как восьмеричное значение, передаваемое системному вызову open (). Например, чтобы создать файл с разрешением на чтение и запись для владельца, группы и остальных пользователей, программа выполнила бы следующий системный вызов: fd = open ("myFile", OCREAT | ORDWR, 0666); Для получения информации относительно шифрования параметров полномочий в виде восьмеричного числа см. главу 2. Системный вызов open () более подробно описан в главе 13. Когда shell выполняет перенаправление (с помощью символа >), он использует последовательность системного вызова, подобную показанной в предыдущем примере, чтобы создать файл с восьмеричным разрешением 666. Однако, если вы попробуете создать файл, указывая символ переназначения >, то скорее всего получите файл с установкой параметров полномочий 644 (восьмеричное), как показано в следующем примере: $ date > date.txt $ Is -1 date.txt -rw-r—r— 1 glass 29 May 3 18:56 date.txt $ _ Причина различия в установке параметров полномочий состоит в том, что каждый процесс UNIX содержит специальную величину umask, используемую для ограничения назначения параметров полномочий и запрашиваемую системой во время создания файла. По умолчанию величина umask равна восьмеричному значению 022. Набор битов значения umask маскирует набор битов требуемой установки параметров полномочий. В предыдущем примере требуемые параметры полномочий 666 были замаскированы значением 022, что в результате дало 644. В табл. 4.8 приведена расшифровка параметров umask и получаемых в результате наложения значений. Таблица 4.8. Побитовый пример эффекта установки umask rwx rwx rwx Начальный 110110110 Маска 000010010 Финальный 110100100
Если файл уже существует до перенаправления в него вывода, значения первоначальных параметров полномочий файла сохраняются, а значение umask игнорируется. Синтаксис umask [восьмеричнаяВеличина] Команда shell umask присваивает umask указанное восьмеричное число или, если аргумент опущен, показывает текущее значение umask. Значение umask сохраняется до следующего изменения. Дочерние процессы наследуют свое значение umask от родителей. В следующем примере значение umask изменено на 0, после чего был создан новый файл: $ umask ...вывести текущее значение umask. 22 ...маскирует разрешение записи для группы/других. $ umask 0 ...установить значение umask на 0. $ date > date2.txt ...создать новый файл. $ Is -1 date2.txt — rw—rw—rw— 1 glass 29 May 3 18:56 date2.txt Обзор главы Перечень тем В этой главе мы рассмотрели: □ общую функциональность четырех основных командных интерпретаторов; □ общие метасимволы shell; □ перенаправление ввода и вывода; □ подстановку имени файла; □ конвейеры; □ подстановку команды; □ командные последовательности; □ сгруппированные команды;
□ создание скриптов; □ различие между локальными переменными и переменными окружения; □ два различных типа кавычек; □ основы управления работой; □ механизм поиска команды; □ несколько основных встроенных команд. Контрольные вопросы 1. Можете ли вы изменить shell, установленный по умолчанию? 2. Какая команда UNIX используется для того, чтобы изменить текущий пользовательский каталог? 3. Как вы можете ввести команды, которые длиннее одной строки терминала? 4. В чем заключается различие между встроенной командой и утилитой? 5. Как сделать скрипт исполняемым? 6. Как иногда называется замещение имени файла? 7. Объясните использование замещения команды. 8. Объясните значения терминов "родительский shell", "дочерний shell" и "subshell". 9. Как вы думаете, почему команда kin получила свое имя? 10. Опишите способ подмены стандартной утилиты. 11. Чем удобна величина umask и почему? Упражнения 4.1. Напишите скрипт, который печатает текущую дату, ваше пользовательское имя и название вашего входного shell. [Уровень: легкий.] 4.2. Поэкспериментируйте с командой ехес путем создания серии из трех shell-скриптов a.sh, b.sh и c.sh, каждый из которых выводит свое имя, выполняет утилиту ps и затем вызывает при помощи ехес следующий скрипт этой последовательности. Пронаблюдайте, что происходит, когда вы запускаете первый скрипт, выполняя ехес а. sh. [Уровень: средний.] 4.3. Объясните, почему файл, который создан в следующей сессии, не затрагивается значением umask? [Уровень: средний.] $ Is -1 date.txt -rw-rw-rw- 1 glass 29 Aug 20 21:04 date.txt
$ umask 0077 $ date > date.txt $ Is -1 date.txt -rw-rw-rw- 1 glass 29 Aug 20 21:04 date.txt 4.4. Напишите скрипт, который создает три фоновых процесса, ждет их завершения, после чего выводит простое сообщение. [Уровень: средний.] Проект Сравните и противопоставьте особенности командного интерпретатора UNIX с графическими shell, доступными в Windows. [Уровень: средний.]
Глава 5 Bourne shell Мотивация Командный интерпретатор Bourne shell, написанный Стивеном Боурном (Stephen Bourne), был первым популярным UNIX shell и сейчас присутствует во всех UNIX-системах. Он поддерживает довольно универсальный язык программирования и похож на более мощный Кот shell, который описан в главе 6. Знание Bourne shell поможет вам понять работу многих скриптов, уже написанных для UNIX, а также подготовит к знакомству с Кот shell. Предпосылки Перед чтением данной главы вам необходимо ознакомиться с главой 4 и поэкспериментировать с основными функциями shell. Задачи В этой главе мы познакомимся со специфическими для Bourne shell функциями, включая использование локальных переменных и переменных окружения, встроенного языка программирования и средств перенаправления ввода/вывода. Изложение Как обычно, материал главы представлен в виде нескольких UNIX-сессий, что позволяет увидеть в работе обсуждаемое в теории. Утилиты В этой главе мы познакомимся с утилитами: expr test
Команды shell Ниже перечислены команды shell, которые будут рассмотрены в данной главе. break for...in...do...done set case...in...esac if...then...elif...fi trap continue read while...do...done export readonly Общие сведения о Bourne shell Bourne shell поддерживает все основные функции программной оболочки, описанные в главе 4, а также следующие специфические возможности (рис. 5.1): □ несколько способов задания значений и доступа к переменным; П встроенный язык программирования, который обеспечивает условные переходы, организацию циклов и обработку прерываний; □ усовершенствованные средства перенаправления и работы с последовательностью команд; П несколько новых встроенных команд. Рис. 5.1. Функции Bourne shell Запуск Bourne shell — это обычная С-программа, исполняемый файл которой хранится в каталоге /bin/sh. Если оболочка является установленной по умолчанию, то она запускается автоматически в процессе регистрации в системе. Можно также вызвать Bourne shell вручную из скрипта или с терминала, используя команду sh.
Когда Bourne shell стартует в диалоговом режиме, он ищет файл .profile в домашнем каталоге пользователя. Если файл найден, то выполняются все команды shell, содержащиеся в файле. Затем, независимо от того, был ли .profile найден, диалоговый режим Bourne shell выводит свое приглашение и ждет пользовательских команд. Стандартное приглашение Bourne shell — это символ $, хотя он может быть изменен путем установки локальной переменной psi, о которой мы поговорим чуть позже. Внимание Если Bourne shell запущен не в диалоговом режиме, файл не читается. Одно из обычных применений .profile — это инициализация переменных окружения типа term (содержит тип пользовательского терминала) и path (сообщает shell, где искать исполняемые файлы). Вот пример файла запуска .profile для Bourne shell: TERM=vtlOO # установка типа терминала. export TERM # скопировать в окружение. # Установить путь и метасимволы stty erase ,1Л?" kill "Ли" intr ”ЛС” eof РАТН='.:$HOME/bin:/bin:/usr/sbin:/usr/bin:/usr/local/Ып’ Переменные Bourne shell поддерживает следующие действия с переменными: П простое назначение и доступ; □ проверка переменной на существование; □ чтение переменной со стандартного ввода; □ создание неизменяемой переменной; □ экспорт локальной переменной в переменные окружения. Командный интерпретатор Bourne shell также определяет несколько локальных переменных и переменных окружения в дополнение к тем, которые были рассмотрены в главе 4. Создание и назначение переменной Bourne shell имеет следующий синтаксис для присвоения значения переменной: {имя=значение}+ Если переменная не существует, она неявно создается; иначе ее предыдущее значение переписывается. Недавно созданная переменная всегда локальна,
хотя может быть превращена в переменную окружения способом, о котором мы поговорим позднее. Чтобы присвоить значение, которое содержит пробелы, обрамите его кавычками. Например: $ firstName=Graham lastName-Glass аде=29 ...назначение переменных. $ echo $firstName $lastName is $age Graham Glass is 29 ...простой доступ. $ name=Graham Glass ...синтаксическая ошибка. Glass: not found $ name="Graham Glass" ...используйте кавычки для задания строк. $ echo $name ...теперь это работает. Graham Glass $ Доступ к переменной Bourne shell поддерживает методы доступа к переменным, перечисленные в табл. 5.1. Если доступ к переменной осуществляется прежде, чем ей присвоено значение, то возвращается пустая строка. Таблица 5.1. Специальные переменные Bourne shell Синтаксис Описание $имя Заменяется значением имя ${имя} Заменяется значением имя. Эта форма полезна, если выражение следует сразу за алфавитно-цифровым символом, который иначе интерпретировался бы как часть имени переменной ${имя-слово} Заменяется значением имя, если оно установлено, в противном случае — слово ${имя+слово} Заменяется слово, если имя установлено, в противном случае ничего не делает ${name=word} Присваивает слово переменной имя, если имя еще не установлено, и затем заменяется значением имя ${имя?слово} Заменяется имя, если имя установлено. Если имя не установлено, слово выводится в стандартный канал ошибки, и происходит выход из shell. Если слово опущено, то вместо этого выводится стандартное сообщение об ошибке Возможно, указанные методы несколько сложны, однако, даже если вы никогда не будете их использовать, то сможете понимать код, в котором они применяются. Представленные ниже примеры иллюстрируют каждый из
методов доступа. В первом примере мы будем использовать фигурные скобки, чтобы добавить строку к значению переменной: $ verb=sing ...определить переменную. $ echo I like $verbing ...нет переменной verbing. I like $ echo 1 like ${verb}ing ...теперь это работает. I like singing $ _ В следующем примере используется замещение команды для присвоения переменной startDate текущей даты, если переменная еще не установлена: $ startDate=${startDate-'date'} ...если не установлена, выполнить date. $ echo $startDate ...посмотреть ее значение. Tue Wed 4 06:56:51 GST 1998 $ _ Далее переменной х присваивается значение по умолчанию, после чего оно выводится на терминал: $ echo х - ${х=10) ...присвоить значение по умолчанию. х = 10 $ echo $х ...подтвердить, что значение переменной было установлено. 10 $ _ В данном примере в зависимости от того, установлены переменные или нет, выводятся те или иные сообщения: $ flag=l ...определить переменную. $ echo ${flag+'flag is set'} ...первое условное сообщение. flag is set $ echo ${flag2+'flag2 is set'} ...второе условное сообщение. ...результат нулевой. $ _ Следующий пример иллюстрирует доступ к неопределенной переменной grandTotal и вывод сообщения об ошибке: $ total=10 ...определить переменную. $ value=${total?'total not set'} ...доступ осуществлен. $ echo $value ...посмотреть ее значение. 10 $ value=${grandTotal?'grand total not set'} ...не установлена.
grandTotal: grand total not set $ _ В завершающем примере используется скрипт с тем же методом доступа, что и в предыдущем, в результате чего произошла ошибка: $ cat script.sh ...посмотреть скрипт. value=${grandTotal?’grand total is not set’} echo done # эта строка никогда не выполнится. - $ script.sh 4 ...выполнить скрипт. script.sh: grandTotal: grand total is not set $ _ Чтение переменной co стандартного ввода Команда read позволяет читать переменные со стандартного ввода. Если пользователь определяет только одну переменную, то вся строка сохраняется в переменной. Вот стандартный скрипт, напоминающий пользователю о необходимости ввести его полное имя: $ cat script.sh ...посмотреть скрипт. echo ’’Please enter your name: \c” read name # читать только одну переменную. echo your name is $name # вывести переменную. $ script.sh ...выполнить скрипт. Please enter your name: Graham Walker Glass your name is Graham Walker Glass ...была прочитана вся строка. $ Синтаксис read {переменная}+ Команда read читает одну строку со стандартного ввода и затем последовательно присваивает слова из строки указанным переменным. Оставшиеся слова присваиваются последней переменной. В представленном ниже примере была определена более чем одна переменная: $ cat.script.sh ...посмотреть скрипт. echo ’’Please enter your name: \c" read firstName lastName # читать две переменных.
echo your first name is $firstName echo your last name is $lastName $ script.sh ...выполнить скрипт. Please enter your name: Graham Walker Glass your first name is Graham ...первое слово. your last name is Walker Glass ...остаток. $ script.sh ...выполнить его снова. Please enter your name: Graham your first name is Graham ...первое слово. your last name is ...только одно. $ Экспорт переменных Команда export позволяет отмечать локальные переменные для экспорта в переменные окружения. Синтаксис export {переменная} + Команда export отмечает указанные переменные для экспорта в переменные окружения. Если переменные не определены, то выводится список всех переменных, отмеченных для экспорта в течение сессии shell. Как правило, для именования переменных окружения используются большие1 буквы. Однако вы можете использовать и строчные, если это вам удобно. Утилита env позволяет изменять и выводить такие переменные. Синтаксис env {переменная = значение} * [команда] Утилита env присваивает значения определенным переменным окружения и затем выполняет дополнительную команду, используя переопределенные таким образом переменные. Если переменные или команда не определены, выводится список текущих переменных окружения. 1 Прописные. — Ред.
Для примера создадим локальную переменную с именем database, которую затем пометим для экспорта. После этого создадим дочерний shell, который унаследует копию переменных окружения родителя: $ export ...вывести мой текущий экспорт. export TERM ...установлена в моем стартовом файле .profile. $ DATABASE=/dbase/db ...создать локальную переменную. $ export DATABASE ...отметить ее для экспорта. $ export export DATABASE ...заметьте, что она была добавлена. export TERM $ env DATABASE=/dbase/db . . .вывести переменные окружения. НОМЕ=/home/glass LOGNAME=glass PATH=:/usr/ucb:/bin:/usr/bin SHELL=/bin/sh TERM=vtlOO USER=glass $ sh ...создать дочерний shell. $ echo $DATABASE /dbase/db ...копия была унаследована. $ ...завершить subshell. $ _ Переменные только для чтения Команда readonly позволяет защищать переменные от модификации. Синтаксис readonly {переменная} * Команда readonly устанавливает статус "только для чтения" для указанных в качестве аргументов программы переменных, тем самым защищая их от изменений. Если переменные не определены, выводится список текущих переменных с таким статусом чтения. Копии экспортируемых переменных не наследуют статус "только для чтения".
В следующем примере переменная устанавливается в режим, доступный только для чтения, после чего экспортируется, а мы посмотрим на статус копии — она не унаследует разрешения только на чтение: $ password=Shazam. ...определить локальную переменную. $ echo $password Shazam ...вывести ее значение. $ readonly password ...защитить ее. $ readonly readonly password ...вывести все переменные со статусом readonly. $ password=Phoombah password: is read only ...попытаться модифицировать ее. $ export password ...экспортировать переменную. $ password=Phoombah ...попытаться модифицировать ее. password: is read only $ sh ...создать subshell. $ readonly $ echo $password Shazam ...экспортированная переменная не readonly. ... ее значение было скопировано корректно. $ password=Alacazar $ echo $password Alacazar . . .но ее величина может быть изменена. ...вывести ее значение. $ AD ...завершить subshell. $ echo $password Shazam ...вывести оригинальное значение. $ _ Предопределенные локальные переменные В дополнение к предопределенным локальным переменным ядра, Bourne shell определяет собственные локальные переменные, перечисленные в табл. 5.2. Таблица 5.2. Предопределенные локальные переменные Bourne shell Имя Описание $0 Индивидуально указанный список всех позиционных параметров $# Число позиционных параметров $ ? Код возврата последней команды
Таблица 5.2 (окончание) Имя Описание $ 1 ID процесса последней фоновой команды $- Текущие опции shell, назначенные в командной строке или встроенным набором команд $$ ID процесса, выполняемого shell Ниже приведен небольшой скрипт, в котором компилятор С (сс) вызывается с переданным в качестве параметра несуществующим файлом, вследствие чего операция терпит неудачи и возвращает код ошибки: $ cat script.sh ...посмотреть скрипт. echo there are $# command line arguments: $@ cc $1 # компилировать первый аргумент. echo the last exit value was $? # вывести код возврата. $ script.sh nofile tmpfile ...выполнить скрипт. there are 2 command line arguments: nofile tmpfile cc: Warning: File with unknown suffix (nofile) passed to Id Id: nofile: No such file or directory i the last exit value was 4 ...сообщение об ошибке от cc. $ _ Следующий пример иллюстрирует использование имени $! для принудительного завершения последнего фонового процесса: $ sleep 1 000 & ... создает фоновый процесс. 29455 ...ID фонового процесса. $ kill $! ..."убить” его! 29455 Terminated $ echo $! ...ID процесса все еще помнится. 29455 $ Предопределенные переменные окружения Базовые переменные окружения, о которых мы говорили в главе 4, дополняются перечисленными в табл. 5.3 переменными.
Таблица 5.3. Предопределенные переменные окружения Bourne shell Имя Описание $IFS Когда shell разбирает командную строку перед ее выполнением, он использует символы из этой переменной в качестве разделителей, ips обычно содержит пробел, символ табуляции и символ перевода строки $PS1 Переменная содержит значение приглашения командной строки (по умолчанию используется $). Чтобы заменить приглашение, просто присвойте PS1 новое значение $PS2 Переменная содержит значение вторичного приглашения командной строки (по умолчанию >), которое отображается, когда shell требует ввода дополнительной информации. Чтобы изменить приглашение, присвойте PS2 новое значение $SHENV Если эта переменная не установлена, shell ищет файл запуска .profile в домашнем каталоге пользователя, когда создается новый shell. Если переменная определена, то командный интерпретатор ищет каталог, указанный в shenv Ниже приведен небольшой пример, иллюстрирующий использование первых трех переменных. Здесь приглашение shell, сохраненное в переменной psi, устанавливается в отличное от заданного по умолчанию. Кроме того, разделитель полей задается равным двоеточию (:), а предыдущее значение сохраняется в локальной переменной. Далее производится проверка вывода приглашения: $ PSI = "sh?" sh? old.IFS=$IFS sh? IFS-":" sh? ls:*.c badguy.c number.c fact2.c number2.c sh? IFS=$oldIFS sh? string="a long\ > string" sh? echo $s tring a long string sh? PS2 = "??? " sh? string="a long\ ??? string" sh? echo $string a long string sh? ...установить новое первичное приглашение. ...запомнить старое значение IFS. ...заменить разделитель слов на двоеточие. ...это выполняется хорошо! open.с trunc.c writer.с reader.с who.с ...восстановить старое значение IFS. ...определить строку через две строки терминала ...> — это вторичное приглашение. ...посмотреть значение string. ...изменить вторичное приглашение. ...задать длинную строку. ...??? — это новое вторичное приглашение. ...посмотреть значение string. \
Арифметические действия Сам Bourne shell не поддерживает арифметических операций, однако утилита ехрг помогает устранить этот недостаток. Синтаксис ехрг выражение Утилита ехрг вычисляет выражение и посылает результат на стандартный вывод. Все компоненты выражения должны быть разделены пробелами, а все метасимволы shell должны завершаться символом \ (экранироваться). Выражение может давать результат в числовом или строчном виде в зависимости от операторов, которые оно содержит. Результат выражения может быть присвоен переменной shell соответствующим использованием команды замещения. Допустимо построение выражения с помощью перечисленных ниже бинарных операторов к целочисленным операндам, сгруппированным в порядке увеличения приоритета: Оператор Описание *, /, % Умножение, деление, остаток +> ~ Сложение, вычитание :=j i= Операторы сравнения & 1 Логическое И Логическое ИЛИ Круглые скобки могут использоваться для явного управления порядком вычисления (однако их также нужно экранировать). Утилита также поддерживает следующие строчные операторы: Оператор Описание строка: регулярноеВыражение Обе формы возвращают длину строки match строка регулярноеВыражение строка, если выражения совпадают, иначе возвращают ноль substr строка начало длина Возвращает подстроку строки, начинающейся с индекса на чало и состоящей из длина символов
(окончание) Оператор Описание index строка списокСимволов Возвращает индекс первого символа в строке. который появляется В спискеСимволов length строка Возвращает длину строки Формат регулярного выражения определен в Приложении. Следующий пример иллюстрирует некоторые функции ехрг и использует замещение команд: $ Х=1 $ х=' ехрг $х + 1' $ echo $х 2 $ х= 'ехрг 2 + 3 \* 5' $ echo $х 17 $ echo 'ехрг \(2 + 3\) \* 5' 25 $ echo 'ехрг length "cat”' 3 $ echo 'ехрг substr "donkey” 4 3' key $ echo 'expr index "donkey" "ke"' 4 $ echo 'expr match "Smalltalk" *. 9 $ echo 'expr match "transputer" 1 0 $ echo 'expr "transputer" : ’★.Ik 0 $ echo 'expr \ ( 4\ > 5 \ ) ' ...начальное значение x. ...увеличить x на единицу. ... * перед +. ...перегруппировать. ...найти длину cat. ...выделить подстроку. ...определить позицию подстроки. ★1k’' ...проверить ...на совпадение. ★.!&'' ...проверить ... на совпадение. г' ... проверить ...на совпадение. ...больше ли 4 > 5?
О $ echo 'ехрг \ ( 4 \ > 5\) \/ \ (6 \ < 7 \ ) ' .. .больше ли 4 > 5 или 6 < 7? 1 $ Условные выражения Структуры управления, подробно описанные в следующем разделе, часто используются для перехода в зависимости от значения логического выражения, возвращающего истину или ложь. Утилита test поддерживает достаточно большой набор UNIX-ориентированных выражений, которые являются подходящими для большинства случаев. Выражение test может иметь формы, показанные в табл. 5.4. Внимание Утилита очень требовательна к синтаксису выражений; пробелы, указанные в этой таблице, нельзя опускать. Синтаксис test выражение [выражение] Эквивалентной формой, используемой в некоторых UNIX-системах, является заключение выражения в круглые скобки. Утилита test возвращает 0, если выражение вычисляет истину; иначе возвращает код выхода, отличный от 0. Код возврата обычно используется структурами управления shell, выполняющими переходы по условию. Некоторые Bourne shell выполняют утилиту test, как встроенную команду. В таком случае они также поддерживают вторую форму вычисления. Однако чтобы эта форма работала, скобки должны быть отделены пробелами. Таблица 5.4. Выражения, используемые утилитой test Форма -Ь имяФайла -с имяФайла Описание Возвращает истину, если имяФайла существует в качестве специального блочного файла Возвращает истину, если имяФайла существует в качестве специального символьного файла
Таблица 5.4 (продолжение) Форма Описание -d имяФайла Возвращает истину, если имяФайла существует в качестве каталога -f имяФайла Возвращает истину, если имяФайла существует, как не каталог -g имяФайла Возвращает истину, если имяФайла существует в качестве файла "установки ID группы" -h имяФайла Возвращает истину, если имяФайла существует в качестве символической связи -к имяФайла Возвращает истину, если имяФайла существует и имеет установленный "промежуточный бит округления" -1 строка Длина строки -п строка Возвращает истину, если строка содержит, по крайней мере, один символ -р имяФайла Возвращает истину, если имяФайла существует в качестве именованного конвейера -г имяФайла Возвращает истину, если имяФайла существует в качестве читаемого файла -s имяФайла Возвращает истину, если имяФайла содержит, по крайней мере, один символ -t fd Возвращает истину, если дескриптор файла fd связан с терминалом * -и имяФайла Возвращает истину, если имяФайла существует в качестве файла "установки ID пользователя" -w имяФайла Возвращает истину, если имяФайла существует в качестве файла для записи -х имяФайла Возвращает истину, если имяФайла существует как исполняемый файл — z строка Возвращает истину, если строка не содержит никаких символов strl - str2 Возвращает истину, если strl равна str2 strll - str2 Возвращает истину, если strl не равна str2 строка Возвращает истину, если строка не нулевая intl-eq int2 Возвращает истину, если целое inti равно целому int2 inti -ne int2 Возвращает истину, если целое inti не равно целому int2 inti -gt int2 Возвращает истину, если целое inti больше целого int2 inti -ge int2 Возвращает истину, если целое inti больше или равно целому in t2
Таблица 5.4 (окончание) Форма Описание inti -It int2 Возвращает истину, если целое inti меньше целого int2 inti -le int2 Возвращает истину, если целое inti меньше или равно целому in t2 ! выражение Возвращает истину, если выражение ложно exprl -a expr2 Возвращает истину, если выражения exprl и ехрг2 оба истинны exprl —о expr2 Возвращает истину, если exprl или ехрг2 истинно \ (выражение \) Экранированные круглые скобки используются для группирования выражений Структуры управления Bourne shell поддерживает широкий диапазон структур управления, которые делают командный интерпретатор удобным инструментом программирования высокого уровня. Программы shell обычно хранятся в скриптах и, как правило, используются для автоматизации задачи инсталлирования и обслуживания. В следующих разделах в алфавитном порядке будут описаны структуры управления. Однако для их понимания желательно быть знакомым хотя бы с одним языком программирования высокого уровня. case... in... esac Команда case поддерживает многопозиционный переход, базирующийся на значении отдельной строки. Синтаксис case выражение in шаблон { | шаблон} *) списокКоманл esac выражение определяет строку, возможно, содержащую групповые символы, сравниваемую с шаблоном. списокКоманл включает одну или нескольких команд shell. Командный интерпретатор вычисляет выражение, а затем сравнивает его по порядку с каждым шаблоном. Когда первое соот
ветствие шаблону найдено, выполняется связанный с ним списокКоманд. Далее shell переходит на строку esac. Шаблоны в последовательности отделяются символом | ("или") и связаны с одним и тем же набором действий. Если shell не находит совпадения, выполняется esae. echo ’your choice? \c* read reply echo case $reply in "I") date r r "2”|”3") pwd r r ”4”) stop=l r r *) echo illegal choice Ниже приведен пример скрипта menu.sh, который использует структуру управления case (скрипт также доступен в сети; см. Введение для получения дополнительной информации): #! /bin/sh echo menu test program stop=0 # переустановить флаг прекращения цикла, while test $stop -eq 0 # цикл до выполнения, do cat « ENDOFMENU # вывести меню. 1 : print the date. 2 , 3: print the current working directory. 4 : exit ENDOFMENU echo # приглашение. # читать ответ. # отклик процесса. # вывести дату. # вывести рабочий каталог. # установить флаг прекращения цикла. # по умолчанию. # ошибка. esac done
Пример работы скрипта menu.sh: $ menu.sh menu test program 1 : print the date. 2r 3: print the current working directory. 4 : exit your choice? 1 Thu Feb 5 07:09:13 CST 1998 1 : print the'date. 2r 3: print the current working directory. 4 : exit your choice? 2 /home/glass 1 : print the date. 2 , 3: print the current working directory. 4 : exit your choice? 5 illegal choice 1 : print the date. 2 , 3: print the current working directory. 4 : exit your choice? 4 $ for... do... done Структура for позволяет выполнить несколько раз список команд, используя различные значения переменной цикла во время каждой итерации. Синтаксис for имяПеременной [ in {списокСлов} * ] do списокКоманл done Команда for циклически присваивает значению имяПеременной каждое из слов параметра списокСлов, выполняя команды из аргумента список-команд после каждой итерации. Если списокСлов не представлен, вместо
него используется $@. Команда break заставляет цикл завершиться, а команда continue переводит его к следующей итерации. Ниже приведен пример скрипта со структурой управления for: $ cat for.sh ...посмотреть скрипт. for color in red yellow green blue do echo one color is $color done $ for.sh ...выполнить скрипт. one color is red one color is yellow one color is green one color is blue $ _ if... then... fi Команда if поддерживает вложенные условные ветвления. Синтаксис if условие! then списокКоманд! elif условие2 ...необязательнаяг ...elif может повторяться несколько раз. then списокКома нд2 else ...необязательная, else может появляться один раз. списокКома ндЗ fi Выполняются команды из условие!. Если они завершаются удачно, выполняются команды ИЗ списокКоманд!. ЕСЛИ ПОСЛеДНЯЯ команда условие! завершается неудачно, и если указан один или более el if-компонентов (возвращающих истину), выполняются команды, указанные после then. Если команда возвращает сигнал об ошибке, и в скрипте задано условие else, выполняются команды, указанные после него. 9 Зак. 786
Вот пример скрипта, который использует структуру управления if: $ cat if.sh ...посмотреть скрипт, echo ’enter a number: \с’ read number if [ $number -It 0 ] then echo negative elif [ $number -eq 0 ] then echo zero else echo positive fi $ if.sh ...выполнение скрипта, enter a number: 1 positive $’ if.sh ...выполнить скрипт снова, enter a number: -1 negative $ trap trap позволяет задать команду, которая должна быть выполнена, когда командный интерпретатор получает сигнал конкретного значения. Синтаксис trap.[[команда ] {сигнал} + ] Команда trap предписывает shell выполнять команду всякий раз, когда получен любой из пронумерованных сигналов. Если поступило несколько сигналов, они перехватываются в числовом порядке. Если значение сигнала 0 определено, тогда команда выполняется при завершении shell. Если команда опущена, то значения пронумерованных сигналов сбрасываются в их первоначальное значение. Если команда — пустая строка, то пронумерованные сигналы игнорируются. Выполнение trap без аргументов приводит к выводу списка всех сигналов и их trap-установок. (Для получения дополнительной информации о сигналах и их действиях по умолчанию см. главу 13.)
Вот пример скрипта, который использует структуру управления trap: $ cat trap.sh ...посмотреть скрипт. trap ’echo Control-C; exit 1’ 2 # выполнить <Ctl>+<C> (сигнал 2) while 1 do echo infinite loop sleep 2 # приостановиться на две секунды, done $ trap.sh ...выполнить скрипт. infinite loop infinite loop ... я нажал <Ctrl>+<C>. Control-C ...выведено командой echo. $ _ Обратите внимание, что после нажатия комбинации клавиш <Ctrl>+<C> shell выполнил команду echo, сопровождаемую командой exit. until... do... done Команда until выполняет некоторую серию команд до тех пор, пока другая серия команд2 не станет истинной. Синтаксис until условие do списокКоманл done Команда until выполняет команды из списка условие и прекращается, если условие истинно. Иначе, выполняются команды из аргумента списокКоманл, и процесс повторяется. Если списокКоманл пуст, ключевое слово do должно быть опущено. Команда break вызывает немедленное завершение цикла, а команда continue переводит его к следующей итерации. Вот пример скрипта, который использует структуру управления until: $ cat until.sh ...вывести скрипт. 2 Иными словами, условие. — Ред.
until [ $х -gt 3 ] do echo x = $x x='expr $x + 1' done $ until.sh ...выполнить скрипт. x = 1 x = 2 x = 3 $ while... done Команда while выполняет серию команд до тех пор, пока другая серия3 выполняется успешно. Синтаксис while условие do списокКома нд done Команда while выполняет условие и прекращается, если последняя команда из него заканчивается неудачно. Иначе выполняется списокКо-манд, и процесс повторяется. Если списокКоманд пуст, ключевое СЛОВО do должно быть опущено. Команда break вызывает прерывание цикла, а команда continue переводит его к следующей итерации. Ниже приведен пример скрипта, который содержит структуру управления while и демонстрирует генерацию небольшой таблицы умножения: $ саt multi.sh ... вывести скрипт. if [ "$1" -eq "" ]; then echo "Usage: multi number" exit fi x=l # установка значения для внешнего цикла 3 Условие. — Ред.
while [ $x -le $1 ] # внешний цикл do y=l # установка значения для внутреннего цикла while [ $у -1е $1 ] do # генерирует один вход таблицы echo 'ехрг $х \* $у' " \с" у = 'ехрг $у + 1' # обновить счетчик внутреннего цикла done echo # пустая строка x='expr $х + 1' # обновить счетчик внешнего цикла done $ multi.sh 7 ...выполнить скрипт. 1 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42 7 14 21 28 35 42 49 $ Пример проекта: track Для иллюстрации основной части возможностей Bourne shell воспользуемся небольшим скриптом track. Этот скрипт отслеживает регистрацию и выход из системы пользователей, генерируя простой отчет о пользовательских сессиях. Скрипт использует следующие утилиты: □ утилита who выводит список текущих пользователей системы; □ утилита grep фильтрует текстовые строки, которые соответствуют указанному шаблону; П утилита diff показывает различия между двумя файлами; □ утилита sort сортирует текстовый файл; □ утилита sed выполняет предварительно запрограммированное редактирование файла; □ утилита ехрг вычисляет значение выражения; П утилита cat выводит содержимое файла; □ утилита date отображает текущее время;
П утилита rm удаляет файл; П утилита mv перемещает файл; □ утилита sleep устанавливает паузу на несколько секунд. Утилиты grep, diff, sort и sed описаны в главе 3\ о другой утилите (who) рассказано в главе 9. Рассмотрим пример работы этого скрипта: $ track -пЗ Ivor -t200 ...отследить сессию Ивора. track report for ivor: ...первоначальный вывод. Login ivor ttyp3 Feb 5 06:53 track report for ivor: ...Ивор вышел из системы. Logout ivor ttyp3 Feb 5 06:55 ...завершить программу, используя комбинацию клавиш <Ctrl>+<C>. stop tracking ...сообщение прекращения программы. $ Синтаксис track [-псчетчик] [-tnaysa] Ю_пользователя Скрипт track отслеживает сессии входа и выхода указанного пользователя. С периодичностью в указанное паузой число секунд track просматривает систему и фиксирует зарегистрированных в системе. Если указанный пользователь зарегистрировался или вышел из системы за время последнего просмотра, эта информация передается на стандартный вывод. Скрипт работает, пока не сбросится счетчик количества просмотров. По умолчанию пауза равна 20 секундам, а счетчик 10 000 просмотров. Обычно этот скрипт выполняется в фоновом режиме с переадресацией стандартного вывода в файл. Программа track состоит из трех файлов: □ track — главный скрипт Bourne shell; □ Track.sed — sed-скрипт для редактирования вывода утилиты diff; П track.cleanup — маленький скрипт, который очищает временные файлы. Алгоритм работы описанного скрипта может быть разделен на три части. 1. Разбор командной строки и установка значений трех локальных переменных: user, pause и loopcount. Если произошли какие-нибудь ошибки, скрипт завершается выводом сообщения о них.
2. Затем устанавливается перехват двух событий: завершение скрипта и int-(<Ctrl>+<C>) или QUiT-сигналы (<Ctrl>+<\>). Если был получен сигнал выхода quit, инициализируется событие завершения скрипта. Скрипт очистки получает ID процесса главного скрипта в качестве единственного аргумента и удаляет временные файлы. 3. Далее цикл выполняется заданное количество раз, сохраняя отфильтрованный список текущих пользователей во временном файле .track.new.55, где 55 — ID процесса скрипта. Затем файл сравнивается с последней версией вывода, сохраненного в файле .track.old.55. Если строка находится в новом файле, а не в старом, это означает, что пользователь, скорее всего, зарегистрировался в системе. Если строка размещена в старом файле, пользователь покинул систему. Если после работы diff-файл вывода имеет длину, отличную от нуля, то информация передается утилите sed и выводится. После чего скрипт делает паузу на указанное количество секунд и продолжает выполнять цикл. Листинг двух пропущенных через утилиту diff наборов данных, переданных ей утилитой who, иллюстрируется следующей сессией: $ cat track.new.1112 ...новый вывод от who. glass ttypO Feb 4 23:04 glass ttyp2 Feb 4 23:04 $ cat track.old.1112 glass ttypO Feb 4 23:04 glass ttypl Feb 4 23:06 ...старый вывод от who. $ diff track.new.1112 track.old.1112 2c2 < glass ttyp2 Feb 4 23:04 > glass ttypl Feb 4 23:06 $ . ...изменения. track.sed Скрипт track.sed удаляет все строки, которые начинаются с цифры или ", а затем подставляет символ < вместо login и символ > вместо logout. /А[0-9].*/d /А---/d s/A</login/ s/A>/logout/
track.cleanup echo stop tracking rm -f .track.old.$1 .track.new.$1 .track.report.$1 track pause=20 # пауза по умолчанию между сканированиями loopCount=10000 # счетчик числа сканирований, по умолчанию error=0 # флаг ошибки for arg in $* # разбор аргументов командной строки do case $arg in \ -t*) # время pause='expr substr $arg 3 10' # извлечение числа -n*) # счетчик сканирований loopCount='ехрг substr $arg 3 10' # извлечение числа f г *) user=$arg # имя пользователя esac done if [ ! "$user" ] # проверка, был ли найден ID пользователя then error=l fi if [ $error -eq 1 ] # вывести ошибку, если ошибка найдена then cat « ENDOFERROR # вывести сообщение использования usage: track [-n#] [-t#] userid ENDOFERROR exit 1 # завершить shell fi trap ’track.cleanup $$; exit $exitCode’ 0 # trap в режиме выхода trap ’exitCode=l; exit’ 23 # trap в режиме INT/QUIT > .track.old.$$ # обнулить старый track-файл. count=0 # число сканирований так же while [ $count -It $loopCount ]
do who grep $user | sort > .track.new.$$ # сканировать систему diff .track.new.$$ .track.old.$$ | \ sed -f track.sed > .track.report.$$ if [ —s .track.report.$$ ] then echo track report for ${user): cat .track.report.$$ fi mv .track.new.$$ .track.old.$$ sleep $pause count='expr $count +1' done exitCode=0 # изменяется только отчет # вывести отчет # запомнить текущее состояние # подождать немного # обновить счетчик сканирования # установить код возврата Дополнительные встроенные команды Bourne shell поддерживает несколько специализированных встроенных команд. Некоторые, имеющие отношение к структурам управления, мы уже обсудили ранее. В следующих разделах в алфавитном порядке будут описаны остальные встроенные команды. Команда чтения: точка (.) Чтобы выполнить содержимое текстового файла, не запуская subshell, как это происходит при выполнении скрипта, командный интерпретатор использует точку (.), за которой следует имя файла. Файл не должен быть исполняемым. Команда удобна, если пользователь изменяет файл .profile и желает выполнить его повторно. Пример: $ cat .profile ...предположим, что .profile только что редактировался. TERM=vtlOO export TERM $ . .profile ...выполнить его повторно. Обратите внимание, что subshell не создан, любые локальные переменные являются локальными переменными текущего shell.
Команда null Команда null обычно используется в соединении со структурами управления, о которых мы уже поговорили ранее, и не выполняет никакого действия. Она часто указывается в структурах case, чтобы обозначить пустой набор операторов, связанных с конкретной веткой. Синтаксис null Команда null не выполняет никакого действия. Установка опций shell: set Команда зе1позволяет управлять некоторыми опциями shell (табл. 5.5). Таблица 5.5. Опции команды set Опция Описание е Если shell не выполняет команды с терминала или файла запуска, и команда терпит неудачу, тогда происходят системное прерывание err и выход п Принимает, но не выполняет команды. Опция не затрагивает диалоговые shell t Выполняет следующую команду и затем выходит и Генерирует ошибку, когда сталкивается с неустановленной переменной v Выводит команды shell, когда они читаются х Выводит команды shell, когда они выполняются Выключает опции х и v и интерпретирует дальнейшие символы, как аргументы Опции -х и -v полезны в отладке shell-скрипта, т. к. они выводят строки до и после обработки переменной, группового символа и метасимволов замещения команды. Синтаксис set -ekntuvx {аргументы}* Команда set позволяет пользователю выбирать опции shell. Любые указанные аргументы назначаются позиционным параметрам $1, $2 и т. д., переписывая их текущие значения.
В приведенном ниже примере проиллюстрировано использование различных опций команды set: $ cat script.sh ...посмотреть скрипт. set -vx а.с # установить режим отладки и перезаписать $1. Is $1 # получить доступ к первому позиционному параметру. set - # выключить трассировку. echo goodbye $USER echo $notset set -u # неустановленные переменные будут теперь генерировать ошибку. echo $notset # генерировать ошибку. $ script.sh Ь.с ...выполнить скрипт. Is $1 ...вывод от опции -v. + Is а.с ...ВЫВОД ОТ ОПЦИИ -X. а.с ...обычный вывод. set - . ...ВЫВОД ОТ ОПЦИИ -V. + set - ...ВЫВОД ОТ ОПЦИИ -X. goodbye glass ...обычный вывод. script.sh: notset: parameter not set ...доступ к неустановленной ...переменой. $ Усовершенствования В дополнение к новым функциями, которые уже были описаны ранее, в Bourne shell усовершенствованы следующие общие для всех командных интерпретаторов возможности: □ перенаправление ввода/вывода; П использование последовательностей команд. Перенаправление Помимо использования обычных возможностей перенаправления, Bourne shell позволяет дублировать, закрывать и переадресовывать произвольные каналы ввода/вывода. Вы можете связывать стандартный дескриптор ввода файла (0) с файловым дескриптором п, используя следующий синтаксис: $ команда <& п ...связать стандартный ввод. Точно так же можно связывать стандартный дескриптор вывода файла (1) с дескриптором файла п при помощи последовательности: $ команда >& п ...связать стандартный вывод.
Для закрытия каналов стандартного ввода и вывода служит синтаксис: $ команда <&- $ команда >&- ...закрывает стандартный ввод и выполняет команду. ...закрывает стандартный вывод и выполняет команду. Вы можете использовать файловый указатель перед любым метасимволом, который должен применяться вместо 0 (для переназначения ввода) или 1 (для переназначения вывода). Очень часто дескриптор файла 2 соответствует стандартному каналу ошибки. Приведенный ниже пример иллюстрирует использование описанных выше возможностей переназначения. Утилита man всегда пишет "Reformatting page. Wait" ("Переформатирование страницы. Ждите") в стандартный канал ошибки, когда начинает работать, и "done" ("завершено") — после завершения. Если вы переадресовываете только стандартный вывод, эти сообщения появляются на терминале. Для переадресации стандартного канала ошибки в отдельный файл используйте последовательность переназначения 2>. Для записи ошибок в файл стандартного входа указывайте последовательность: 2>*1. Пример: $ man Is > Is.txt Reformatting page. $ man Is > Is.txt $ cat err. txt Reformatting page. $ man Is > Is.txt $ head -1 Is.txt Reformatting page. ...направить стандартный вывод в Is.txt. Wait... done ...из стандартного канала ошибки. 2> err.txt ...направить канал ошибки в err.txt. ...посмотреть файл. Wait... done 2>&1 ...связать канал ошибки со стандартным . . .каналом вывода. ...посмотреть первую строку ls.txt. $ Последовательности команд Если группа команд помещена между круглыми скобками, они выполняются дочерним shell. Bourne shell также позволяет группировать команды, обрамляя их фигурными скобками, в которых разрешено указывать перенаправление ввода/вывода и конвейеризацию внутри группы, при этом команды выполняются непосредственно родительским shell. После открывающей фигурной скобки должен следовать пробел, а после закрывающей — точка с запятой. В представленном ниже примере первая команда cd не затрагивает текущий рабочий каталог shell, т. к. она работает внутри subshell, а вызванная второй раз выполняется shell: $ pwd ...вывести текущий рабочий каталог. /home/glass
$ (cd /; pwd; Is | wc -1) 22 $ pwd /home/glass $ { cd /;>pwd; Is I wc -1; } 22 $ pwd $ ...подсчитать файлы при помощи subshell. ...мой shell не перемещался. ...подсчитать файлы при помощи shell. ...мой shell переместился. Опции командной строки В табл. 5.6 описаны параметры командной строки, поддерживаемые Bourne shell. Таблица 5.6. Параметры командной строки Bourne shell Опция Описание -с строка Создает shell для выполнения командной строки строка -s Создает shell, который читает команды со стандартного ввода и посылает сообщения shell в стандартный канал ошибки -i Создает диалоговый shell; подобна опции -s, за исключением того, что все сигналы sigterm, sigint и sigquit игнорируются (для информации о сигналах см. главу 13) Обзор главы Перечень тем В данной главе мы рассмотрели: □ создание стартового файла Bourne shell; □ создание и доступ к переменным командного интерпретатора; □ арифметические операции; □ условные выражения;
□ шесть структур управления; □ пример проекта для отслеживания сессий пользователя с системой; □ несколько встроенных команд; □ усовершенствования базовых функций. Контрольные вопросы 1. Кто автор Bourne shell? 2. Опишите обычное использование встроенной переменной $$. 3. Как легче всего повторно выполнить пользовательский файл .profile? 4. Какой метод применяется для передачи значения переменной shell в subshell? 5. Какие возможности отладки предоставляет Bourne shell? Упражнения 5.1. Напишите утилиту shheip, которая работает так, как описано ниже. Синтаксис shheip [-к] {команда}* Утилита shheip выводит справку об указанной команде Bourne shell. Опция -к ВЫВОДИТ каждую команду, КОТОрая известна shheip. Вот пример shheip в действии: $ shheip null ...запрос помощи о null. The null command performs no operation. $ _ Удостоверьтесь, что ваша утилита показывает соответствующее сообщение об ошибке, если указана недопустимая команда. Желательно, чтобы текст сообщения справки о каждой команде хранился в отдельном файле, а не внутри скрипта shheip. Если вы решите справку внутри скрипта, пробуйте использовать функцию перенаправления документа в буфер.4 [Уровень: легкий.] 4 См. главу 4. — Ред.
5.2. Напишите утилиту junk. Синтаксис junk [-1] [-p] {имяФайла}* Утилита junk является аналогом утилиты rm. Вместо удаления файлов, она перемещает их в каталог junk, находящийся в домашнем каталоге пользователя. Если .junk не существует, он автоматически создается. Опция -1 выводит текущее содержимое каталога .junk, а опция -р производит очистку этого каталога. Вот пример работы скрипта: $ Is -1 reader.с ...вывести существующие файлы. -rw-r—г— 1 glass 2580 May 4 19:17 reader.с $ junk reader.с ...выполнить j unk! $ Is -1 reader.с reader.c not found ...подтвердить, что он был перемещен. $ junk badguy.c, $ junk -1 ...выполнить junk с другим файлом. ...вывести содержимое каталога .junk. -rw-r—r— 1 glass 57 Мау 4 19:17 badguy.c -rw-r—r— 1 glass 2580 Мау 4 19:17 reader.с $ junk -p ...очистить .junk. $ junk -1 $ ...вывести .junk. Не забывайте подробно комментировать ваш скрипт. [Уровень: средний.] 5.3. Измените скрипт junk так, чтобы он управлялся с помощью меню. [Уровень: легкий.] Проекты. 1. Напишите скрипт ghoul, который трудно "убить". Когда скрипт получает сигнал sigint (от нажатия комбинации клавиш <Ctrl>+<C>), он должен создать перед "смертью" свою копию. Таким образом, каждый раз, когда пользователь пытается ликвидировать ghoul, запускается его копия. Однако он может быть "убит" сигналом sigkill (—9). [Уровень: средний.]
2. Спроектируйте утилиту телефонной книги, которая позволяет просматривать и изменять алфавитный список имен, адресов и телефонных номеров. Используйте утилиты, описанные в главе 3, такие как awk и sed, для поддержки и редактирования информации в файле телефонной книги. [Уровень: высокий.] 3. Постройте утилиту управления процессом, которая позволяет ликвидировать его на основе информации об использовании процессора, ID пользователя, общего количества истекшего времени и т. д. Этот вид утилиты был бы особенно полезен для системных администраторов (см. главу 15). [Уровень: высокий.]
Глава 6 Korn shell Мотивация Korn shell, написанный Дэвидом Корном (David Korn), является более мощной версией Bourne shell и имеет усовершенствования в области управления заданиями, редактирования командной строки и программных возможностей. Это позволило командному интерпретатору Korn shell завоевать большую популярность в мире UNIX-систем. Предпосылки Для понимания этой главы вам необходимо прочитать предыдущую и поэкспериментировать с Bourne shell. Задачи В данной главе рассмотрим специфичные для Korn shell возможности. Изложение По сложившейся уже традиции материал главы представлен в виде нескольких примеров UNIX-сессий. Команды shell Мы рассмотрим следующие команды shell: alias jobs select bg kill typeset fc let unalias fg print function return
Общие сведения о Korn shell Korn shell поддерживает все функции Bourne shell, описанные в главе 5, и содержит следующие дополнительные функции (рис. 6.1): □ настройка команд с использованием псевдонимов; □ доступ к выполненным командам через механизм истории (vi- и emacs-подобные редактирующие возможности командной строки); □ функции; □ расширенное управление заданиями; □ несколько новых встроенных команд и усовершенствованные существующие. jobs bg fg <Ctrl>+<Z> Рис. 6.1. Функциональные возможности Korn shell Запуск Korn shell — это обычная С-программа, выполняемый файл которой хранится как /bin/ksh. Если вашим shell является /bin/ksh, его диалоговый режим активизируется автоматически, в процессе регистрации в UNIX. Можно также вызвать Korn shell вручную из скрипта или с терминала, используя команду ksh, которая имеет несколько опций командной строки. Последовательность запуска Korn shell различна для диалогового и недиалогового shell (табл. 6.1). Значение $env обычно устанавливается в скриптах $HOME/.kshrc и $HOME/.profile. После чтения файлов запуска диалоговый режим Korn shell отображает свое приглашение и ожидает ввода команды. Стандартное приглашение Korn shell — $, хотя оно может быть изменено путем установки локальной переменной psi, описанной в главе 5. Ниже
приведен пример Korn shell скрипта .profile, который выполняется один раз в начале каждой сессии: TERM=vtlOO; export TERM # тип моего терминала. ENV=-/.kshrc; export ENV # имя файла окружения. HISTSIZE=100; export HISTSIZE # помнить 100 команд. MAILCHECK=60; export MAILCHECK # секунды между проверками, set -о ignoreeof # не позволяет <Ctrl>+<D> завершить сессию, set -о trackall # ускорить поиск файла, stty erase ,ЛН* # установить символ возврата, tset # установить терминал. Таблица 6.1. Последовательность запуска Korn shell Шаг Тип командного интерпретатора Действие 1 Только диалоговый Выполняет команды из /etc/profile, если он существует 2 Только диалоговый Выполняет команды из $номе/. profile, если он существует 1 3 Оба Выполняет команды из $env, если он существует Некоторые из этих команд могут быть вам непонятны, но их значение станет ясным по мере чтения главы. Ниже показан пример Korn shell скрипта .kshrc, содержащего, как правило, полезную специфичную для этой оболочки информацию, используемую всеми shell, включая те, которые были созданы исключительно для выполнения скриптов: РАТН='.:-/bin:/bin:/usг/bin:/usг/local/bin:/gnuemacs’ PS1=’! $ export PSI # поместить номер команды в подсказку. alias h="fc -1” # установить полезные псевдонимы, alias ll="ls -1” alias rm=,,m -i" alias ccb^'ccLx" alias up="cdx .." alias dir="/bin/ls” alias ls="ls -aF" alias env="printenv|sort" # Функция, чтобы показывать путь и каталог при перемещении function cdx
{ if ’cd’ ’^G" then echo $PWD Is -aF fi } Каждый Korn shell, включая все subshell, выполняет этот скрипт при запуске. Псевдонимы Korn shell позволяет создавать собственные команды, используя псевдонимы (alias). Ниже проиллюстрирована работа команды alias: $ alias dir='ls -aF1 ...регистрировать псевдоним. $ dir ...то же самое, как напечатать Is -aF. ./ main2.c р.reverse.c reverse.h ../ main2.o palindrome.c reverse.old $ dir *.c ...то же самое, как напечатать Is -aF *.c. main2.c p.reverse.c palindrome.c $ alias dir ...определение dir. dir=ls -aF $ Синтаксис •alias [-tx] [слово [=строка]] Команда alias поддерживает простую форму настройки командной строки. Если слово псевдонима равно строке, а вы вводите команду, начинающуюся с этого словз^ первое появление словз заменяется строкой^ и команда обрабатывается повторно. Если слово или строка не определены, то выводится список всех текущих псевдонимов shell. Если пользователь указывает только слово, то выводится строка, в настоящее время связанная со словом псевдонима. Если слово и строка указаны, shell добавляет данный псевдоним в свою коллекцию. В случае, если псевдоним для слова уже существует, он заменяется. Если строка замены начинается со слова, оно не обрабатывается повторно для псевдонимов, предотвращая, таким образом, бесконечные циклы. Если строка замены заканчивается пробелом, то следующее слово обрабатывается, как псевдоним.
Пример: $ alias ls='ls -aFr ...нет проблем. $ Is *.c ...аналогично Is -aF *.c. main2.c p.reverse.c palindrome.c $ alias dir='ls' ...определить dir через Is. $ dir ...аналогично Is -aF. , / main2.c p.reverse.c reverse.h • • / main2.о palindrome.c reverse.old $ Создание псевдонимов встроенных команд Все встроенные команды за исключением case esac select { do fi then } done for time elif function until else if while могут иметь псевдонимы. Удаление псевдонимов Чтобы удалить псевдоним, используйте команду unalias. Синтаксис unalias {слово}+ Команда unalias удаляет все указанные псевдонимы. Пример: $ alias dir . . .посмотреть существующий псевдоним. dir=ls $ unalias dir ...удалить псевдоним. $ alias dir ...попытка посмотреть псевдоним снова, dir alias not found $
Предопределенные псевдонимы В табл. 6.2 представлены предопределенные псевдонимы Korn shell. Их использование станет понятным по мере изучения главы. Например, псевдоним г очень удобен для повторного вызова предыдущих команд вместо длинной последовательности fc -е * Таблица 6.2. Предопределенные псевдонимы Korn shell Псевдоним Значение false let 0 functions typeset -f history fc -1 integer typeset -i nohup nohup r fc -e - true type whence -v hash alias -t Некоторые полезные псевдонимы В табл. 6.3 перечислены полезные псевдонимы. Другие интересные псевдонимы рассмотрены в главе 7. Таблица 6.3. Некоторые полезные псевдонимы Псевдоним Значение Описание rm rm -i Указывает rm о необходимости запрашивать подтверждение mv mv -i Указывает mv о необходимости запрашивать подтверждение Is Is -aF Указывает 1s о необходимости выводить подробную информацию env printenv | sort Демонстрирует отсортированный список переменных окружающей среды 11 Is -1 Позволяет получить более удобный расширенный листинг каталога
Псевдонимы путей Обычное использование псевдонимов — это сокращение полного путевого имени. Чтобы ускорить процесс поиска, воспользуйтесь псевдонимами путей. Все псевдонимы с опцией -t интерпретируются, как псевдонимы путей, и для того чтобы установить их первоначальное значение служит механизм поиска. В этом случае псевдоним пути заменяется его значением, таким образом сводя время поиска к минимуму. Если за опцией -t не указано ни одного псевдонима, выводится весь список текущих псевдонимов путей. Например: $ alias -t page ...определить псевдоним пути для раде. $ alias -t ...посмотреть все псевдонимы путей. page=/usr/ucb/page ...сохранено его полное путевое имя. $ Опция -о trackaii команды set (которая будет описана чуть позже в этой главе) предписывает shell отслеживать все команды автоматически, как показано в следующем примере: $ set -о trackaii ...все команды теперь заносятся в список псевдонимов. $ date ...выполнить date. Fri Feb 6 00:54:44 CST 1998 $ alias -t ...посмотреть все псевдонимы путей. date=/bin/date ...date теперь в списке псевдонимов. page=/usr/ucb/page $ _ - Так как значение псевдонима пути зависит от переменной $ратн, все псевдонимы путей вычисляются повторно всякий раз, когда она изменяется. Если переменная path не определена, значения всех псевдонимов путей оказываются установленными на пустой указатель, но при этом остаются в списке псевдонимов. Экспортируемые псевдонимы Чтобы сделать псевдоним доступным дочернему shell, необходимо пометить его как экспортируемый псевдоним, указывая в команде alias после опции -х. Если псевдонимы опущены, выводится список всех текущих экспортируемых псевдонимов. Внимание Если значение псевдонима изменено в дочернем shell, это не затрагивает значение первоначального псевдонима в родительском.
Пример использования экспортированного псевдонима: $ alias -х mroe='morer ...добавить экспортируемый псевдоним. $ alias -х ...посмотреть экспортируемые псевдонимы. autoload=typeset -fu ...стандартный псевдоним. ... ...другие псевдонимы выводятся здесь. ls=ls -F mroe=more ...псевдоним, который я только что добавил. . . . ...другие псевдонимы выводятся здесь. type=whence -v vi=/usr/ucb/vi $ cat test.ksh mroe main2. c ...скрипт, использующий новый псевдоним. $ test.ksh /★ MAIN2.C */ #include #stdio.h, #include "palindrome.h" main () ...выполнить скрипт, mroe работает! printf ("palindrome (\"cat\") = %d\n", palindrome ("cat")); printf ("palindrome (\"noon\") = %d\n", palindrome ("noon")); } $ История Korn shell хранит список команд, введенных с клавиатуры для того, чтобы их можно было отредактировать и выполнить повторно позднее. Эта функция известна как механизм истории. Встроенная команда fc (от англ, fix command) дает к ней доступ. Есть две формы f с. Первая, более простая, разрешает выполнить повторно указанный набор команд; вторая, более сложная, позволяет редактировать их перед повторным выполнением. Пронумерованные команды При использовании истории очень удобно знать номер команды, которую вы собираетесь ввести. Для этого укажите в переменной приглашения psi символ $ PS1=’! $ ' 103 $ ...установка, чтобы PS1 содержала символ !. ...приглашение для команды с номером 103.
Сохранение команд Korn shell записывает выполненные команды в количестве $histsize в файл $histfile. Если переменная окружения histsize специально не задана, ее значение по умолчанию равно 128. Если имя файла histfile не установлено или указанный файл не имеет прав записи, то по умолчанию используется файл $HOME/.sh_history, единый для всех Korn shell. Поэтому пока пользователь не изменит значение $histfile во время сессии, введенные команды доступны, как история для применения в следующей сессии. Ниже приведен файл, в котором сохранена история выполнения команд: $ echo $HISTSIZE ...установлена в .profile. 100 $ echo $HISTFILE ...не установлена предварительно. $ tail -3 $НСМЕ/.sh_history ...вывести последние 3 строки. echo $HISTSIZE echo $HISTFILE tail -3 $НОМЕ/.sh_history $ Повторное выполнение команд Команда fc позволяет повторно выполнять отработанные команды. Синтаксис fc -е - [стараяСтрока=новаяСтрока] префикс Вариант команды fc, которая повторно выполняет предыдущую команду, начинающуюся с префикса после необязательной замены первого появления старойСтроки новойСтрокой. префикс МОЖеТ быть ЧИСЛОМ, В ЭТОМ случае повторно выполняется пронумерованное событие. Пример: 360 $ fc -е - ech ...последняя команда, начинающаяся с ech. echo $HISTFILE 361 $ fc -e - FILE=SIZE ech ...заменить FILE на SIZE, echo $HISTSIZE 100 362 $ fc -e - 360 echo $HISTFILE 363 $ ...выполнить команду с номером 360.
Символ г — предопределенный псевдоним для команды fc -е позволяющий более удобным способом повторно выполнить команды: 364 $ alias г ...посмотреть на псевдоним г. r=fc -е 365 365 $ г 364 ...выполнить команду с номером 364. alias г r=fc -е - 366 $ Редактирование команд Korn shell позволяет выполнить предварительное редактирование команд до их повторного выполнения. Пример: 371 $ whence vi ...найти расположение vi. /usr/ucb/vi 372 $ FCEDIT=/usr/ucb/vi ...присвоить FCEDIT значение полного пути. 373 $ fc 371 ...редактировать команду с номером 371. ...войти в vi, редактировать команду для замены ...на whence Is, сохранить, выйти из vi. whence Is ...вывести отредактированную команду. /bin/Is ...вывод от отредактированной команды. 374 $ fc 371 373 ...редактировать команды с номерами 371-373. ...войти в vi и редактировать список последних трех команд. ...предположим, что я удалил первую строку, ...изменил оставшиеся строки ...на echo -n hi и echo there, и затем вышел. echo —n "hi " ...вывести редактированные команды, echo there hi there ...вывод от отредактированных команд. 375 $ Синтаксис fc [-е редактор] [-nlr] [начало] [конец] Данный вариант синтаксиса команды fc позволяет вызвать редактор с указанным диапазоном команд. После выхода из него выполняется отре
дактированный набор команд. Если редактор не указан, то используется редактор, путь к которому указан в переменной окружения fcedit. По умолчанию значение $fcedit равно /bin/ed, но желательно не использовать это значение. Неплохим вариантом будет /usr/ucb/vi (либо другой полный путь до редактора vi в вашей системе), или путь до иного редактора, с которым вы хорошо знакомы. Если другие опции не определены, редактор вызывается для предыдущей команды. После выхода из редактора Кот shell автоматически повторяет и выполняет ее сохраненную версию. Чтобы определить конкретную команду по ее индексу или префиксу, укажите номер или префикс как значение начала, но не задавайте значение конца. Задание диапазона команд осуществляется так: установите значение начала, чтобы выбрать первую команду в серии, и значение конца, чтобы выбрать последнюю. Отрицательный номер интерпретируется, как смещение по отношению к текущей команде. Опция -1 показывает выбранные команды, но не выполняет их. Если команды не определены, выводятся 16 последних. Опция -г инвертирует порядок отобранных команд, а опция -п запрещает генерацию их номеров при выводе. Пример использования опции -1: 376 $ fc -1 371 373 ...вывести команды с номерами. 371 $ whence vi 372 $ FCEDIT= /usr/ucb/vi 373 $ fc 371 377 $ fc -6 ...редактировать команду с номером 371. . . . редактировать команду для замены на whence Is и затем выйти, whence Is ...вывод отредактированной команды. /bin/Is ...вывод в результате выполнения команды. 378 $ Редактирование команд Korn shell содержит упрощенные встроенные версии редакторов vi, gmacs и emacs для редактирования текущей или предыдущей команд. Чтобы выбрать один из встроенных редакторов, задайте в переменных visual или editor строку, которая заканчивается именем одного из них. Следующий пример иллюстрирует выбор редактора vi: 380 $ VISUAL=vi ...выбрать встроенный редактор vi. 381 $
Встроенный редактор vi Дальнейшее описание предполагает, что вы немного знакомы с редактором vi, который был описан в главе 2. Начните редактирование текущей строки нажатием клавиши <Esc> для входа в командный режим vi, а затем сделайте необходимые изменения. Для перехода из командного режима в режим добавления или вставки нажмите соответственно клавишу <а> или <i>. Возврат в командный режим осуществляется нажатием клавиши <Esc>. Для повторного выполнения команды служит клавиша <Enter>. Внимание Будьте внимательны: если вы нажмете комбинацию клавиш <Ctrl>+<D>, находясь в редакторе, то завершите работу shell, а не редактора. В командном режиме ключевые последовательности попадают в одну из следующих категорий: □ стандартные ключевые последовательности vi (см. главу 2)\ □ дополнительные перемещения; □ дополнительный поиск; □ маскирование имени файла; □ замещение псевдонима. Дополнительные перемещения Клавиши <Т> (<к> или <->) и <J^> (<j> или <+>) позволяют выбрать соответственно предыдущие и следующие команды в списке истории. Это облегчает доступ к ним из встроенного редактора. Чтобы загрузить команду с конкретным номером, перейдите в командный режим, а затем введите номер команды, сопровождаемый нажатием клавиши <G>. Пример: 125 $ echo line 1 line 1 126 $ echo line 2 line 2 127 $ . . . в этом месте я нажал клавишу <Esc> с последующим двойным ....нажатием клавиши <к>. Это действие загрузило команду . . .с номером 125 в командную строку, которую я затем выполнил ...путем нажатия клавиши <Enter>. line 1 128 $ ...здесь я нажал клавишу <Esc> с последующим 125 <G>.
...Это действие загрузило команду с номером 125 в командную строку, ...которую я затем выполнил путем нажатия клавиши <Enter>. line 1 129 $ _ Дополнительный поиск Стандартные конструкции /строка и ?строка производят поиск команды соответственно назад и вперед по списку истории. Например: 127 $ echo line 1 line 1 138 $ echo line 2 line 2 139 $ ...в этом месте я нажал клавишу <Esc> с последующим вводом /ech, ...что загрузило последнюю команду, содержащую строку ech, ... в командную строку. ...Затем я нажал клавишу <п> для продолжения поиска ...очередной команды, которая совпала с искомой. В завершение ...я нажал клавишу <Enter> для выполнения команды. line 1 $ _ Использование маски для имени файла Использование звездочке (*) в командном режиме добавляет ее к слову, на котором расположен курсор, вследствие чего слово будет обработано, как маска для замены имен файлов. Если совпадения не произойдет, пользователь услышит звуковой сигнал. В противном случае слово будет заменено списком в алфавитном порядке всех соответствующих имен файлов, и редактор автоматически перейдет в режим ввода. Пример: 114 $ Is m* m m3 main.c mbox ml madness . c main, о mon.out m2 main makefile myFile 115 $ Is ma ... в этом месте я нажал клавишу <Esc> . . . и клавишу <*>, а затем клавишу <Enter>. 115 $ Is madness.c main main.с main.о makefile madness.c main.с makefile main main.о 116 $
Если вы используете символ равно (=) в командном режиме, редактор выводит пронумерованный список всех файлов, которые содержат текущее слово как префикс, а затем повторно выводит командную строку: 116 $ 1s та ...в этом месте я нажал клавишу <Esc>, ...а затем клавишу <=>. 1) madness.с 2) main 3) main.с 4) main.о 5) makefile 116 $ Is та_ ...возврат к первоначальной командной строке. При использовании символа косой черты (/) в командном режиме редактор пытается интерпретировать имя текущего файла. Если оно соответствует каталогу, добавляется /; иначе добавляется пробел. Пример: 116 $ 1s та ...в этом месте я нажал клавишу <Esc>, а затем клавишу <\>. ...завершения не было выполнено, поскольку "та" — ...это префикс больше, чем одного файла. 116 $ 1s так ...в этом месте я нажал клавишу <Езс>, а затем клавишу <\>. ... Редактор дописал имя, и получилось "makefile". 116 $ Is makefile _ Замещение псевдонима Если, работая в редакторе, вы часто указываете один и тот же шаблон, можно воспользоваться механизмом замены псевдонимов. Если вы задаете _символ, как псевдоним слова, последовательность @ символ заменяется словом в командном режиме. В представленном ниже примере символ i в начале псевдонима переводит встроенный редактор в режим вставки, а нажатие клавиши <Esc> в конце строки заставляет его завершить сеанс vi: 123 $ alias _с= ' icommon text^[' . ..Л[ — это символ от комбинации ...клавиш <Ctrl>+<V>, который будет ...сгенерирован после <Esc> 124 $ echo ...в этом месте я нажал клавишу <Esc> за @с 124 $ echo common text Встроенный редактор emacs/gmacs Дальнейшее описание предполагает, что вы знакомы с редактором emacs, который был представлен в главе 2. Во встроенном редакторе поддерживается
большинство ключевых последовательностей emacs. Вы можете перемещать курсор и управлять текстом, используя стандартные ключевые последовательности редактора emacs. Для повторного выполнения команды следует нажать клавишу <Enter>. Главное различие между встроенным редактором и стандартным emacs в том, что ключевые последовательности перемещения курсора или вниз, поиск вперед и обратный поиск работают в списке истории. Например, последовательность <Т> <Ctrl>+<P> показывает предыдущую команду в командной строке. Точно так же ключевая последовательность обратного поиска <Ctrl>+<R> строка демонстрирует самую последнюю команду, содержащую строку. Арифметические действия Команда let позволяет выполнять арифметические вычисления. Синтаксис let выражение Команда let выполняет арифметические вычисления над целыми числами двойной точности и поддерживает все основные математические операторы, используя стандартные правила предшествования. Они приведены ниже в порядке уменьшения приоритета операций: Оператор Описание । Унарный минус Логическое отрицание * / 9- > /> ° Умножение, деление, остаток Сложение, вычитание < j > > о Операторы отношения == 1 = » • Равенство, неравенство = Присвоение Все операторы объединяются слева направо за исключением оператора присвоения. Выражения могут быть помещены между круглыми скобками для изменения порядка вычисления. Shell не проверяет переполнение, учитывайте это! Операнды могут быть целочисленными кон-
стантами или переменными. Когда встречается переменная, она заменяется значением, которое в свою очередь может содержать другие переменные. Вы можете явно заменить основание по умолчанию (10), используя формат основание#значение, Где основание — ЭТО ЧИСЛО между.2 и 36. Нельзя помещать пробелы или знаки табуляции между операндами или операторами. Недопустимо размещать $ перед переменными, которые являются частью выражения. Вот несколько примеров работы команды let: $ let х = 2 + 2 ksh: =: syntax error $ let x=2+2 $ echo $x 4 $ let y=x*4 $ echo' $y 16 $ let x=2#100+2#100 $ echo $x 4 $ ...выражение содержит пробелы. ...пробелы или табуляция недопустимы! ...хорошо. ...не помещайте $ перед переменными. ...сложить два двоичных числа. ...число выводится в десятичной системе. Предотвращение интерпретации метасимволов К сожалению, shell интерпретирует некоторые из стандартных операторов типа <, > и * как метасимволы. Поэтому они должны быть заключены в кавычки или им должна предшествовать обратная косая черта (\) для запрещения интерпретации их как специальных. Чтобы избежать этого неудобства, существует эквивалентная форма команды let, которая автоматически оперирует всеми символами, как будто они были окружены двойными кавычками, и позволяет использовать пробелы вокруг символов. Например, последовательность (( list )) эквивалентна let " list " Я лично всегда использую синтаксис ( о ) вместо let. Вот пример: $ (( х = 4 )) ... пробелы — это нормально. $ (( у = х * 4 ))
$ echo $y 16 $ _ Возвращаемые значения Если результат вычисления выражения равен 0, возвращается код 1; иначе — 0. Код возврата может использоваться структурами управления, например, оператором if, как в этом примере: $(( х = 4 )) ...4 присвоить х. $ if (( х > 0 )) ...использовать в структуре управления. > then > echo х is positive > fi x is positive ...вывод структуры управления. $ Для простых арифметических проверок стоит использовать ((..)) вместо test-выражений. Замена тильды Любое обозначение в формате -имя является объектом замены тильды. Командный интерпретатор проверяет файл пароля, чтобы определить, является ли имя именем пользователя и, если это так, заменяет последовательность -имя полным именем пути до домашнего каталога пользователя. В противном случае последовательность —имя остается неизменной. Замена тильды происходит после обработки псевдонимов. В табл. 6.4 приведен список замен тильды, включая специальные случаи -+ и —. Таблица 6.4. Замена тильды в Korn shell Последовательность тильды Заменяется на $НОМЕ -user домашний каталог пользователя — user -/путь $ НОМЕ/путь -+ $PWD (текущий рабочий каталог) .— $OLDPWD (предыдущий рабочий каталог) Ю Зак. 786
Предопределенные локальные переменные pwd и oldpwd будут описаны позже в этой главе. Ниже приведены некоторые примеры замены тильды: $ pwd /home/glass $ echo ~ /home/glass $ cd / $ echo $ echo — /home/glass $ echo ~dcox /home/de ox $ ...текущий рабочий каталог. ...мой домашний каталог. ...изменить на корневой каталог. ...текущий рабочий каталог. ...предыдущий рабочий каталог. ...домашний каталог другого пользователя. Меню: select Команда select позволяет создавать простые меню. Она выводит пронумерованный список слов, указанных в in-выражении в стандартном канале ошибок, после чего отображает приглашение, хранящееся в специальной переменной PS3, а затем ждет входную строку от пользователя. Когда пользователь вводит строку, та сохраняется в предопределенной переменной reply. Далее происходит одно из следующих действий: □ если пользователь ввел одно из предложенных чисел, имя устанавливается равным этому числу, команды из списка выполняются, посде чего вновь выводится приглашение, и система ожидает выбор очередной команды; П если пользователь ввел пустую строку, варианты выбора выводятся снова; П если пользователь указал отсутствующий вариант, имя устанавливается на пустой указатель, команды из списка выполняются, и выводится приглашение сделать другой выбор. Синтаксис select имя [in {слово}+] do списокКома нд done
Приведенный ниже пример заменяет цикл while более простой командой select! $ cat menu.ksh ...вывести скрипт, к echo menu test program select reply in "date" "pwd" "pwd" "exit" do case $reply in "date") date 11 "pwd") pwd "exit") break r r *) echo illegal choice z / esac done $ menu.ksh ...выполнить скрипт, menu test program 1) date 2) pwd 3) pwd 4) exit #? 1 Fri Feb 6 21:49:33 CST 1998 #? 5 illegal choice #? 4 $ _ Функции Korn shell позволяет определять функции, которые могут быть вызваны, как команды shell. Параметры, передаваемые функциям, доступны через стан
дартный механизм передачи параметров. Функции должны быть определены перед их использованием. Существуют два способа определить функцию (см. синтаксис). Рекомендуется использовать вторую форму, т. к. она похожа на конструкцию в языке С. Для вызова функции следует ввести ее имя, сопровождаемое соответствующими параметрами. По очевидным причинам shell не проверяет количество или тип параметров. Синтаксис function имя { списокКоманд Ключевое слово function может быть опущено: имя{) списокКоманд Ниже представлен пример скрипта, который определяет и использует функцию, которая не имеет параметров: $ cat fund. ksh ...вывести скрипт. message () # нет параметров функции. { echo hi echo there } i=l while (( i <= 3 )) do message ' # вызов функции. let i=i+l # увеличить на единицу счетчик цикла, done $ fund. ksh . . . выполнить скрипт. hi there hi /
there hi there $ Использование параметров в функциях Как уже было отмечено, параметры передаются функции стандартным способом. Пример: $ cat func2.ksh f О { echo parameter 1 = $1 echo parameter list = $* } # main program. f 1 f cat dog goat $ func2.ksh parameter parameter parameter parameter $ . . .вывести скрипт. # вывести первый параметр. # вывести входной список. # вызвать с одним параметром. # вызвать с тремя параметрами ...выполнить скрипт. 1 = 1 list = 1 1 = cat list = cat dog goat Возврат из функции Команда return возвращает значение. Синтаксис return [ значение ] Когда return используется без аргументов, передается код возврата последней выполненной в функции команды. Иначе, возвращается код, равный значению. Если команда return выполняется из главного скрипта, она эквивалентна команде exit. Код возврата доступен вызывающему процессу через переменную $?.
Ниже в качестве примера приведена функция, которая перемножает аргументы и возвращает результат: $ cat func3.ksh ...вывести скрипт, f () # функция с двумя параметрами. (( returnValue = $1 * $2 )) return $returnValue } # main program. f 3 4 # вызов функции. result=$? # сохранить код возврата, echo return value from function was $result $ func3.ksh ...выполнить скрипт, return value from function was 12 $ Контекст Функция выполняется в том же самом контексте, что и процесс, который вызывает ее. Это означает, что функция и процесс разделяют одни и те же переменные, текущий рабочий каталог и перехватчики событий. Единственное исключение — событие выхода, которое наступает, когда функция выполняет возврат. Локальные переменные Команда typeset (которая далее будет описана более подробно) имеет специальные ориентированные на функцию возможности. Созданная с использованием typeset переменная ограничивается областью действия функции, в которой она создана, и всех вызываемых функций. Если переменная с указанным именем уже существует, ее значение заменяется, когда функция выполняет возврат. Эта особенность напоминает понятие "область действия переменной" в языках программирования высокого уровня. В следующем примере используется команда typeset для объявления локальной переменной: $ cat func4.ksh f О typeset х (( х = $1 * $2 )) ...вывести скрипт. # функция с двумя параметрами. # объявить локальную переменную. # установить локальную переменную.
echo local x = $x return $x } # main program. x=l # установить глобальную переменную. echo global x = $x # вывести значение перед функциональным вызовом. f 3 4 # вызвать функцию. result=$? # сохранить код возврата. echo return value from function was $result echo global x = $x # значение после функции. $ func4.ksh ...выполнить скрипт. global х = 1 local x = 12 return value from function was 12 global x = 1 $ Рекурсия Как показывает практика, во многих случаях целесообразно использовать рекурсивные функции. Ниже приведены два скрипта, которые выполняют рекурсивное вычисление факториала — factorial о. Первый использует код возврата, чтобы вернуть результат, а второй — стандартный вывод для отображения результата. Внимание Эти скрипты доступны в сети (см. Введение для получения дополнительной информации). Рекурсивный факториал: использование кода возврата 4 factorial () # функция с одним параметром. if (( $1 <= 1 )) then return 1 # вернуть результат в коде возврата, else typeset tmp # объявить две локальных переменных, typeset result
( ( tmp = $1 - 1 ) ) factorial $tmp # вызвать рекурсивно. ( ( result = $?*$!)) return $result # передать результат в коде возврата, fi } # main program, factorial 5 # вызвать функцию echo factorial 5 = $? # вывести код возврата. Рекурсивный факториал: использование стандартного вывода factorial () # функция с одним параметром { if (( $1 <= 1 )) then echo 1 # вывести результат на стандартный вывод, else typeset tmp # объявить две локальных переменных, typeset result (( tmp = $1 - 1 )) (( result = 'factorial $tmp' * $1 ) ) echo $result # вывести результат на стандартный вывод, fi } # echo factorial 5 = 'factorial 5' # вывод результата. Использование кода функций в нескольких скриптах Для использования исходного кода функции в нескольких скриптах следует сохранить его в отдельном файле, а прочитать его можно с помощью встроенной команды в начале скрипта, содержащего функцию. Предположим, что исходный код одного из предыдущих скриптов вычисления факториала был сохранен в файле fact.ksh: $ cat.ksh ...вывести скрипт. . fact.ksh # читать исходный код функции, echo factorial 5 = 'factorial 5' # вызов функции.
$ func6.ksh ...выполнить скрипт, factorial 5 = 120 $ Расширенное управление заданиями Korn shell дополняет возможности управления заданиями Bourne shell и поддерживает команды, перечисленные в табл. 6.5. Они доступны только в UNIX-системах, которые поддерживают управление заданиями. Следующие несколько разделов содержат описание управления заданиями и примеры их использования. Особенности управления заданиями Korn shell идентичны средствам командного интерпретатора С shell, о котором речь пойдет в следующей главе. Таблица 6.5. Команды управления заданием Korn shell Команда Описание jobs Выводит задания пользователя bg • Помещает специфицированное задание в фоновый режим fg Помещает специфицированное задание в приоритетный режим kill Посылает произвольный сигнал процессу или заданию Задания Команда shell jobs выводит список всех заданий данного командного интерпретатора. Синтаксис jobs [-1] Команда jobs выводит список всех работ shell. В случае использования с опцией -1 к листингу добавляется ID процесса. Синтаксис каждой выводимой строки выглядит следующим образом: номерЗадания [+|~] PID Статус Команда Здесь + и - соответственно означают, что задание было последним или предпоследним, помещенным в фоновое выполнение. Статус может быть таким: • Running (Выполняется); • stopped (Остановлено (отложено));
• Terminated (Прекращено ("убито" сигналом)); • Done (Выполнено (нулевой код возврата)); • Exit (Выход (ненулевой код возврата)). Основное назначение символов + и - состоит в том, что они могут использоваться при определении задания в следующей команде (см. разд. "Спецификация задания " далее в этой главе). Пример: $ jobs ...нет заданий. $ sleep 1000 & ...запустить фоновое задание. [1] 27128 $ man Is | ul -tdumb > Is.txt & ...другое фоновое задание. [2] 27129 $ jobs -1 ...вывести текущие задания. [2] +27129 Running man Is 1 ul -tdumb > Is.txt & [1] - 27128 Running sleep 1000 & $ _ Спецификация задания Команды bg, fg, и kill позволяют специфицировать работу с помощью одного из форматов, перечисленных в табл. 6.6. Таблица 6.6. Спецификация заданий в Korn shell Форма Специфицирует %целоеЗначение Задание с номером целоеЗначение % префикс Задание, чье имя начинается с префикса 9- 4-Ъ Т Задание, которое было указано последним о. 9-о о То же самое, что и % + С о Задание, которое было указано предпоследним bg Команда shell bg возобновляет указанное задание как фоновый процесс. В следующем примере задание выполнялось в приоритетном режиме, а потом было приостановлено нажатием комбинации клавиш <Ctrl>+<Z> и переведено в фоновый.
Ниже приведены используемые для этого команды: $ man ksh | ul -tdumb > ksh.txt ...запустить в приоритетном режиме. AZ ...приостановить его. [1] + Stopped man ksh | ul -tdumb > ksh.txt $ bg %1 ... возобновить в фоновом режиме. [1] man ksh | ul -tdumb > ksh.txt & $ jobs ...вывести текущие задания. [1] + Running man ksh | ul -tdumb > ksh.txt $ Синтаксис bg [%задание] Команда shell bg возобновляет указанное задание, как фоновый процесс. Если никакое задание не определено, возобновляется последнее. fg Команда shell fg возобновляет указанное задание, как приоритетный процесс. Синтаксис fg [%задание] Команда shell fg возобновляет указанное задание, как приоритетный процесс. Если никакое задание не специфицировано, возобновляется последнее упомянутое задание. В представленном ниже примере фоновое задание было переведено в приоритетный режим: $ sleep 1000 & [1] 27143 $ man ksh | ul [2] 27144 $ jobs [2] + Running [ 1] - Running -tdumb > ksh.txt & ...запустить фоновое задание. ...запустить другое. ...вывести текущие задания. man ksh | ul -tdumb > ksh.txt & sleep 1000 &
$ fg %та . . .перевести задание в приоритетный режим, man ksh I ul -tdumb > ksh.txt ...команда выводится повторно. $ kill Команда shell kill посылает сигнал указанному заданию или процессам. Синтаксис kill [-1] [-сигнал] {процесс | %задание}+ Команда shell kill посылает сигнал указанному заданию или процессам. Процесс задается его номером PID. Сигнал может быть определен или его номером, или символически, путем удаления приставки "SIG" из символической константы в файле /usr/include/sys/signal.h. Чтобы получить список сигналов, используйте опцию -1. Если сигнал не определен, посылается сигнал term. Если сигнал term или hup был отправлен приостановленному процессу, посылается сигнал cont, который возобновляет его. Пример: $ kill -1 ...вывести все сигналы kill. 1) HUP 12) SYS 23) STOP 2) INT 13) PIPE 24) TSTP 3) QUIT 14) ALRM 25) CONT 4) ILL 15) TERM 26) TTIN 5) TRAP 16) USR1 27) TTOU 6) ABRT 17) USR2 28) VTALRM 7) EMT 18) CHLD 29) PROF 8) FPE 19) PWR 30) XCPU 9) KILL 20) WINCH 31) XFSZ Ю) BUS 21) URG 11) SEGV 22) POLL $ man ksh | ul -tdumb > ksh. txt & ...запустить фоновое задание. [1] 27160 $ kill -9 %1 ..."убить" его через спецификацию задания. [1] + Killed man ksh | ul -tdumb > ksh.txt & $ man ksh | ul -tdumb > ksh.txt & ...запустить другое. [1] 27164
$ kill -KILL 27164 [1] + Killed $ ..."убить” его через ID процесса, man ksh ul -tdumb > ksh.txt & Усовершенствования В дополнение к новым возможностям, которое уже были описаны, Кот shell содержит усовершенствования следующих возможностей: □ перенаправление; □ конвейеры; □ замещение команд; П доступ к переменной; □ дополнительные встроенные команды. Перенаправление Korn shell имеет некоторые усовершенствования перенаправления, а именно, способность удалять ведущие символы табуляции в документах, находящихся в буфере1. Если слову предшествует знак -, то ведущие символы табуляции удаляются из строки, введенной со стандартного входа. Синтаксис команда « [-] слово Пример: $ cat «- ENDOFTEXT this input contains > some leading tabs > '"D z this input contains some leading tabs $ _ Данный пример команды позволяет тексту, находящемуся в буфере, в скрипте размещаться с отступом, чтобы соответствовать близлежащим командам shell. 1 См. разд. "Перенаправление ввода в буфер shell" главы 4. — Ред.
Конвейеры Оператор | & поддерживает простую форму параллельной обработки. Когда команда сопровождается |&, она выполняется как фоновый процесс, стандартный ввод и вывод которого связаны с первоначальным родительским shell двусторонним конвейером. Когда первоначальный shell генерирует вывод, используя команду print -р, он посылается на стандартный канал ввода дочернего shell. Когда первоначальный shell читает ввод, используя команду read -р, он принимается со стандартного вывода дочернего shell. Вот пример: $ date |& ...начать дочерний процесс. [1] 8311 $ read -р theDate ...читать со стандартного вывода дочернего процесса. [1] + Done * date |& ... дочерний процесс прекратился. $ echo $theDate ...вывести результат. Sun Мау 10 21:36:57 CDT 1998 $ Замещение команды В дополнение к уже описанному методу замещения команды (окружения ее тупыми штрихами (')) Korn shell позволяет выполнять замену команды, используя следующий синтаксис: $ (команда) Обратите внимание, что символ $, который непосредственно предшествует открывающей круглой скобке, является частью синтаксиса, а не приглашением shell. Пример: $ echo there are $(who | wc -1) users on the system there are 6 users on the system $ _ Чтобы подставить содержимое файла в команду shell, используйте конструкцию $ (<имяФайла) вместо более длинной формы $(cat имяФайла}
Переменные Korn shell поддерживает следующие дополнительные средства работы с переменными: □ более гибкие методы доступа; □ предопределенные локальные переменные; □ предопределенные переменные окружения; □ простые массивы; □ команду typeset для форматирования вывода переменных. Гибкие методы доступа В дополнение к методам доступа к переменной, поддерживаемым Bourne shell, Korn shell реализует возможности работы с ними, перечисленные в табл. 6.7. Таблица 6.7. Методы доступа к переменной в Korn shell Синтаксис Действие ${#имя} Заменяется длиной значения имя ${#ИМЯ[* ] } Заменяется числом элементов в массиве имя ${имя:+слово} Работают подобно аналогам, которые не содержат :, за исклю- ${имя:=слово} чением того, что имя должно быть установлено и не равно нулю, а не просто определено ${имя:2 слово} ${имя:+слово} $ {имяЪша блон] Удаляет ведущий шаблон из имени. Выражение заменяется зна- $ {имя# #ша блон} чением имя, если оно не начинается с шаблона, и оставшимся суффиксом, если оно начинается с шаблона. Первая форма синтаксиса удаляет самый маленький шаблон соответствия, а вторая — большой $ {имя%та блон} Удаляет замыкающий шаблон из имени. Выражение заменяется $ {имя% % та блон} значением имя, если оно не заканчивается шаблоном, и оставшимся суффиксом, если оно завершается шаблоном. Первая форма синтаксиса удаляет самый маленький шаблон соответствия, вторая — самый большой Вот некоторые „примеры: $ fish='smoked salmon' ...установить переменную. $ echo ${#fish} ...вывести длину значения переменной.
13 $ cd dirl ...переместиться в каталог. $ echo $PWD ...вывести текущий рабочий каталог, /home/glass/dirl $ echo $HOME /home/glass $ echo ${PWD#$HOME/} ...удалить ведущее $НОМЕ/ dirl $ fileName=menu.ksh ...установить переменную. $ echo $ {fileName%. ksh} .bak ...удалить замыкающее .ksh menu.bak - ...и добавить .bak. $ Предопределенные локальные переменные В дополнение к стандартному набору предопределенных локальных переменных, Korn shell поддерживает переменные, перечисленные в табл. 6.8. Таблица 6.8. Предопределенные локальные переменные Korn shell Имя Описание $_ Последний параметр предыдущей команды $PPID ID процесса родительского shell $PWD Текущий рабочий каталог shell $OLDPWD Предыдущий рабочий каталог shell $RANDOM Случайное целое число $REPLY Устанавливается командой select $SECONDS Число секунд, прошедших с начала вызова shell $CDPATH Используется командой cd $COLUMNS Устанавливает ширину окна редактирования для встроенных редакторов $EDITOR Указывает тип встроенного редактора $ENV Содержит имя стартового файла Korn shell $FCEDIT Определяет редактор, который вызывается командой f с $HISTFILE Имя файла истории $HISTSIZE Количество строк истории для запоминания
Имя Таблица 6.8 (окончание) Описание $LINES Используется командой select для определения отображения вариантов выбора $MAILCHECK Указывает shell, сколько секунд ожидать перед проверкой почты. Значение по умолчанию 600 $MAILPATH Содержит список имен файлов, разделенных двоеточием. Shell проверяет эти файлы на изменение каждые $ MAILCHECK секунд $PS3 Приглашение, используемое командой select, по умолчанию #? $TMOUT Если переменная равна значению, большему, чем 0, и истекает больше, чем $тмоит секунд между командами, происходит завершение работы shell $VISUAL Содержит тип встроенного редактора Пример: $ echo hi there hi there ...вывести сообщение для демонстрации $ echo $_ ...вывести последний аргумент последней команды. there $ echo $PWD /home/glass ...вывести текущий рабочий каталог. $ echo $PPID 27709 ...вывести PID родительского shell. $ cd / ...переместиться в корневой каталог. $ echo $OLDPWD /home/glass ...вывести последний рабочий каталог. $ echo $PWD ...вывести текущий рабочий каталог. $ echo $RANDOM $ RANDOM . . . вывести два случайных числа. 32561 8323 $ echo $SECONDS 918 ...вывести секунды с начала работы shell. $ echo $TMOUT ...вывести значение тайм-аут 0 $ ...нет выбранного тайм-аута.
Одномерные массивы Korn shell поддерживает простые одномерные массивы. Синтаксис Для присвоения значения элементу массива используйте конструкцию: имяМассива[индекс]=значение Для доступа к значению элемента массива используйте конструкцию: ${имяМассива[индекс]} Для того чтобы сформировать массив, просто присвойте значение переменной, указывая в скобках список индексов между 0 и 511. Элементы массива создаются по мере необходимости. Если вы опускаете индекс, используется 0 в качестве значения по умолчанию. Вот пример, который использует скрипт для вывода квадратов чисел от 0 до 9: $ cat squares.ksh ...посмотреть скрипт. i=0 while ( ( i < 10 ) ) do (( squares[$i] = i * i )) ...присвоить отдельные элементы. (( i = i + 1 }) ...увеличить счетчик цикла. done echo 5 squared is ${squares[5]} ...вывести один элемент, echo list of all squares is ${squares[*]} ...вывести все. $ squares.ksh ...выполнить скрипт. 5 squared is 25 list of all squares is 0 1 4 9 16 25 36 49 64 81 $ typeset Команда typeset позволяет создавать и манипулировать переменными. В табл. 6.9 перечислены ее опции. Синтаксис typeset {-HLRZfilrtux [значение] [имя [=слово]]}* Команда typeset позволяет создавать и манипулировать переменными: форматировать, конвертировать их во внутреннее представление целых
чисел для более быстрого выполнения арифметических операций, присваивать им статус "только для чтения", переключаться между строчными и прописными буквами, экспортировать переменные. Каждая переменная имеет связанный с ней набор флагов, которые определяют ее свойства. Например, если переменной поставлен в соответствие флаг "заглавный", она будет всегда выводить свое содержимое прописными буквами, даже когда они строчные. Опции typeset используются путем установки и переустановки различных флагов, связанных с переменными. Предшествующий опции знак - активизирует заданный флаг. Для выключения флага и отмены действия опции поставьте перед ней + вместо -. % Таблица 6.9. Опции команды typeset Опция Описание L Включает флаг L и выключает флаг R. Выравнивает слово влево и удаляет ведущие пробелы. Если ширина слова меньше, чем ширина поля имени, то дополняет слово заключительными пробелами. Если ширина слова больше ширины, то усекает конец слова до размера поля. Если флаг Z установлен, ведущие нули также удаляются R Включает флаг R и выключает флаг L. Выравнивает слово вправо и удаляет завершающие пробелы. Если ширина слова меньше чем ширина поля имени, то дополняет слово ведущими пробелами. Если ширина слова больше, то усекает конец слова до размера поля z Выравнивает слово вправо и заполняет нулями, если первый непробельный символ — это цифра, и флаг L выключен Форматирование Во всех опциях форматирования ширина поля имени равна ширине значения, если оно установлено. В противном случае она установлена на ширину слова. Регистр С помощью опций изменения регистра значение может быть конвертировано в строчные и прописные буквы, как показано в табл. 6.10. Ниже приведен пример, который выравнивает влево все элементы в массиве, а затем отображает их прописными буквами: $ cat justify. ksh wordList[0] = ’j eff’ ...вывести скрипт. # установить три элемента.
wordList[1]=’John’ wordList[2]= ’ellen' typeset -uL7 wordList # форматировать все элементы массива. echo ${wordList [*]} # осторожно! shell удаляет пробелы без кавычек, echo "${wordList[*]}" # работает хорошо. $ justify.ksh ...выполнить скрипт. JEFF JOHN ELLEN JEFF JOHN ELLEN $ _ Таблица 6.10. Изменение регистра символов при помощи команды typeset Опция Описание 1 Включает флаг 1 и выключает флаг и. Конвертирует слово в регистр строчных букв и Включает флаг и и выключает флаг 1. Конвертирует слово в регистр прописных букв Тип Тип хранящегося значения может быть установлен с помощью опций, перечисленных в табл. 6.11. Изменим рассмотренный выше фрагмент кода, объявив массив квадратов, как массив целых чисел. Это ускорит его работу: $ cat squares.ksh ...посмотреть скрипт. typeset -i squares # объявить массив целых (для скорости). i=0 while (( i < 10 )) do (( squares[$i] = i * i )) (( i = i + 1 )) done echo 5 squared is ${squares[5]} echo list of all squares is ${squares[*]} $ squares.ksh ...выполнить скрипт. 5 squared is 25 list of all squares is 0 1 4 9 16 25 36 49 64 81 $
Таблица 6.11. Установка типа значениям при помощи команды typeset Опция Описание i Сохраняет имя, как целое число для ускорения арифметических вычислений. Задает основание вывода, равное значению, если оно установлено; иначе использует основание слова r Устанавливает атрибуты доступа к переменной равными "только для чтения" X Помечает переменную, как экспортируемую Разное В табл. 6.12 показаны две дополнительные опции команды typeset. Таблица 6.12. Дополнительные опции команды typeset Опция Описание f Единственные флаги, которые можно использовать с этой опцией, — t, устанавливающий трассировку функции, и х, выводящий все функции с установленным атрибутом х t Связывает имя с меткой слова Приведенный ниже пример демонстрирует трассировку функции factorial с применением опций -ft, после чего скрипт выполняется: $ cat func5.ksh ...посмотреть скрипт factorial () # функция одного параметра { if (( $1 <= 1 )) then return 1 else typeset tmp typeset result ( ( tmp = $1 - 1 )) factorial $tmp (( result =$?*$1)) return $result
# typeset -ft factorial ...выбрать трассировку функции, factorial 3 echo factorial 3 = $? $ func5.ksh ...выполнить скрипт. + let 3 <= 1 ...информация отладки. + typeset tmp + typeset result + let tmp =3-1 4- factorial 2 4- let 2 <= 1 4- typeset tmp 4- typeset result 4- let tmp =2-1 4- factorial 1 4- let 1 <= 1 4- return 1 4- let result =1*2 4- return 2 4- let result =2*3 4- return 6 factorial 3=6 $ typeset с не именованными переменными Если переменные не определены, выводятся имена всех переменных, имеющих указанный набор флагов. Если никакие флаги не указаны, то отображается список всех переменных и их параметров. Пример: $ typeset export NODEID export PATH ...вывести список всех переменных typeset. leftjust 7 t export integer MAILCHECK $ typeset -i ...вывести список целых переменных typeset. LINENO=1 MAILCHECK=60 $
Встроенные команды Korn shell использует усовершенствованные версии следующих встроенных команд: □ I cd; □ set; □ print (улучшенная версия команды echo из Bourne shell); □ read; □ test; О trap. cd Версия команды Korn shell cd содержит несколько новых возможностей. Синтаксис cd { имя } cd староеИмя новоеИмя Первая форма команды cd обрабатывается следующим образом: • если имя опущено, shell перемещается в домашний каталог, указанный в переменной $номе; • если имя равно -, shell перемещается в предыдущий рабочий каталог, который сохраняется в переменной $oldpwd; • если имя начинается с /, shell перемещается в каталог, полный путь которого — имя', • если имя начинается с других символов, командный интерпретатор производит поиск совпадений в каталогах, указанных в переменной $cdpath, после чего перемещает shell в соответствующий каталог. Значение $cdpath по умолчанию равно пустой строке, поэтому поиск производится только в текущем каталоге. Если используется вторая форма синтаксиса команды cd, shell заменяет первое найденное совпадение, указанное в параметре староеИмя, значением новоеИмя. Затем shell использует новое имя пути. Новое имя текущего каталога сохраняется в переменной pwd. Текущее значение $pwd может быть просмотрено с помощью встроенной команды pwd.
Ниже приведен пример cd в действии: $ CDPATH=.:/usr ...установить мой CDPATH. $ cd dirl $ pwd /home/glass/dirl ...переместиться в dirl, размещенный в $ cd include ...переместить ся в include, размещенный в /usr. $ pwd /usr/include ...вывести текущий рабочий каталог. $ cd - ...переместиться в мой предыдущий каталог. $ pwd /home/glass /dirl $ . ...вывести текущий рабочий каталог. * set Команда set позволяет устанавливать и снимать флаги, управляющие широким набором характеристик shell. В табл. 6.13 перечислены опции, доступные этой команде. Синтаксис set [ +-aefhkmnostuvx ] [ +-о опция] {аргумент} ★ Команда Korn shell set поддерживает все возможности аналогичной команды Bourne shell и несколько дополнительных усовершенствований. Опция, которой предшествует + вместо изменяет свое значение на противоположное. Таблица 6.13. Опции команды set Опция Описание а Все переменные автоматически получают флаг для экспорта f Запрещает замещение имени файла h Все невстроенные команды автоматически интерпретируются, как прослеженные псевдонимы ш Помещает все фоновые задания в уникальную процессную группу и выводит уведомление о завершении. Эта опция автоматически устанавливается для диалоговых shell п Принимает, но не выполняет команды. Опция не влияет на диалоговые shell
Таблица 6.13 (окончание) Опция Описание о Описание опции см. далее Р Присваивает $РАТН значение по умолчанию, заставляя последовательность запуска игнорировать файл $ номе/, profile, и читает /etc/suid_profile вместо файла $env. Этот флаг устанавливается автоматически, когда shell выполняется процессом в режиме "set user ID" или "set group ID". Для получения дополнительной информации о процессах "set user ID" см. главу 13 s Сортирует параметры Не изменяет никакие флаги. Если аргументов нет, все параметры возвращаются в исходное состояние Опция о Опция о команды set принимает аргумент, часто имеющий тот же самый эффект, что и один из флагов, используемых с set. Если аргумент не указан, выводятся текущие установки. В табл. 6.14 приведен список допустимых аргументов и их значения: Обратите внимание, что, установив опцию ignoreeof в .profile, можно защитить себя от случайного выхода из системы по нажатию комбинации клавиш <Ctrl>+<D>: set -о ignoreeof Таблица 6.14. Аргументы set -о Опция Описание allexport Эквивалентна флагу a errexit Эквивалентна флагу е bgnice Фоновые процессы выполняются с низшим приоритетом emacs Вызывает встроенный редактор emacs gmacs Вызывает встроенный редактор gmacs ignoreeof Не выходит по нажатию комбинации клавиш <Ctrl>+<D>. Вместо этого используется exit keyword Эквивалентна флагу к markdirs Добавляет окончание / к каталогам, сгенерированным путем замены имени файла monitor Эквивалентна флагу m
Таблица 6.14 (окончание) Опция Описание noclobber Предотвращает перенаправление усечения существующих файлов поехес Эквивалентна флагу п noglob Эквивалентна флагу f no log Не сохраняет определения функции в файле истории nounset Эквивалентна флагу и privileged То же самое, как -р verbose Эквивалентна флагу v trackall Эквивалентна флагу h vi Вызывает встроенный редактор vi viraw Символы обрабатываются во время печати в режиме vi xtrace Эквивалентна флагу х print Команда print — усовершенствованная версия встроенной команды Bourne shell echo, позволяющая посылать вывод в произвольный описатель файла. Синтаксис print -npsuR [п] {аргумент}* По умолчанию команда print выводит значения, указанные в качестве аргументов, на стандартный вывод, и сопровождает это переводом строки. Опция -п запрещает перевод строки, а опция -и позволяет определить описатель файла л из одной цифры для канала вывода. Опция -s добавляет вывод к файлу истории вместо направления его на стандартный выход. Опция -р посылает вывод в двунаправленный конвейерный канал shell. Опция -R интерпретирует все остающиеся слова как аргументы. Пример: 121 $ print -u2 hi there ...послать вывод в стандартный канал ошибок, hi there
122 $ print -s echo hi there 124 $ r 123 echo hi there hi there 125 $ print -R -s hi there -s hi there $ ...добавить в историю. ...вызвать снова команду с номером 123. ...рассматривает -s, как аргумент. read Команда Korn shell read — это расширенная версия одноименной команды Bourne shell. Синтаксис read -prsu [п] [имя?приглашение] {имя}* Команда Korn shell read работает точно так же, как одноименная команда Bourne shell, и имеет следующие дополнительные возможности: • опция -р читает входную строку с двунаправленного конвейера shell; • опция -и использует описатель файла п для ввода; • если первый аргумент содержит ?, остаток аргумента используется, как приглашение. Пример: $ read. 'name?Enter your name ' Enter your name Graham $ echo $name Graham $ _ test Команда Korn shell test поддерживает несколько новых операторов, описанных в табл. 6.15. Кроме того, она предлагает удобный синтаксис, позволяющий сделать программу более читаемой.
Таблица 6.15. Операторы проверки, уникальные для команды test Korn shell Оператор Описание -L имяФайла Возвращает истину, если имяФайла — символическая связь файл! -nt файл2 Возвращает истину, если файл1 новее, чем файл2 файл1 -ot файл2 Возвращает истину, если файл1 старше, чем файл 2 файл! -ef файл2 Возвращает истину, если файл! такой же, как файл2 Синтаксис [ [ testBbipaxeHHe] ] эквивалентно test textBMpaxceHne Ниже приведен пример использования нового синтаксиса команды test: $ cat test.ksh ...посмотреть скрипт. i=i ' while [[ i -le 4 ]] do echo $i (( i = i + 1 )) done $ test.ksh ... выполнить скрипт. 1 2 3 4 $ trap Команда Korn shell trap— это доработанная версия аналогичной команды Bourne shell.
Синтаксис trap [команда] [сигнал] Команда Korn shell trap работает аналогично одноименной команде из Bourne shell, но имеет некоторые особенности: • если аргумент то все указанные сигналы повторно устанавливаются в их начальные значения; • если сигнал exit или 0 устанавливается trap внутри функции, тогда команда выполняется после выхода из нее. В следующем примере установлен перехват события exit внутри функции: $ cat trap.ksh ...вывести скрипт. f О { echo ’enter f () ’ trap ’echo leaving f...’ EXIT # установить локальную ловушку, echo ’exit f ()’ } # main program. trap ’echo exit shell’ EXIT # установить глобальную ловушку. f # вызов функции f(). $ trap.ksh ...выполнить скрипт, enter f () exit f () leaving f... ...локальный EXIT перехвачен. exit shell ...глобальный EXIT перехвачен. $ Пример проекта: junk Чтобы проиллюстрировать некоторые возможности Korn shell, рассмотрим проект junk, упомянутый в главе 5. Скрипт Korn shell использует функцию, чтобы обработать сообщения об ошибке, и массив с именами файлов. Остальные действия будут понятны читателю из комментариев. (Этот скрипт доступен в сети. Для дополнительной информации см. Введение.)
Синтаксис junk -1р {имяФайла}* Утилита junk — это аналог утилиты rm. Вместо удаления файлов она перемещает их в каталог junk домашнего каталога пользователя. Если .junk не существует, он автоматически создается. Опция -1 выводит текущее содержимое каталога .junk, а опция -р производит его очистку. junk #! /bin/ksh # junk script # Korn shell version # author: Graham Glass # 9/25/91 # # Initialize variables fileCount=0 listFlag=O purgeFlag=O fileFlag=O # количество специфицированных файлов. # 1, если используется опция list (-). # 1, если используется опция очистки -р. # 1, если специфицирован хотя бы один фа если используется опция list (-). если специфицирован хотя бы один файл. junk=~/.junk # имя каталога junk. # error () ’ { # # Вывести сообщение об ошибке и выйти # cat « ENDOFTEXT Dear $USER, the usage of junk is as follows: junk -p means "purge all files" junk -1 means "list junked files" junk clist of files, to junk them ENDOFTEXT exit 1
# # Разбор командной строки. # for arg in $* do case $arg in "-P") purgeFlag=l r r "-I") listFlag=l r r -*) t r echo $arg is an illegal option • • r r *) fileFlag=l fileList[$fileCount]=$arg # добавить в список, let fileCount=fileCount+l r r esac done # # Проверка: не слишком ли много опций. # let total=$listFlag+$purgeFlag+$fileFlag if (( total != 1 )) then error fi # # Если каталог junk не существует, создать его. # if [[ ! (-d $junk) ]] then ’mkdir’ $junk # взято в кавычки на случай, если есть псевдоним.
# # Обработка опций. # if (( listFlag = 1 )) then ’Is1 -IgF $junk # вывод каталога junk, exit 0 fi # if (( purgeFlag == 1 ) ) then ’rm’ $junk/* # удалить файлы из каталога junk, exit О fi # if (( fileFlag == 1 )) then ’mv’ ${fileList [*] } $junk # поместить файлы в каталог junk, exit О fi # exit 0 Вот пример вывода результатов работы junk: $ Is *.ksh ...вывести некоторые для junk. fact.ksh* func5.ksh* test.ksh* trap.ksh* f unc4.ksh* squares.ksh* track.ksh* $ junk func5.ksh func4.ksh ...выполнить junk для пары файлов. $ junk -1 ...вывести мой junk-каталог, total 2 -rwxr-xr-x 1 gglass apollocl 205 Feb 6 22:44 func4.ksh* -rwxr-xr-x 1 gglass apollocl 274 Feb 7 21:02 func5.ksh* $ junk -p ...очистить мой junk-каталог. $ junk -z ...испытать глупую опцию. —z is an illegal option Dear glass, the usage of junk is as follows: junk -p means "purge all files"
junk -1 means "list junked files" junk <list of files> to junk them $ _ Ограниченный shell Существует разновидность Korn shell, называемая ограниченным Korn shell, который поддерживает все возможности командного интерпретатора за исключением того, что пользователь не может: П менять каталог; □ осуществлять перенаправление вывода, используя > или »; □ устанавливать переменные окружения shell, env или path; □ использовать абсолютные пути. Эти ограничения накладываются только после выполнения файлов .profile и $env. Любые скрипты, выполненные ограниченным Korn shell, интерпретируются их ассоциированными shell и не ограничены никаким образом. Ограниченный Korn shell — это обычная С-программа, исполняемый файл которой хранится в /bin/rksh. Если выбранный shell — /bin/rksh, при регистрации в системе автоматически вызывается ограниченный диалоговый Korn shell . Его также можно запустить вручную, из скрипта или с терминала, с ПОМОЩЬЮ КОМанДЫ rksh. Системные администраторы, как правило, используют такой shell, чтобы предоставить пользователям ограниченный доступ к системе следующим образом: 1. Пишут серии обычных скриптов Korn shell, позволяющих пользователям получить доступ к возможностям, которые они (пользователи) желают применять. 2. После чего размещают эти скрипты в каталоге с атрибутом "только для чтения", обычно находящемся в /usr/local/rbin. 3. Далее присваивают переменной $ратн пользовательского .profile значение /usr/local/rbin и несколько других каталогов на выбор. 4. Изменяют вход пользователя в файле пароля (см. главу 15), устанавливая shell равным /bin/rksh. Опции командной строки Если первый аргумент командной строки -, Korn shell стартует, как входной shell. Korn shell поддерживает опции командной строки Bourne shell, флаги 11 Зак. 786
встроенной команды set (включая -х и -v) и опции, перечисленные в табл. 6.16. Таблица 6.16. Опции командной строки Korn shell Опция Описание -г Делает Korn shell ограниченным Korn shell имяФайла Выполняет команды shell в имяФайла, если опция -s не используется. имяФайла — это $0 внутри имяФайла-скрипта Обзор главы Перечень тем В этой главе мы рассмотрели: П создание стартового файла Korn shell; П псевдонимы и механизм истории; □ встроенные строчные редакторы vi и emacs; П арифметические операции; П функции; П усовершенствованное управление заданиями; П несколько дополнительных возможностей команд. Контрольные вопросы 1. Кем был написан Korn shell? 2. Почему полезен механизм псевдонимов? 3. Каким образом вы можете повторно отредактировать и выполнить предыдущую команду? 4. Поддерживает ли Korn shell рекурсивные функции? 5. Опишите современный синтаксис команды test. Упражнения 6.1. Перепишите скрипт junk, представленный в данной главе, так, чтобы он управлялся с помощью меню. Используйте команду select. [Уровень: легкий.]
6.2. Напишите функцию dateToDays, которая принимает три параметра: название месяца, например, Sep; день, например, 18; год, например, 1962 — и возвращает количество дней, прошедших с 1 января 1900 г. до указанной даты. [Уровень: средний.] 6.3. Напишите набор функций, которые эмулируют каталожные стековые возможности С shell (будут описаны в главе 7). Используйте переменные окружающей среды, чтобы определить стек и его размер. [Уровень: средний\ 6.4. Напишите скрипт pulse, который принимает два параметра: имя скрипта и целое число. Скрипт должен выполняться указанное число секунд, потом приостановиться на то же самое время, а затем продолжить выполнение, пока условие будет истинно. [Уровень: высокий.] Проекты 1. Напишите скелетный скрипт, который автоматизирует администрирование системы, используя интерфейс меню. Скрипт должен выполнять следующие задачи: • автоматическое удаление файлов ядра; • автоматические предупреждения пользователям, захватывающим много процессорного времени или дискового пространства; • автоматическая архивация. [Уровень: легкий.] 2. Напишите скрипт-менеджер псевдонимов, который позволяет выбрать эмуляцию DOS, эмуляцию VMS или ее отсутствие. [Уровень: средний.]

Глава 7 С shell Мотивация С shell был написан после Bourne shell и придерживается синтаксиса и структур управления языка С. Первый С shell стал фаворитом разработчиков UNIX, поскольку был призван поддерживать расширенное управление заданиями. Многие пользователи С shell переходят к Korn shell и Bash shell из-за их дополнительных возможностей и эффективности, но С shell все еще остается популярным. Предпосылки Вам необходимо прочитать главу 4 и поэкспериментировать с некоторыми из основных возможностей командного интерпретатора. Задачи В данной главе объясняются и демонстрируются специфические для С shell возможности. Изложение Информация представлена в форме нескольких примеров UNIX-сессий и небольшого проекта. Команды shell В главе рассматриваются следующие команды shell: alias nice chdir nohup dirs notify source stop suspend
foreach...end onintr switch...case...endsw glob popd unalias goto pushd unhash hashstat rehash unset history repeat unsetenv if...then...else...endif set while...end logout setenv Общие сведения о С shell С shell поддерживает все основные возможности shell, описанные в главе 4. а также новые: П несколько способов установки и доступа к переменным; П встроенный язык программирования, который поддерживает условные переходы, циклы и обработку прерываний; □ настройку команд с помощью псевдонимов; □ доступ к предыдущим командам через механизм истории; П расширенное управление заданиями; □ несколько новых встроенных и усовершенствованные существующие команды. Эти новые возможности проиллюстрированы в иерархической диаграмме на рис. 7.1. программирования заданиями команды alias unalias J°^s S,OP repeat while notify nohup set /setenv \ .cshrc unsetenv unset Рис. 7.1. Функциональность С shell
Запуск С shell — это обычная С-программа, исполняемый файл которой хранится как /bin/csh. Если ваш выбранный shell — это /bin/csh, диалоговый режим С shell активизируется автоматически при регистрации пользователя в UNIX. Вы можете также вызвать С shell вручную из скрипта или с терминала, используя команду csh, которая имеет несколько опций командной строки, описанных в конце главы. Когда С shell стартует, как входной shell, существующий глобальный файл инициализации входа в систему, который применим ко всем пользователям, может также’быть выполнен. Этот файл полезен для установки переменных окружения (типа path) так, чтобы они содержали информацию о локальном окружении. Имя файла изменяется от одной версии UNIX к другой, но похоже на /.login или /etc/login. При вызове С shell последовательность запуска различна для входа в систему с регистрацией и входе без регистрации shell, как показано в табл. 7.1. Обратите внимание, что файл .cshrc выполняется при входе в систему перед любым типом файла инициализации. Это может показаться нелогичным и, в конце концов, стало причиной непредвиденного поведения пользователей, когда обрабатывались их файлы инициализации. Следует помнить, что С shell всегда выполняет собственный файл инициализации немедленно при старте, а затем определяет, является ли shell входным shell, который требует выполнения других файлов инициализации. Таблица 7.1. Последовательность запуска С shell Шаг Тип shell Описание 1 Оба Выполняет команды из $HOME/.cshrc, если он существует 2 Только при входе Выполняет команды из глобального файла инициализации входа в систему, если он существует 3 Только при входе Выполняет команды из $номе/.login, если он существует Как только диалоговый shell стартует и завершает выполнять все соответствующие файлы инициализации, он выводит приглашение и ждет команды пользователя. Стандартным приглашением С shell является символ %, хотя он может быть изменен путем установки локальной переменной $prompt, которая описывается далее. Файл .login обычно содержит команды, которые устанавливают переменные окружения, например, term, содержащую тип вашего терминала, и path, сообщающую shell, где искать исполняемые файлы. Помещайте в пользовательский .login-файл определения, которые должны быть установлены толь
ко однажды (переменные окружения, чьи значения наследуются другими shell), или то, что имеет смысл лишь для диалоговой сессии (такие, как определенные установки терминала). Вот пример .login-файла: echo -n "Enter your terminal type (default is vtlOO):" set termtype = $< set term - vtlOO if ("$termtype" != "") set term = "$termtype" unset termtype set path=(. /bin /usr/bin /usr/local/bin ) stty erase "/ч?" kill ,,/4U" intr "ЛС" eof , ,,/чр" crt crterase set cdpath = (~) set history = 40 set notify set prompt = "! % " set savehist = 32 Файл .cshrc в основном содержит команды, которые устанавливают общие псевдонимы, или что-нибудь еще, что применимо только к текущему shell. Суффикс "гс" является аббревиатурой от англ, run commands — выполняемые команды. Вот пример файла .cshrc: alias emacs /usr/local/emacs alias h history alias 11 Is -1 alias print prf -pr pbl-2236-lp3 alias Is Is -F alias rm rm -i alicts m more Переменные C shell поддерживает локальные переменные и переменные окружения. Локальная переменная может содержать одно значение, тогда она называется простой переменной, или больше, чем одно значение, тогда она называется списком. Создание и присвоение значений простым переменным Чтобы присвоить значение простой переменной, используйте встроенную команду set.
Синтаксис set {имя [-значение]}* Если аргументы не представлены, команда set выводит список всех локальных переменных. Если значение не указано, параметру имя присваивается пустая строка. Если переменная имя не существует, она создается неявно. Вот некоторые примеры: % set flag ...присвоить переменной flag пустую строку. % echo $flag ...ничего не печатается, т. к. она пустая. % set color = rec? ...присвоить color строку red. % echo $color red % set name = Graham Glass ...осторожно! должны использоваться кавычки. % echo $пате ...только первая строка была присвоена. Graham % set name = "Graham Glass" ...теперь это работает, как ожидалось. % echo $пате Graham Glass % set ...вывести список всех локальных переменных, argv () cdpath /home/glass color red cwd /home/glass flag name Graham Glass term vtlOO user glass % Доступ к простой переменной В дополнение к простому синтаксису доступа к переменной ($имя), С shell поддерживает сложные методы доступа, показанные в табл. 7.2.
Представленные ниже примеры иллюстрируют эти методы доступа. В первом примере использовались фигурные скобки, чтобы добавить строку к значению переменной: % set verb = sing % echo I like $verbing verbing: Undefined variable. % echo I like ${verb}ing I like singing Таблица 7.2. Доступ к переменным С shell Синтаксис Описание ${имя} ${2 имя} Заменяется значением имя. Этот формат полезен, если за выражением немедленно следует алфавитно-цифровой символ, который иначе интерпретировался бы, как часть имени переменной Заменяется 1, если имя существует, и 0 в противном случае В следующем примере переменная использовалась как простой флаг в условном выражении: % cat flag.csh ...посмотреть скрипт. # set flag ...присвоить переменной flag пустую строку. if (${?flag}) then ...перейти, если flag установлен. echo flag is set endif % flag.csh ...выполнить скрипт. flag is set Q, Q Создание списочных переменных Чтобы присвоить переменной список значений, используйте встроенную команду set. Синтаксис set {имя = ({слово}* )}* Если указанная переменная не существует, она создается неявно. Переменной присваивается копия списка слов.
Пример: % set colors = ( red yellow green ) ...задать строку. % echo $colors ...вывести введенный список, red yellow green % Доступ к списочной переменной С shell поддерживает пару способов для доступа к списочной переменной. Оба эти метода имеют две формы, вторая окружена фигурными скобками (табл. 7.3). Вторая форма полезна, если за выражением немедленно следует алфавитно-цифровой символ, который иначе интерпретировался бы как часть имени переменной. Таблица 7.3. Доступ к списочным переменным С shell Синтаксис Описание $имя[селектор] Обе формы заменяются элементом имя, чей индекс опреде- ${имя[селектор]} лен значением селектора, который может быть числом, диапазоном чисел в формате “начало-конец" или звездочкой (*). Если начало опущено, предполагается 1. Если конец опущен, предполагается индекс последнего элемента. Если представлена *, то выбираются все элементы. Первый элемент списка имеет индекс 1 $#имя $ {#имя} Обе формы заменяются числом элементов в имени Вот некоторые примеры: % set colors = ( red yellow green ) % echo $colors[1] red % echo $colors[2-3] yellow green % echo $colors[4] Subscript out of range. % echo $#colors 3 % ...задать список. ...вывести первый элемент. ...вывести второй и третий элементы. ...недопустимый доступ. ...вывести размер списка.
Построение списков Чтобы добавить элемент в конец списка, присвойте первоначальному списку собственное значение, следом через пробел укажите новый элемент и окружите эту конструкцию круглыми скобками. Если вы пробуете присвоить новому несуществующему элементу значение, то получите сообщение об ошибке. Следующий пример иллюстрирует некоторые манипуляции со списком: % set colors = ( red yellow green ) % set colors[4] = pink Subscript out of range. % set colors = ( $colors blue ) % echo $colors red yellow green blue •* % set colors[4] = pink % echo $colors red yellow green pink % set colors = $colors black % echo $colors red $ set girls - ( sally georgia ) $ set boys = ( harry blair ) $ set both = ( $girls $boys ) $ echo $both sally georgia harry blair g. о ...задать список. ...попытка установить четвертый. * ...добавить к списку. ...это работает! .хорошо, т. к. четвертый существует. .ч - I , .не забудьте использовать (). .только первый был установлен. • 9' .построить один список. .построить другой. .объединить списки. .вывести результат. Предопределенные локальные переменные В дополнение к обычным предопределенным локальным переменным С shell определяет переменные, перечисленные в табл. 7.4. Вот маленький скрипт, который использует переменную $<, чтобы получить ответ пользователя: % cat var5.csh ...вывести скрипт. # echo -n "please enter your name: " set name = $< # получить входную строку, echo hi $name, your current directory is $cwd % var5.csh ...выполнить скрипт. please enter your name: Graham hi Graham, your current directory is /home/glass g о
Таблица 7.4. Предопределенные локальные переменные С shell Имя Описание $?0 Равно 1, если shell выполняет команды из указанного файла; 0 — иначе $< Следующая строка стандартного входа приводится полностью $argv Список, содержащий все позиционные параметры: $argv[l], эквивалентен $1 $cdpath Список альтернативных каталогов, которые использует chdi г для целей поиска $cwd Текущий рабочий каталог $echo Установлена, если опция командной строки -х активна $histchars Может применяться, чтобы переопределить метасимволы истории по умолчанию. Первый символ используется вместо ! для замен истории, а второй — вместо 74 для быстрого повторного выполнения команды $history Размер списка истории $home Домашний каталог shell $ignoreeof Защищает shell от завершения, когда тот получает сигнал от нажатия комбинации клавиш <Ctrl>+<D> $mail Список файлов для проверки почты. По умолчанию shell проверяет почту каждые 600 секунд (10 минут). Если первое слово $mail — это число, shell использует его значение вместо значения по умолчанию $noclobber Защищает существующие файлы от подмены по символу > и не- $noglob существующие файлы от добавления по символу » Предотвращает расширение групповых символов $nonomatch Предотвращает появление ошибки, если нет файлов, соответствующих имени файла при расширении группового символа $notify По умолчанию shell уведомляет пользователя об изменениях в статусе работы как раз перед выводом нового приглашения. Если переменная $ not if у установлена, изменения в статусе отображаются немедленно, когда они происходят $path Используется shell для определения местоположения выполняемых файлов $prompt Приглашение shell $savehist Количество команд, сохраняемых в файле истории $shell Полное путевое имя входного shell
Таблица 7.4 (окончание) Имя Описание $status Код возврата последней команды $time Если переменная установлена, любой процесс, который берет больше указанного количества секунд, приводит к выводу сообщения, указывающего статистику процесса $verbose Установлена, если используется опция командной строки -v Создание и присвоение переменных окружения Чтобы назначать значение переменной окружения, используйте встроенную команду setenv. Синтаксис setenv имя значение Если указанная переменная не существует, она неявно создается; в противном случае переписывается. Обратите внимание, что переменные окружения всегда хранят одно значение. Для них нет такого понятия, как список окружения. Пример: % setenv TERM vt52 ...установить тип моего терминала. % echo $TERM ...подтвердить. vt52 о о Предопределенные переменные окружения В дополнение к общим предопределенным переменным окружения, С shell поддерживает переменную, показанную в табл. 7.5. Таблица 7.5. Предопределенная переменная окружения С shell Имя Описание $LOGNAME ID владельца shell
Выражения С shell поддерживает строковые, арифметические и ориентированные на файл выражения. Строковые выражения С shell поддерживает строковые операторы, показанные в табл. 7.6. Если операнд — это список, то первый элемент списка служит для сравнения. Скрипт в следующем примере использовал технику соответствия строки, чтобы сделать вывод об ответе пользователя: % cat exprl.csh # echo -n "do you like the C shell?" set reply = $< if ($reply == "yes") then echo you entered yes else if ($reply =~ y*) then echo I assume you mean yes endif % exprl.csh do you like the C shell? yeah I assume you mean yes % ...посмотреть скрипт. # приглашение. # получить строку со входа. # проверить на точное совпадение. # проверить на неточное совпадение. ...выполнить скрипт. Таблица 7.6. Строковые операторы С shell Оператор Описание == Возвращает истину, если строковые операнды абсолютно равны ! = Возвращает истину, если строковые операнды не равны =~ Подобен ==, за исключением того, что правый операнд может содержать групповые символы ! ~ Подобен ! =, за исключением того, что правый операнд может содержать групповые символы Арифметические выражения I С shell поддерживает арифметические операторы, перечисленные в табл. 7.7 в порядке убывания приоритета. Они работают точно так же, как их стандартные С-копии за исключением того, что обрабатывают только целые
числа. Выражения могут быть окружены круглыми скобками для управления порядком вычислений. Таблица 7.7. Арифметические операторы С shell Операторы Описание । Унарный минус Логическое отрицание * / 9- > / > ° Умножение, деление, остаток + > “ Сложение, вычитание Побитовый сдвиг влево, побитовый сдвиг вправо < , > , о Операторы отношения == I = ! • Равенство, неравенство А> 1 Битовое И, битовое исключающее ИЛИ, битовое ИЛИ 1 1 , & & Логическое ИЛИ, логическое И Когда вычисляется арифметическое выражение, пустая строка эквивалентна 0. Любое выражение, содержащее операторы &, &&, |, I I, <, >, « или >>, должно быть заключено в круглые скобки, чтобы помешать shell интерпретировать эти символы специальным образом. Вот типичный скрипт, который использует пару операторов: % cat ехргЗ.csh ...вывести скрипт. # set а = 3 set Ь = 5 if ($а >2 && $Ь > 4) then echo expression evaluation seems to work endif % ехргЗ.csh ...выполнить скрипт. expression evaluation seems to work о о Вы не можете применять команду set, чтобы назначить результат выражения переменной. Вместо этого используйте встроенную команду @, которая имеет форматы, показанные ниже.
Синтаксис Формат Описание Выводит все переменные shell @ переменная ор выражение Присваивает переменной выражение @ переменная [ индекс] ор выражение Присваивает выражение переменной с индексом Здесь ор — это =, += *= или /=. Вот некоторые примеры: % set <а=2*2 ...вы не можете использовать set для присвоения. set: Syntax error. о, о ...использование @ вместо. о, о echo $а 0 а = 2 * 2 % @ а = $а + $а ...сложить две переменные. % echo $а 8 % set flag = 1 % @ b = ($а && $flag) ...нужны скобки, потому что &&. % echo $b 1 % @ b = ($а && $flag) % echo $b О Вы можете также увеличить или уменьшить значение переменной на 1, используя ++ или —, как в следующих командах: % set value = 1 % @ value ++ % echo $value 2
Выражения, ориентированные на файл Чтобы сделать решение задач с использованием файлов немного легче для программирования, С shell поддерживает несколько файловых выражений. Описание каждой опции показано в табл. 7.8. Синтаксис -опция имяФайла Возвращается 1 (истина), если выбранная опция истинна, и 0 (ложь) в противном случае. Если имяФайла не существует или недоступно, все опции возвращаются 0. Таблица 7.8. Опции, используемые в файловых выражениях Опция Описание г Shell имеет разрешение чтения для имяФайла w Shell имеет разрешение записи для имяФайла X Shell имеет разрешение выполнения для имяФайла е имяФайла существует о имяФайла принадлежит тому же самому пользователю, что и процесс shell z имяФайла существует и имеет размер 0 байт f имяФайла — это обычный файл (не каталог или специальный файл) d имяФайла — это файл каталога (не обычный каталог или специальный файл) Вот пример скрипта, который использует опцию -w, чтобы определить, является ли файл перезаписываемым: % cat ехрг4.csh ...вывести скрипт. # echo -n "enter the name of the file you wish to erase:" set filename = $< # получить строку ввода. if (! (-w "$filename")) then # проверить, имею ли доступ. echo you do not have permission to erase that file. else rm $ filename
echo file erased endif % expr4.csh ...выполнить скрипт. enter the name of the file you wish to erase: / you do not have permission to erase that file. % Автоматическое дописывание имени файла Подобно Korn shell, С shell предусматривает способ избежать ввода длинных имен файлов в командной строке. (Эта функциональная возможность была введена в течение эволюции С shell, поэтому старые версии не могут обеспечивать ее.) Чтобы включать функцию дописывания имени файла, вы должны установить переменную fiiec: % set fiiec Теперь всякий раз, когда вы напечатаете часть имени файла, можете нажать клавишу <Esc>, и если часть имени файла, которую вы напечатали только что, уникально идентифицирует файл, остальная часть имени будет добавлена автоматически. Если текст уникально не идентифицирует файл, ничего изменено не будет, и вы услышите звуковой сигнал. Вы можете также ввести *, чтобы увидеть список имен файлов, которые в настоящее время соответствуют части напечатанного имени. Пример: % Is -al . log* .login .logout % Is -al .login ...нажал клавишу <Esc> — ничего, тогда напечатал * ...shell повторно вывел, я добавил i и нажал клавишу ...<Esc>, а затем была добавлена буква "п". Псевдонимы С shell позволяет создавать и настраивать собственные пользовательские команды с помощью встроенной команды alias. Пример: % alias dir 'Is -aF' ...регистрация псевдонима. % dir ...так же как печатание Is -aF. . / main2.c р.reverse.с reverse.h ../ main2.o palindrome.c reverse.old % dir *.c ...так же как печатание Is -aF *.с.
main2.с р.reverse.с palindrome.с % alias dir ...посмотреть значение, ассоциированное с dir. Is -aF $ Синтаксис alias [слово [строка]] Команда alias поддерживает простую форму настройки командной строки. Если ваше слово псевдонима равно строке и позже вы вводите команду, начинающуюся со слова, первое его появление зал^еняется строкой, и затем команда обрабатывается повторно. Если вы не вводите слово или строку, то отображается список всех текущих псевдонимов shell. Если вводится только слово, то выводится строка, в настоящее время связанная со словом псевдонима. Если вы снабжаете слово и строку, shell добавляет указанный псевдоним к его собранию псевдонимов. Если для слова псевдоним уже существует, он заменяется. Если строка замены начинается со слова, оно не обрабатывается повторно для псевдонимов, чтобы предотвратить бесконечные циклы. Если строка замены содержит слово где-нибудь в другом месте, появляется сообщение об ошибке во время выполнения псевдонима. В следующем примере создается псевдоним слова в терминах его самого: % alias Is 'Is -aF' % Is *.c main2.c p.reverse.c % alias dir 'Is' % dir ./ main2.c p.reverse.c ../ main2.o palindrome.c % alias who 'date; who' % who ...определить Is в терминах его самого. ...так же как печатание Is -aF *.с. palindrome.с ...определить dir в терминах 1s. ...так же как печатание Is -aF. reverse.h reverse.old ...идентифицирует проблему цикла. Alias loop. % alias who 'date; /bin/who' ...полный путь предотвращает ошибку. % who ...теперь работает прекрасно. Fri Feb 13 23:33:37 CST 1998 glass ttypO Feb 13 23:30 (xyplex2)
Удаление псевдонима Чтобы удалить псевдоним, используйте встроенную команду unalias. Синтаксис unalias шаблон Команда unalias удаляет все псевдонимы, которые соответствуют шаблону. Если в качестве шаблона указан символ *, то удаляются все псевдонимы. Полезные псевдонимы В табл. 7.9 предоставлен список полезных псевдонимов вместе с кратким описанием каждого. Я храню эти псевдонимы в моем файле .cshrc.1 Таблица 7.9. Полезные псевдонимы С shell Псевдоним Команда Описание cd cd \!*; set prompt = "$cwd \!>"; Is V Приглашение пользователя изменяется так, чтобы оно содержало и текущий рабочий каталог, и самый последний номер команды (см. разд. “История" далее в этой главе) Is Is -F Предписывает утилите 1s включить дополнительную информацию о файле rm rm -i Предписывает утилите rm запрашивать подтверждение rm mv\!* -/tomb Заставляет утилиту rm перемещать файл в специальный каталог tomb вместо удаления файла h history Отображает список предварительно используемых команд, печатая только один символ vi (mesg n; /bin/vi \!*; mesg y) Защищает от получения сообщений от других пользователей, в то время как вы находитесь в редакторе vi mroe more Исправляет обычную ошибку орфографии при использовании утилиты more 1 Очень часто повествование в книге ведется от имени одного автора, по видимому, Грехама Гласса. — Ред.
Таблица 7.9 (окончание) Псевдоним Команда Описание ls-11 1s -1 * Исправляет обычную ошибку орфографии при использовании утилиты 1s 11 1s -1 Позволяет получать расширенный листинг каталога Разделение псевдонимов Чтобы делать псевдоним доступным дочернему shell, разместите его определение в shell-файле .cshrc. Параметризованные псевдонимы Псевдоним может ссылаться на аргументы в оригинальной команде, используя механизм истории, описанный в следующем разделе. К первоначальной команде обращаются, как будто это была предыдущая команда. Полезный псевдоним для cd, который я упомянул, демонстрирует удачное использование этой возможности: часть псевдонима \! * заменяется всеми аргументами первоначальной команды. Символ \ предшествует !, чтобы запретить его специальное значение во время назначения псевдонима: alias cd ’cd \!*; set prompt = "$cwd \l > ”; Is’ История C shell хранит запись команд, введенных с клавиатуры так, чтобы их можно было отредактировать и позднее повторно выполнить. Эта функция известна как механизм историй. Метасимвол ! дает доступ к истории. Пронумерованные команды При использовании истории удобно принять меры, чтобы приглашение содержало номер команды, которую пользователь собирается ввести. Для этого добавьте последовательность \! в значение переменной приглашения: % set prompt = '\! % 1 ...включить номер события в приглашение. 1 % echo Genesis . . . эта команда — событие с номером 1. Genesis 2 % ... следующая команда будет событием с номером 2.
Сохранение команд С shell делает запись последних $history команд во время конкретной сессии. Если значение переменной $history не установлено принудительно, по умолчанию используется 1. Если вы хотите, чтобы следующая сессия могла иметь доступ к этим командам, установите переменную $savehist. Тогда последние $savehist команды поддерживаются в файле, указанном переменной histfile (который обычно определен по умолчанию в $HOME/.history, но может изменяться с версиями UNIX). Файл истории разделяется всеми диалоговыми С shell, созданными одним пользователем, если переменной histfile преднамеренно не присвоено никакое уникальное значение в каждом из shell. В представленном ниже примере я проинструктировал мой shell помнить последние 40 команд в списке истории и сохранять последние 32 команды между сессиями: 2 % set history = 40 . . .помнить последние 40 команд. 40 3 % set savehist = 32 ...хранить 32 команды между сессиями. 32 4 % Чтение истории Чтобы получить листинг истории shell, используйте встроенную команду history. Синтаксис history [-rh] [номер] Команда history позволяет получать доступ к списку истории shell. Если никакие параметры не указаны, команда выводит последние $history команд. Опция -г обеспечивает вывод списка истории в обратном порядке, а опция -h запрещает показ номеров событий. Команде history обычно назначается псевдоним h для скорости ее ввода. Вот пример: 4 % alias h history ...создать полезный псевдоним. 5 % h ' ...вывести текущую историю. 1 set prompt = ’\! % ’
2 set history = 40 3 set savehist =32 4 alias h history 5 h 6 % h -r 3 ... вывести последние 3 команды в обратном порядке. 6 h 3 5 h 4 alias h history % Повторное выполнение команды Чтобы повторно выполнить предыдущую команду, используйте метасимвол ! в одном из форматов, указанных в табл. 7.10. Эти последовательности могут появляться где угодно в командной строке, хотя обычно используются самостоятельно. Таблица 7.10. Повторное выполнение команд в С shell Формат Описание । । Заменяется текстом самой последней команды ! номер Заменяется текстом команды с указанным номером !префикс Заменяется текстом самой последней команды, которая начиналась с префикса !?подстрока? Заменяется текстом самой последней команды, которая содержит подстроку Вновь вызванная команда выводится на терминал до своего выполнения. Значение префикса или подстроки не может содержать пробел. Специальное значение ! не запрещается никаким видом кавычек, но может быть заблокировано предшествующим ему пробелом, символом табуляции, =, ( или \. Вот некоторые примеры: 41 % echo event 41 event 41 42 % echo event 42 event 42 43 % !! . ’ echo event 42 event 4 2 44 % !41 ...простое echo. ...другое простое echo. ...повторно выполнить последнюю команду. . . .вывод команды перед повторным выполнением. ...повторно выполнить команду с номером 41.
echo event 41 event 41 45 % /ec echo event 41 event 41 46 % . . .вывод команды перед повторным выполнением. ...повторно выполнить команду, начинающуюся с ес. . . .вывод команды перед повторным выполнением. Доступ к частям команд истории Вы можете получить доступ к части предыдущей команды с помощью модификаторов истории, которые являются набором опций. Эти опции могут немедленно следовать за спецификатором события. Каждый модификатор возвращает отдельную лексему или ряд лексем от указанного события. Табл. 7.11 предоставляет список модификаторов. Двоеточие перед опциями $ и * является необязательным. Таблица 7.11. Модификаторы истории С shell Модификатор Возвращаемые лексемы :0 Первая : номер (номер + 1) :начало-конец (начало + 1) до (конец + 1) . Первая :$ Последняя . * Предпоследняя Для использования одного из модификаторов на самой последней команде вы можете указать перед ним модификатор !! или только !. Вот некоторые примеры: 48 % echo I'like horseback riding ...оригинальная строка. I like horseback riding 49 % !!:0 !!:1 !!:2 !!:4 ...доступ к указанным аргументам. echo I like riding I like riding 50 % echo !48:l-$ ...доступ к ряду аргументов. echo I like horseback riding I like horseback riding 51 %
Доступ к частям имен файлов Если модификатор истории ссылается на имя файла, оно может быть далее изменено для получения доступа к конкретной части имени. Существующие модификаторы могут сопровождаться модификаторами имени файла, показанными в табл. 7.12. Таблица 7.12. Модификаторы имен файлов С shell Модификатор Часть файла Часть указанного имени файла, которая возвращается :h Заголовок Путь к файлу : г Корень Полное имя файла без расширения файла : е Расширение Расширение файла : t Остаток Имя и расширение файла Следующий пример демонстрирует обращение к различным частям оригинального имени файла с помощью вышеупомянутых средств доступа к имени файла: 53 % Is /usr/include/stdio.h ...оригинал. /usr/include/stdio.h 54 % echo 153:l:h ...доступ к заголовку. echo /usr/include /usr/include 55 % echo !53:l:r echo /usr/include/stdio /usr/include/stdio ...доступ к корню. 56 % echo !53:l:e echo h h ...доступ к расширению. 57 % echo !53:l:t echo stdio.h ...доступ к остатку. stdio.h Q. О Замена истории Модификатор замены замещает указанную часть команды в предыдущем событии.
Синтаксис !событие:s/часть1/часть2/ Эта последовательность заменяется указанным событием после замены первого Появления части1 частью2. Пример: 58 % Is /usr/include/stdio.h /usr/include/stdio.h 58 % echo 158:1:s/stdio/signal/ echo /usr/include/signal.h /usr/include/signal.h 59 % ...оригинал. ...выполнить замену. Структуры управления С shell поддерживает широкий диапазон структур управления, которые делают язык похожим на инструмент программирования высокого уровня. Программы shell обычно сохраняются в скриптах и, как правило, используются для автоматизации задачи установки и сопровождения. Некоторые структуры управления требуют, чтобы вводились несколько строк. Если такая структура управления вводится с клавиатуры, shell выводит приглашение символом ? для ввода каждой дополнительной строки, пока структура управления не закончится в точке, в которой она выполняется. Далее приводится описание каждой структуры управления в алфавитном порядке. Демонстрационные примеры С shell похожи на примеры Bourne shell, чтобы вы могли сравнить и противопоставить два командных интерпретатора. foreach... end Команда foreach позволяет списку команд выполняться многократно, каждый раз используя различное значение для указанной переменной. Синтаксис foreach имяПеременной (списокСлов) списокКоманл end
Команда foreach выполняет итерацию значения имяПеременной через каждое значение В спискеСлов, ВЫПОЛНЯЯ списокКоманд ПОСЛе КаЖДОГО присвоения. Команда break заставляет цикл немедленно завершиться, а команда continue — перейти к следующей итерации. Вот пример скрипта, который содержит команду foreach: % cat foreach.csh ...вывести скрипт. # foreach color (red yellow green blue) # четыре цвета echo one color is $color end % foreach. csh one color is red one color is yellow one color is green one color is blue ...выполнить скрипт. о, о goto Команда goto осуществляет безусловный переход к указанной метке. Для того чтобы объявить метку, просто начините строку с ее имени, а за именем поставьте двоеточие. Синтаксис goto метка Метка в виде метка: должна существовать далее в скрипте. Появляется утверждение goto, управление передается строке, следующей за меткой. Обратите внимание, что метка может как предшествовать, так и следовать за утверждением goto, даже если команда вводится с клавиатуры. Используйте goto осторожно, избегайте кода "похожего на спагетти"2 (даже если вы любите спагетти). Вот пример простой конструкции с командой goto: % cat goto.csh ...вывести скрипт. # echo gotta jump 2 To есть длинного кода. — Ped.
goto endOfScript # переход echo I will never echo this endOfScript: # метка echo the end % goto.csh ...выполнить скрипт, gotta jump the end о Ъ if... then... else... endif Есть два формата команды if. Первый поддерживает простой односторонний переход. Синтаксис i f (условие) команда \ Эта форма команды if вычисляет условие и, если оно истинно (не НОЛЬ), ВЫПОЛНЯет команду. Вот пример этого формата if: % if (5 > 3) echo five is greater than 3 five is greater than three о "6 Второй формат команды if поддерживает альтернативный переход. Синтаксис if {условие!) then списокКоманд! else if {условие2) then списокКоманд2 else списокКомандЗ endif
Части команды else и else if не обязательны, но завершающий endif должен обязательно присутствовать. Если условие1 истинно, выполняются команды из спискаКоманд1 и команда if завершается. Если условие! ложно и есть одно или больше составляющих else if, то истинное выражение, следующее после else if, вызывает выполнение команд после связанного then, и команда if заканчивается. Если не найдено ни одного истинного выражения и есть составляющая else, выполняются команды После else. Пример второй формы if: % cat if.csh ...вывести скрипт. # echo -n ’enter a number: ’ set number = $< if ($number < 0) then # приглашение пользователю. # читать строку ввода. echo negative else if ($number == 0) then echo zero else echo positive endif % if. csh ...выполнить скрипт. enter a number: -1 negative g. о onintr Команда onintr позволяет определить метку, на которую должен быть осуществлен переход, когда shell получает сигнал sigint. Этот сигнал обычно производится нажатием комбинации клавиш <Ctrl>+<C> и описан более подробно в главе 13. Синтаксис onintr [- | метка] Команда onintr инструктирует shell перейти на метку, когда получен сигнал sigint. Если используется опция сигнал sigint игнорируется. Если опции не указаны, восстанавливается оригинальная shell-программа обработки SIGINT.
Пример: % cat onintr.csh ...вывести скрипт. onintr controlC # установить ловушку на <Ctrl>+<C>. while (1) echo infinite loop sleep 2 end controlC: echo control C detected % onintr.csh ...выполнить скрипт, infinite loop infinite loop ЛС ...нажал <Ctrl>+<C>. control C detected repeat Команда repeat позволяет выполнять отдельную команду указанное количество раз. Синтаксис repeat выражение команда Команда repeat вычисляет выражение И ВЫПОЛНЯет команду необходимое количество раз. Пример использования repeat: % repeat 2 echo hi there ...вывести две строки. hi there hi there switch... case... endsw Команда switch поддерживает многопозиционный переход, основанный на значении единственного выражения.
Синтаксис switch (выражение) case шаблон1: списокКоманд! breaksw case шаблон2: списокКомандЗ breaksw case шаблонЗ: списокКомандЗ breaksw default: списокКоманД—defa ul t endsw В выражении определяется строка., шаблон1, шаблон2, шаблонЗ могут включать Групповые СИМВОЛЫ, а списокКоманд 1, списокКоманд2, списокКомандЗ, списокКоманд_(1еfault — списки из одной или более команд shell. Командный интерретатор вычисляет выражение и сравнивает его с каждым шаблоном сверху вниз. Как только шаблон соответствия найден, выполняется его ассоциированный список команд, и затем shell переходит на строку endsw. Если никакого совпадения не найдено и условие по умолчанию присутствует, то выполняется списокКоманд-default. Если ника-кого совпадения не найдено, а условие по умолчанию отсутствует, то выполнение продолжается с команды после endsw. Ниже приведен пример скрипта menu.csh, который использует структуру управления switch: # echo menu test program set stop =0 # переустановить флаг завершения цикла while ($stop ==0) # пока не выполнится цикл cat « ENDOFMENU # вывести меню 1 : print the date 2r 3: print the current working directory 4 : exit ENDOFMENU echo
echo -n ’your choice? ' set reply = $< echo "" switch ($reply) case "1": date breaksw case ”2H: case ”3”: pwd breaksw case "4": set stop = 1 breaksw default: echo illegal choice breaksw endsw end # приглашение # читать ответ # процесс ответа # вывести дату # вывести рабочий каталог # установить флаг завершения цикла # по умолчанию # ошибка \ Вот вывод скрипта menu.csh: % menu.csh menu test program 1 : print the date 2f 3: print the current working directory 4 : exit your choice? 1 Sat Feb 14 00:50:26 CST 1998 1 : print the date. 2 , 3: print 'the current working directory 4 : exit your choice? 2 /home/glass 1 : print the date. 2 , 3: print the current working directory 4 : exit your choice? 5 illegal choice 12 Зак. 786
1 : print the date. 2 , 3: print the current working directory 4 : exit your choice? 4 while... end Встроенная команда while позволяет многократно выполнять список команд, пока указанное выражение истинно (не ноль). Синтаксис while (выражение) списокКоманл end Команда while вычисляет выражение и, если оно истинно, выполняет каждую команду в спискеКоманд, а затем повторяет процесс. Если выражение ложно, цикл while заканчивается и скрипт продолжает выполнять команды, следующие за end. Команда break немедленно завершает цикл, команда continue предписывает перейти к следующей итерации. Вот пример скрипта, который содержит структуру управления while, чтобы вывести маленькую таблицу умножения: % cat multi.csh ...вывести скрипт. # set x = 1 # установить значение внешнего цикла while ($x <= $1) # внешний цикл set у = 1 # установить значение внутреннего цикла while ($y <= $1) # внутренний цикл @ v = $x * $y # вычисление входа echo -n $v " " # вывести вход @ у ++ # обновить счетчик внутреннего цикла end echo "" # новая строка @ x ++ # обновить счетчик внешнего цикла end % multi. csh 7 ...выполнить скрипт.
т 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42 7 14 21 28 35 42 49 % _ Пример проекта: junk Для иллюстрации некоторых возможностей С shell, которые мы обсудили, ниже представлена версия скрипта С shell junk, который был предложен в конце главы 6. Синтаксис junk -1р {имяФайла}★ junk заменяет утилиту rm. Вместо удаления файлов она перемещает их в каталог .junk домашнего каталога пользователя. Если каталог .junk не существует, он автоматически создается. Опция -1 выводит текущее содержимое каталога .junk, а опция -р производит его очистку. Скрипт С shell, который представлен ниже, использует списочную переменную для хранения имен файлов. Остальная часть функциональных возможностей очевидна из представленных комментариев. (Скрипт shell доступен в сети. Для дополнительной информации см. Введение.) junk #! /bin/csh #junk script #author: Graham Glass #9/25/91 # #Initialize variables # set fileList = () # список всех специфицированных файлов. set listFlag =0 # установлена в 1, если Опция -1 указана.
set purgeFlag =0 # 1, если опция -р указана. set fileFlag =0 # 1, если хотя бы один файл специфицирован, set junk = ~/.junk # каталог .junk. # # Разбор командной строки. # foreach arg ($*) switch ($arg) case "-p": set purgeFlag = 1 breaksw case "-1": set listFlag = 1 breaksw case echo $arg is an illegal option goto error breaksw default: set fileFlag = 1 set fileList = ($fileList $arg) # добавить в список, breaksw endsw end # # Проверка: не слишком ли много опций. # 0 total = $listFlag + $purgeFlag + $fileFlag if ($total != 1) goto error # # Если каталог .junk не существу