ВВЕДЕНИЕ В UNIX



                       Дегтярев Е.К.













                    Москва     1991




                                  - 1 -


1. СОСТАВ СИСТЕМЫ
   Система UNIX   разработана   в   подразделении  Computing
Science Research Group фирмы Bell Labs в штате Нью-Джерси  в
США. Принципы ее построения были описаны первоначально в ря-
де статей журнала этой фирмы [1], а различные аспекты ее ис-
пользования - в ряде книг [2,3,4].

1.1. Главные части UNIX
   Ядро - управление основными ресурсами (процессор,  опера-
тивная память) и периферийными устройствами обмена и  хране-
ния данных (магнитные диски, магнитные ленты, принтеры, тер-
миналы, линии связи и т.д.).
   Файловая система (ФС) организует структуры данных на уст-
ройствах хранения.
   Shell -  командный интерпретатор:  слушает ваш терминал и
транслирует вашу команду в запрос к ядру и ФС.

1.2. Основные свойства UNIX
                             ------       ------
   Интерактивность:          ╨ вы ╨<=====>╨UNIX╨
                             ------       ------
   Мультизадачность: несколько задач, или процессов; в част-
ности,  возможны процессы "заднего плана" (back ground);  от
них не надо ждать ответа, чтобы продолжать что-нибудь делать
(на их фоне).
   Многопользовательская система - это следствие предыдущего
свойства:

                                  - 2 -
                                 ---------    \
                             --->╨процесс╨    ╨ 
                             ╨   ---------    ╨
                     ------  ╨   ---------    ╨
                     ╨ вы ╨--+-->╨процесс╨    ╨
          ------  -->------      ---------    ╨
          ╨UNIX╨==╨                           ╨-> процессы (задачи)
          ------  -->------      ---------    ╨
                     ╨ он ╨--+-->╨процесс╨    ╨
                     ------  ╨   ---------    ╨
                             ╨   ---------    ╨
                             --->╨процесс╨    ╨
                                 ---------    /

1.3. Языки программирования в UNIX
   - С, ПАСКАЛЬ, ФОРТРАН используются чаще всего;
   - СНОБОЛ, БЭЙСИК и многие другие также доступны во многих
реализациях UNIX;
   - интерактивные арифметические калькуляторы.
   Компиляторы языков  программирования  -  наиболее  машин-
но-зависимые части реализаций UNIX,  так как генерация кодов
на каждом компьютере своя.
1.4. Версии UNIX
   Основные версии:
   1) версии 6, 7, III, V Bell Labs AT&T (16 р, 32 р - ЭВМ);
   2) версия 4.2,  4.3 Калифорнийского университета (32 р  -
VAX, SUN).
   Система работает на десятках типов  ЭВМ:  серия  DEC  PDP
(СМ),  серия DEC VAX,  Honeywall 6070, семейство IBM/370 (ЕС
ЭВМ), Amdahl 470, Perkin Elmer, Zilog Z8000, рабочие станции
на  базе  Motorola  MC 68000,  серия HP 9000 ,  персональные
компьютеры на базе Intel 286,386,486 и других.



                                  - 3 -
2. ПЕРВЫЕ ШАГИ
2.1. Начало и конец сеанса работ
   Каждый пользователь имеет:
   - имя пользователя (для установления взаимодействия поль-
зователей и начисления расходов);
   - пароль пользователя (для контроля входа в систему и за-
щиты своих данных).
   Пользователи могут  быть  объединены в группы (для работы
над проектами и т.п.) для разделения общих  ресурсов,  тогда
еще есть имя группы пользователей.
   Один пользователь,называемый superuser является админист-
ратором системы (его имя - root).  В частности, он "заводит"
(регистрирует) всех прочих пользователей.
   Можно сменить свой пароль в любое время:
   login : peter
   password: . . . .
   $ passwd
   Changing password for peter
   Old password: . . .
   New password:   ***
   Retype new password:  ***
   $ ^D (Control-D)   (выход из сеанса)
   login:
   где  $ - подсказка системы
(может быть изменена на любой символ или строку).


2.2. Исправление ошибок при наборе текста команды
   Исправление последней буквы путем набора:
   - backspace
   - ^H
   - # (диез)

                                  - 4 -
   Исправление последней строки путем набора:
   - ^X
   - ^V
   - @

2.3. Некоторые простые команды
   Дата:
   $ date
   Sun Fed 14 11:38  1985
   $
   Узнать всех пользователей (активных):
   $ who
   mary tty0 Feb 14  08 : 30
   peter tty5 Feb 14 08 : 32
   . . .
   $
   Вариант:
   $ who am i
   mary tty 0 Feb 14 08 : 30

2.4. Формат команд
   Команды разделяются либо концом строки, либо точкой с
запятой:
   $ who; date
   mary tty0 Feb 14  08 : 30
   sun Feb 14 11 : 38 1985

                                  - 5 -
   Командная строка - последовательность  слов,  разделенных
пробелами.  Первое слово командной строки есть команда;  ос-
тальные - параметры.
   Типы параметров:
   - имя файла = идентификатор (использует символы a-z, A-Z,
0-9, _,.,-);
   - опция (ключ) уточняет смысл команды;  начинается обычно
с минуса.
   Например -al (может быть со  знаком  +  или  без  знака);
смысл опции зависит от команды;
   - выражение - описывает обычно строку символов или  явля-
ется строкой.
   Порядок параметров в команде:
   command options expression filename(s)
   Примеры команд:
   rm old.news bod.news
   rm -fr goodies.c baddies.o
   grep -o "mary" people
2.5. Приостановка - продолжение вывода на экран
   ^S - приостановка;
   ^Q - продолжение.
2.6. Останов выполнения команды
   ^C или клавиша BREAK (не работает по линиям связи).

3. СТРУКТУРА ИНФОРМАЦИИ О ФУНКЦИЯХ UNIX
   Руководство UNIX Reference Manual содержит 8 секций:
   1. Commands - команды;
   2. System calls - системные вызовы;

                                  - 6 -
   3. Subroutines - подпрограммы;
   4. Special files - спецфайлы;
   5. File format and convension - формат файлов и  соглаше-
ния;
   6. Games - игры;
   7. Macro  packages and language Conventions - макропакеты
и языковые соглашения (для обработки текстов);
   8. Administrator commands and procedures - команды и про-
цедуры администратора.

   Описание  команды состоит из следующих разделов:
   NAME              - имя и функция;
   SYNOPSIS          - синтаксис;
   DESCRIPTION       - описание функции;
   FILE              - используемые файлы;
   SEE ALSO          - смежные команды;
   DIAGNOSTIC        - ответы на ошибки;
   BUGS              - замеченные некорректности.

   Все руководство UNIX Peference Manual хранится в  системе
на  диске  и  может быть напечатано на экране или принтере в
любое время командой:
   $ man i <имя>
например:
   $ man grep
где i - номер секции; если i опущено, подразумевается i = 1.

                                  - 7 -

4. КАТАЛОГИ И ФАЙЛЫ
   При регистрации пользователя ему назначается  администра-
тором собственный каталог пользователя (Home directory).

4.1. Печать рабочего каталога
   Узнать его имя можно так:
   $ pwd                          (print working directory)
   /users/mary
   Выводится полное   имя   рабочего   (текущего)   каталога
/users/mary, где users - имя охватывающего каталога в иерар-
хии каталогов ФС.  Еще один охватывающий каталог root подра-
зумевается по умолчанию (корневой главный каталог):
   root/users/mary = /users/mary.
   Изменение текущего каталога можно  сделать  командой  cd,
рассматриваемой позже.

4.2. Печать содержимого каталога
   $ ls                - печать текущего каталога;
   $ ls -al            -a(all) - все файлы и подкаталоги;
                       -l(long) - полную информацию;
   $ ls /              - печать каталога root;
   $ ls -l /           - печать каталога root полная.


                                  - 8 -
4.3. Структура корневого каталога
   Как правило,  корневой каталог имеет следующую структуру,
но администратор системы может изменять эту структуру.
                          ---------
                          ╨   /   ╨
                          ---------
                              ╨
   ---------+--------+--------+--------+--------+---------
   ╨        ╨        ╨        ╨        ╨        ╨        ╨
   ╨        ╨        ╨        ╨        ╨        ╨        ╨
-------  -------  -------  -------  -------  -------  -------
╨ dev ╨  ╨ lib ╨  ╨ bin ╨  ╨ usr ╨  ╨ etc ╨  ╨ tmp ╨  ╨users╨
-------  -------  -------  -------  -------  -------  -------
 специ-  библио-   часто      ╨     команды   вре-   каталоги
 альные  теки      исполь-    ╨     админи-   менные пользова-
 файлы   (под-     зуемые     ╨     стратора  файлы   телей
         прогр.)   команды    ╨                         ╨
                     ---------+---------           -----+----
                     ╨        ╨        ╨           ╨
                  -------  -------  -------     -------
                  ╨ lib ╨  ╨games╨  ╨ bin ╨     ╨peter╨------
                  -------  -------  -------     -------
                  библио-    игры    редко
                  теки            используемые
                                    команды

   Каталоги можно посмотреть командой ls:
   $ ls -l /bin         - часто используемые команды;
   $ ls -l /bin/bin     - редко используемые команды;
   $ ls /dev            - драйверы устройств;
   $ ls /users          - каталоги пользователей.

                                  - 9 -

4.4. Изменение рабочего каталога
   Изменение рабочего каталога производится командой
(cd - change directory).

   $ cd /etc
   $ ls -l      - печать команд администратора
   $ cd /usr
   $ ls -l bin - редко используемые команды
   $ cd        - без параметров - возврат к собственному
                 (home) каталогу.

4.5. Соглашения по наименованию каталогов и файлов

   Малые и большие буквы считаются различными. Символы . и _
разрешены только внутри имени. Тип файла указывается оконча-
нием имени точкой с символом (основные):
   .c - программа на C (например, program.c);
   .h - текст на C, включаемый в программу на C (header);
   .f - программа на языке ФОРТРАН;
   .p - программа на языке ПАСКАЛЬ;
   .o - объектный код, полученный транслятором с любого языка;
   .a - библиотечный (архивный) файл.



                                  - 10 -
4.6. Печать содержимого файла
   Команда cat (от concatenate)  -  сцепить  несколько  (или
один)  файлов  и  направить  результат  на стандартный вывод
(Standart Output), обычно на экран дисплея.
   Пример:
   $ cat /etc/motd - посмотреть файл (message of today)
   The system will down at 17:00.
   Этот файл, создаваемый администратором для текущих объяв-
лений,  обычно печатается автоматически при входе в  систему
(login). Если Вы забыли его содержание, можно напечатать еще
раз как в примере.

4.7. Просмотр конца файла

   Команда tail печатает конец файла. По умолчанию - 10 пос-
ледних строк:

   $ tail /usr/pub/greek
   .
   .
   .
   .
   Явно можно задать количество  (со  знаком  -)  или  номер
строки, от которой печатать до конца (со знаком +):
   $ tail -3 /usr/greek  - три последние строки;
   $ tail +6 /usr/greek  - последние строки, начиная с 6-й.


                                  - 11 -
4.8. Определение типа файла

   Применяется команда file:
   $ file /bin/ls /usr/bin etc/passwd usr/include/stdio.h
   /bin/ls: pure executable             - исполняемый;
   /usr/bin: directory                  - каталог;
   /etc/passwd: ascii text              - текст в коде ASCII;
   /usr/include/stdio.h:C program text  - текст C-программы.

4.9. Создание каталога пользователем

   Ваш рабочий каталог,  являющийся корнем вашей  ветви  ФС,
создается администратором. Вы можете создать нижележащие ка-
талоги командой mkdir (make directory).
   Типичная структура   каталогов  пользователей  (с  учетом
групп):


                      ----------
                      ╨  users ╨
                      ----------
                           ╨
    ---------------------+-+-------------------------------
    ╨                    ╨
----------           ----------
╨ group 1╨           ╨ group 2╨   . . .   каталоги групп
----------           ----------
    ╨                     ╨
    ╨                     ------------------
    ╨                              . . .

    ╨                              - 12 -
    --+--------------------+-------------------------------
      ╨                    ╨
  ----------           ----------        корневые катало-
  ╨  mary  ╨           ╨  peter ╨        ги пользователей
  ----------           ----------        группы group1
      ╨
      -+------------------------+------------
       ╨                        ╨
  ----------                ----------  внутренние каталоги
  ╨  progs ╨                ╨  texts ╨  пользователе, соз-
  ----------                ----------  даваемые по mkdir
       ╨                        ╨
       ╨                        ----------
      -+----------+----------------      ╨
      ╨           ╨               ╨      ╨
   ---------- ----------      ---------- ╨
   ╨    c   ╨ ╨   p    ╨      ╨    f   ╨ ╨
   ---------- ----------      ---------- ╨              ╨- ф
       ╨          ╨               ╨      ╨  ----------  ╨- а
     --+--      --+--           --+--    ---╨letters ╨--+- й
     /////      /////           /////       ----------  ╨- л
     файлы      файлы           файлы                   ╨- ы

   Для создания такой структуры следует выполнить команды:
   $ cd                          - вернуться "домой" (home);
   $ mkdir progs texts           - создать каталоги в home;
   $ cd progs                    - перейти в каталог progs;
   $ mkdir c p f                 - создать каталоги в progs
и так далее.


                                  - 13 -
4.10. Копирование файлов командой cp

   Это простейший способ создать файл:
   $ cp /etc/motd message.
   Полагая, что текущий каталог  progs/c,  мы  создали  файл
progs/c/message.
   Можно копировать  файл  в текущий или другой каталог,  не
меняя его имени: cp /etc/motd progs/c.
   Будет создан файл progs/c/motd.
   Если текущий  каталог progs/c,  того же эффекта достигает
команда:
   $ cp /ets/motd . (с точкой в качестве параметра).
   Если второй аргумент каталог, то в качестве первого
можно указывать несколько файлов:
   $ cp /etc/motd /usr/include/stdio.h progs/c
   Режим доступа  файла  - копии совпадает с режимом доступа
исходного файла (см. раздел 4.16).

4.11. Перенос и переименование файлов командой mv

   Эта команда переносит файл или каталог  из  одного  места
файловой системы в другое.  Побочный эффект - переименование
(если исходный и конечный каталоги совпадают).
   Отличие от копирования: исходный файл пропадает.
   Пример: $ mv message mesg
           $ ls
           mesg ....

                                  - 14 -
   Если файл назначения защищен от записи,  то система печа-
тает режим доступа и спрашивает подтверждение переноса.
   Пример:
   $ cp message mesg
   $ chmod 444 message - только чтение
   $ mv mesg message
   message: mode 444? y
   Второй аргумент может быть каталогом,  тогда файл перено-
сится под тем же именем:
   $ mv message progs/c
   $ cd progs.c
   $ ls
   message ....
   Как и в случае  cp  может быть перенесено несколько
файлов, если "второй" аргумент - каталог.

4.12. Удаление файлов командой rm

   rm удаляет файл из каталога и уничтожает его:
   $ cd progs/c
   $ rm motd
   $ ls
   message (нет motd)

                                  - 15 -
   Можно удалить одной командой rm несколько файлов.  Есть интерак-
тивный вариант, требующий подтверждения на каждый файл (ключ
-i):
   $ rm -i file1 file2
   file1 : n (no - нет)
   file2 : y (yes - да)
   Можно форсировать уничтожение ключом -f (даже  если  файл
защищен по записи): -f и -i взаимно исключают друг друга.
   $ rm -f stdio.h.
   Однако этими  средствами нельзя уничтожить каталог,  пока
не уничтожены все файлы.  Это можно сделать рекурсивно: ключ
-r (уничтожить все поддиректории)
   $ rm -r progs.
   Вариант: $ rm -r *     - уничтожить все поддерево.

4.13. Уничтожение пустого каталога: rmdir
   Пустой каталог удаляется (remove directory):
   $ rmdir progs
   [rmdir:progs not empty]  -  сообщение,  если  каталог  не
пуст.

4.14. Использование метасимволов *, ?, []
   Метасимволы служат для подстановки любых строк  и  симво-
лов. В именах файлов в командах языка заданий Shell:
   * - представляет произвольную строку (возможно, пустую);
   ? - любой одиночный знак;
   [C1 - C2] - любая литера из диапазона C1 - C2 (в стандар-
те ASCII).

                                  - 16 -
   Примеры:
   1) $ ls c?
      c1 c2 c3 cs cz
   2) $ ls c*
      c1 c12 c2 c23 c3 cs cs1 cxy cz
   3) $ ls ?1*
      c1 c12
   4) $ ls *1*
      c1 c12 cs1
   5) $ ls c [12 x y z]
      c1 c2 cz
   6) ls c [12 x y z *]
      c1 c2 c12 c25 cz cxy

4.15. Непечатные символы в именах файлов
   Символы со знаком control:  ^A, ^[ (escape) и т.п., полу-
ченные одновременным нажатием клавиши Ctrl и указанной после
символа ^ клавиши,  не видны на печати. Команда ls может по-
казать файл, а rm и другие команды могут не принять имя это-
го файла (т.к. часть символов не видна). Выход - в использо-
вании * в именах (или использование режима rm -i):
   $ ls
   arron circle square triangle
   $ rm square
   rm: square non-existent (если вместо q в имени ^q)
   $ ls s*
   square

                                  - 17 -
   $ rm s*
   $
   Теперь файл удален.

4.16. Владелец файла и защита файла
   Каждый файл  и каталог имеют владельца - обычно это поль-
зователь,  создавший их в первый раз.  Владелец может  затем
назначить  защиту  файла со стороны трех классов пользовате-
лей:
   - владелец  (сам);
   - группа - пользователи этой же группы, где владелец;
   - остальные - все, имеющие доступ к системе.

   Каждый файл имеет 3 вида разрешения на доступ:
   - чтение  (r)  read  - можно читать (смотреть) содержимое
                             файла или  каталога  (читать  с
                             ключом -l в ls);

   - запись  (w)  write  - можно менять содержимое файла или
                             каталога (создавать или удалять
                             файлы в каталоге);

   - выполнять  (x)  execute - использовать файл как команду
                             UNIX и искать (search) в  ката-
                             логе.

                                  - 18 -
   Все комбинации трех видов  разрешения  доступа  для  трех
классов  пользователей (9 комбинаций) записываются в формате
(если все права есть)
     rwx               rwx                 rwx     или 777
      ╨                 ╨                   ╨
   Владелец             ╨                   ╨
                      Группа                ╨
                                          Остальные
   Отсутствие права доступа указывается минусом:
   r--r--r-      или 444
   Пример:
   $ ls -l /bin
   -r-xr-xr-x     1bin  1986  Nov.26    12:00 ar
   ...
   Эта команда показывает режимы доступа.

4.17. Установка и изменение режима доступа к файлу: chmod
   Формат команды chmod(change mode) для установки режима:
   chmod <режим> <файлы>
   Пример:
   $ chmod 644 f1 f2 f3
где 644 соответствует rw-r--r--
   Формат команды chmod для изменения режима:
   chmod <изменения> <файлы>
В изменениях используются обозначения:
   u - user             r - read
   g - group            w - write
   o - other            x - execute
   a - all

                                  - 19 -
   = - назначить
   + - добавить
   - - отнять
   Пример:
   $ ls -l
   -r-------- ... f1
   -r-------- ... f2
   -r-------- ... f3
      $ chmod  a = r, u + w    f1 f2 f3
      или (эквивалентный вариант изменения прав доступа)
      $ chmod  u = rw, go = r  f1 f2 f3
   $ ls -l
   -rw-r--r-- ... f1
   -rw-r--r-- ... f2
   -rw-r--r-- ... f3
   $ chmod o-r f1 f2 f3
   $ ls -l
   -rw-r----- ... f1
   -rw-r----- ... f2
   -rw-r----- ... f3,
   Другие пользователи, не входящие в группу, потеряли право
читать файлы.

5. КОМАНДЫ И СТАНДАРТНЫЕ ФАЙЛЫ
5.1. Стандартные файлы
   Многие команды работают по умолчанию со стандартными
файлами:

                                  - 20 -
   - Standard Input      (S.I.);
   - Standard Output     (S.O.);
   - Diagnostic Output   (D.O.);
   Однако есть средства изменения  умолчания,  т.е.  возмож-
ность указать другие файлы вместо стандартных. Можно
также в качестве D.O. использовать S.O. Эти средства называ-
ются перенаправление (редирекция) ввода и вывода.

5.2. Перенаправление стандартного вывода
   Используется знак >:
   $ ls -l                 - вывод на экран = standard output;
   $ ls -l > dirconts      - вывод в файл dirconts;
   $ cat dirconts          - вывод на экран.
   Пробелы вокруг символа > необязательны.
   Возможна перенаправление  вывода с добавлением (с дописы-
ванием в файл): обозначается >>:
   $ pwd >> dirconts (добавить в файл имя текущего каталога).

5.3. Перенаправление стандартного ввода
   Используется знак <.
   Пример:
   $ mail                   - ввод сообщения с экрана;
   $ mail < message         - ввод сообщения из файла message.
Эта возможность используется реже, чем перенаправление вывода.
   Тривиальный случай перенаправления ввода:

                                  - 21 -
   $ cat < this_file
   $ cat this_file
Это две эквивалентные команды.
   Можно одновременно перенаправить и ввод, и вывод.
   Например:
   $ cat < left > right.
   Будьте осторожны:  надо,  чтобы left не равнялось  right,
иначе можно (вообще говоря) потерять входной файл.
   Безопаснее >>, чем > (добавление, чем запись).

5.4. Создание файла командой cat
   Если не задан входной файл, то будет предполагаться стан-
дартный ввод (клавиатура). Одновременно перенаправим вывод в
новый (создаваемый) файл
   $cat > newfile.
   Здесь стандартный ввод буферизован: накопление 512 (обыч-
но) знаков и потом ввод.
   Небуферизованный (лучше, на случай сбоев) ввод:
   с ключом -u (unbuffered):
   $ cat -u > people
   Mary  101
   Sally 113
   Jana  121
   ^d    [для конца текста(EOF)]
   $

                                  - 22 -
   Можно добавлять:
   $ cat -u >> people
   Charlie 122
   Bill    100
   ^d
   $

5.5. Соединение команд каналами (pipeline)
   Стандартный вывод  одной  команды  может быть стандартным
вводом следующей команды.  Обозначается знаком | (вертикаль-
ная черта).
   Пример:
   $ who  | wc -l - создание списка активных пользователей и
подсчет их числа (count); 19 - ответ, то есть 19 пользовате-
лей.
   $
   Пример:
   $ ls -l /tmp | grep maryann | sort +3nr | lpr
листинг          поиск записей,    сортировка    печать
каталога         содержащих        (по 4-му по-  упорядо-
 /tmp            строку "maryann"  лю) найденных ченного
                                    записей       списка


                                  - 23 -
5.6. Фильтры
   Так называются  команды,  которые  могут вводить со стан-
дартного ввода и выводить на стандартный вывод.  Большинство
команд является фильтрами.
   Есть исключения: ls не может работать со стандартным вво-
дом. Или: lpr не может работать со стандартным выводом.

5.7. Параллельный стандартный вывод и перенаправление вывода
                                         -------------------
                                     --->╨cтандартный вывод╨
              ---------  ---------   ╨   -------------------
Схема такова: ╨ вывод ╨->╨команда╨-->╨
              ╨       ╨  ╨  tee  ╨   ╨          ------
              ---------  ---------   ---------->╨файл╨
                                                ------
   Пример:
         $ ls -l  |  tee dirconts
на экран, то есть     дублирование
стандартный вывод     вывода в файл

5.8. Диагностический вывод
   Сообщения об ошибках,  возникающих при выполнении команд,
выводятся на диагностический вывод,  по умолчанию это (как и
стандартный вывод) - на экран.
   Диагностический вывод тоже может быть перенаправлен в лю-
бой файл.  Для этого используется дескриптор файла  (целое),
который для стандартных файлов равен:

                                  - 24 -
   0 - Standard input;
   1 - Stfndard output;
   2 - Diagnostic output.
   Пример:
   $ cat somefile > outfile  2> errfile,
где знак > эквивалентен 1>.
   Если вы хотите,  чтобы сообщения об ошибках нигде не про-
являлись, направьте их на /dev/null.
   Если вы хотите направить ошибки туда же, куда вывод, надо
набрать
   Shell:  $ cat  somefile 1> outfile 2> &1 (ссылка на пере-
направление)
   Cshell: $ cat somefile >& outfile
или $ cat somefile |& lpr.

5.9. Обработка команд в режиме заднего плана (background)

   Обычно команды   выполняются  в  режиме  переднего  плана
(foreground),  т.е.  "пока вы ждете".  Однако, если во время
выполнения  некоторой команды вы хотите выполнять другие ко-
манды,  то эту (первую) команду  можно  выполнить  в  режиме
background:
   $ nroff  doc &
   2042
   $.
Об этом говорит завершающий знак &.

                                  - 25 -
   Система UNIX создает процесс, который выполняется незави-
симо от командного интерпретатора.  Ответ 2042 - это иденти-
фикатор этого процесса (PID).
   Лучше перенаправлять  стандартный  вывод процесса заднего
плана в файл (из-за опасности совмещения вывода  "переднего"
и "заднего" плана на экране).
   $ nroff doc > doc.format &
   2042
   $
   или:
   $ nroff doc | lpr &
   2042
   $
   Чтобы выяснить состояние процесса заднего плана, надо ис-
пользовать команду ps (process status):
   $ ps
   PID    TTY    TIME   CMD
   2036    02    0:05   sh          (login - процесс терм.2)
   2042    02    0:02   nroff doc   (background)
   2043    02    0:01   ps          (cat pS)
   2050    08    0:03   sh          (login - процесс терм.8).
   Это показывает, что nroff еще не закончилась. Ключи l и a
в команде ps могут дать больше информации об  активных  про-
цессах:
    -l - информация о родителе, адрес, приоритет и т.д.
    -a - о всех процессах системы.

                                  - 26 -
5.10. Выполнение процессов с низким приоритетом
   1) $ nice nroff doc > doc.fmt &
   2099
   $
   Задается выполнение  процесса с меньшим приоритетом.  На-
чальное значение nice равно  20;  параметр  добавления
в команде nice по умолчанию
равен 10;  итого nice = 30.  Приоритет тем выше,  чем меньше
nice.
   Или:
   $ nice -5 nroff doc > doc.fmt &
   Здесь параметр добавления задан явно,  nice  будет  равен
25, то есть приоритет будет на 5 единиц выше, чем по умолча-
нию.
   2) nohup (no hang up) - нечувствительность к разъединению
телефонной линии, на которой "висит" standard output)
   $ nohup nroff doc &
   2176
   $ Sending output to nohup.out (замена standard output
при разрыве линии)
   3) совместное использование:
   $ nice nohup nroff doc > doc.fmt &

5.11. Останов процесса
   $ kill 2042            (убить процесс с PID = 2042)
или
   $ kill - 9 2042 (сигнал номер 9 безусловного останова; на
другие сигналы из интервала (1,15),  посылаемые системой за-
даче, можно блокировать, написав соответствующую реакцию).


                                  - 27 -
6. РЕДАКТОРЫ EX И VI
   Это комбинация  двух непересекающихся возможностей:  ex -
строчный редактор (расширение базового редактора ed);  vi  -
экранный  редактор (может выполнять также все команды редак-
тора ex).

6.1. Вызов vi
   а) $ vi myfile (одно или несколько имен файлов через про-
белы для последовательного вызова их на редактирование).
   Если такого файла нет,  то появится начало пустого файла;
курсор - в начале первой строки.
   б) $ vi + myfile
   На экране - конец файла;  курсор  -  в  начале  последней
строки.
   в) $ vi +10 myfile
   На экране  -  часть  файла и строка 10 - в центре экрана;
курсор - в начале этой строки.

6.2. Выход из vi
   а) Если вы хотите запомнить изменения:

    Esc : w q ! Enter
    (нажать на клавишу Esc,  ввести двоеточие - оно появится
в нижней части экрана, ввести символы w, q и восклицательный
знак, нажать на клавишу Enter).

                                  - 28 -
   б) Если нет:

    Esc : q ! Enter

6.3. Позиционирование курсора
   а) клавиши <-,,,->;
   б) H - home,  M - middle, L - last: начало, середина, ко-
нец экрана;
   в) w - вперед на начало следующего слова;  e -  на  конец
текущего слова; b - назад на начало слова.

6.4. Добавление, изменение и уничтожение текста
   Подвести курсор к нужной позиции и нажать  одну  из  ниже
указанных клавиш.
   Уничтожение
   x - уничтожить текущую букву (где курсор),  текст сдвига-
   ется на ее место.
   Изменение (замена):
   r -  замена текущей буквы;  rv - замена на v.
   s - замена одной или нескольких букв текстом; например,
3stest - замена трех букв строкой 'test'.
   Добавление:
   i -  вставить  произвольный  текст перед курсором.  Конец
ввода текста - клавиша Esc;
   a - добавить произвольный текст после курсора. Конец вво-
да текста - клавиша Esc.


                                  - 29 -
6.5. Операции над словами и строками
     Уничтожение слова (слов):
   - подвести курсор к началу слова и нажать:
   dw (delete word);
   2dw - 2 слова;
   ndw - n слов (n - число).
     Изменение слова:
   - подвести курсор к началу слова и печатать:
   cw  <  слово  >  Esc
   2cw <два слова>  Esc
   и т.д.
     Уничтожение части строки
   d$ - от текущего символа до конца строки (текущий  символ
исчезает - то же делает D);
   d^ - от начала строки до текущего символа (текущий символ
остается).
   Замена части строки (аналогична)
   c$ (или  C)  <текст  замены  (может  быть  из  нескольких
строк)> Esc - замена конца строки (от курсора);
   c^ <текст замены> Esc - замена начала строки (до курсора,
не включая его). ;


     Уничтожение целой строки
   dd   - уничтожение одной строки;
   10dd - уничтожение 10 строк.
     Замена целой строки
   cc  < текст >  Esc  - замена одной строки;
   5cc < текст >  Esc  - замена пяти строк.

                                  - 30 -
     Создание новой строки
   о - пустая строка после текущей строки;
   O - пустая строка перед текущей строкой.
     Ввод до и после текущей строки:
   ^i (или I) - до;
   $a (или A) - после.

6.6. Перестановка части текста (cut-paste)
   Часть текста сохраняется в буфере редактора, затем встав-
ляется в другое место или в  несколько  мест  (если  вставка
повторяется).  Буфера  могут быть именованными и один - ано-
нимный.  При выполнении команд ndd (где n - число) удаляемые
n строк попадают на некоторое время в неименованный буфер.
   Содержание буфера можно вставить:
   - после текущей строчки командой p (put);
   - перед текущей строчкой командой P (Put).
   Следует помнить,  что в анонимном буфере хранится послед-
ний уничтоженный текст,  предыдущие - безвозвратно теряются!
(команды с (change) - тоже уничтожают буфер).

6.7. Сохранение части текста для последующего
использования (yank)
   yw            - сохранить слово (курсор - в начале слова);
   yy   (или Y)  - сохранить одну строку ;
   5yy  (или 5Y) - сохранить 5 строк;
и т.п. (в анонимном буфере).

                                  - 31 -
   Именованные буфера имеют имена из одной буквы от a до  z;
доступ к буферу - по имени имеет вид "x, где x - имя буфера.
   Запись в буфер a
   "a3yy - сохранить 3 строки в буфере a (с начала буфера).
   Вставка текста из анонимного буфера (как обычно):
   - p - после текущей строки;
   - P - перед ней.
   Вставка текста из именованного буфера:
   - "ap - после текущей строки из буфера a;
   - "aP - перед ней из буфера a.
   Добавление в буфер:
   - "aAdd - добавить к a уничтоженную по dd текущую строку.

7. ПРОГРАММИРОВАНИЕ В ЯЗЫКЕ SHELL
7.1. Версии Shell
   Shell - интерпретатор команд,  подаваемых с терминала или
из командного файла. Это обычная программа (т.е. не входит в
ядро операционной системы UNIX). Ее можно заменить на другую
или иметь несколько.
   Две наиболее известные версии:
   - Shell (версии 7 UNIX) или Bourne Shell (от фамилии  ав-
тора S.R.Bourne из фирмы Bell Labs) [5];
   - C-Shell (версии Berkley UNIX).
   Они похожи,  но есть и отличия: C-Shell мощнее в диалого-
вом режиме, а обычный Shell имеет более элегантные управляю-
щие структуры.
   Shell - язык программирования, так как имеет:
   - переменные;

                                  - 32 -
   - управляющие структуры (типа if);
   - подпрограммы (в том числе командные файлы);
   - передачу параметров;
   - обработку прерываний.

7.2. Файл начала сеанса (login - файл)
   Независимо от версии Shell при входе в систему UNIX  ищет
файл  начала сеанса с предопределенным именем,  чтобы выпол-
нить его как командный файл;
   - для UNIX версии 7 это: .profile;
   - для C-Shell это: .login и/или .cshrc.
   В этот файл обычно помещают команды:
   - установки характеристик терминала;
   - оповещения типа who, date;
   - установки каталогов поиска команд (обычно: /bin, /usr/bin);
   - смена подсказки с $ на другой символ и т.д.

7.3. Процедура языка Shell
   Это командный файл. Два способа его вызова на выполнение:
   1. $ sh dothat (где dothat - некоторый командный файл);
   2. $ chmod  755  dothat  (сделать  его  выполнимым,  т.е.
      -rwxr-xr-x)
      $ dothat.
   Следует знать порядок поиска каталогов команд (по умолча-
нию):
   - текущий;
   - системный /bin;
   - системный /usr/bin.

                                  - 33 -
   Следовательно, если имя вашего командного файла дублирует
имя  команды в системных каталогах,  последняя станет недос-
тупной (если только не набирать ее полного имени).

7.4. Переменные Shell
   В языке  Shell  версии  7 определение переменной содержит
имя и значение: var = value.
   Доступ к переменной - по имени со знаком $ спереди:
   fruit = apple (определение);
   echo $fruit (доступ);
   apple (результат echo).

   Таким образом, переменная - это строка. Возможна конкате-
кация строк:
   $ fruit = apple
   $ fruit = pine$fruit
   $ echo $fruit
   pineapple
   $ fruite = apple
   $ wine = ${fruite}jack
   $ echo $wine
   applejack
   $
   Другие способы  установки  значения  переменной - ввод из
файла или вывод из команды (см. раздел 7.6), а также присва-
ивание  значений  переменной - параметру цикла for из списка
значений, заданного явно или по умолчанию (см. раздел 7.9).


                                  - 34 -
   Переменная может быть:
   1) Частью полного имени файла:  $d/filename, где $d - пе-
ременная (например, d = /usr/bin).
   2) Частью команды:
   $ S = "sort + 2n + 1 - 2" (наличие пробелов требует кавы-
чек "")
   $ $S tennis/lpr
   $ $S basketball/lpr
   $ $S pingpong/lpr
   $
   Однако внутри  значения для команды не могут быть символы
|, >,  <,  & (обозначающие канал,  перенаправления и фоновый
режим).

7.5. Предопределенные переменные Shell
   Некоторые из них можно только читать.  Наиболее употреби-
тельные:
   HOME - "домашний" каталог пользователя; служит аргументом
по умолчанию для cd;
   PATH - множество каталогов, в которых UNIX ищет команды;
   PS1  - первичная подсказка (строка) системы (для v.7 - $).
   Изменение PS1 (подсказки) обычно делается в login -  фай-
ле,  например:
    PS1 = ?
или PS1 = "? " (с пробелом, что удобнее).
   Изменение  PATH:
   $ echo $PATH         -  посмотреть;
   :/bin:/usr/bin       -  значение PATH;
   $ cd                 -  "домой";

                                  - 35 -

   $ mkdir bin                  -  новый  каталог;
   $ echo $HOME                 -  посмотреть;
   /users/maryann               -  текущий   каталог;
   $ PATH  = :$HOME/bin:$PATH   -  изменение PATH;
   $ echo $PATH                 -  посмотреть;
   :/users/maryann/bin:/bin:/usr/bin - новое значение PATH.

7.6. Установка переменной Shell выводом из команды
   Пример 1:
   $ now = `date` (где `` - обратные кавычки)
   $ echo $now
   Sun Feb 14  12:00:01 PST  1985
   $
   Пример 2: (получение значения переменной из файла):
   $ menu = `cat food`
   $ echo $menu
   apples cheddar chardonnay (символы возврата каретки за-
меняются на пробелы).

7.7. Переменные Shell - аргументы процедур
   Это особый тип переменных, именуемых цифрами.
   Пример: $ dothis grapes apples pears (процедура).
   Тогда позиционные параметры (аргументы) этой команды дос-
тупны по именам:
   $1 = `grapes`
   $2 = `apples`
   $3 = `pears`

                                  - 36 -
и т.д.  до $9.  Однако есть команда shift,  которая сдвигает
имена на остальные аргументы, если их больше 9 (окно шириной
9).
   Другой способ получить все аргументы (даже если их больше
9):
   $*, что эквивалентно $1$2 ...
   Количество аргументов  присваивается  другой  переменной:
$#(диез).  Наконец, имя процедуры - это $0; переменная $0 не
учитывается при подсчете $#.

7.8. Структурные операторы Shell
   Кроме процедур,  в языке Shell имеются структурные опера-
торы типа "if-else" и "while-do". Программирование на Shell,
кроме написания процедур, используется для:
   - отработки  алгоритма  перед кодированием его в языках С
или  ФОРТРАН-77  (нет  компиляции,  линкирования,  загрузки,
простота отладки);
   - обучения принципам программирования непрограммистов.

7.9. Оператор цикла for
   Пусть имеется командный файл makelist (процедура)
   $ cat makelist
   sort +1 -2 people | tr -d -9 | pr -h Distribution | lpr.
   Если вместо одного файла people имеется несколько, нап-
ример:
   adminpeople, hardpeople, softpeople,...,
то необходимо  повторить  выполнение  процедуры с различными
файлами. Это возможно с помощью for - оператора. Синтаксис:

                                  - 37 -
   for <переменная> in <список значений>
   do  <список команд>
   done
Ключевые слова  for, do, done  пишутся с начала строки.
   Пример (изменим процедуру makelist)
   for file in adminpeople, hardpeople, softpeople
   do
   Sort +1 -2 $file | tr ... | lpr
   done.
   Можно использовать метасимволы Shell в списке значений.
   Пример:
   for file in *people (для всех имен, кончающихся на people)
   do
   ...
   done.
   Если in опущено, то по умолчанию в качестве списка значе-
ний берется список аргументов процедуры, в которой содержит-
ся цикл,  а если цикл не в процедуре, то - список параметров
командной строки (то есть в качестве процедуры выступает ко-
манда).
   Пример: for file
           do
           ...
           done
   Для вызова makelist adminpeople hardpeople softpeople бу-
дет сделано то же самое.

7.10. Условный оператор if
   Используем имена переменных,  представляющие значения па-
раметров процедуры:

                                  - 38 -
   sort +1 -2 $1 | tr ... | lpr
   Пример неверного вызова:
   makelist (без параметров), где $1 неопределен.
   Исправить ошибку можно,  проверяя количество аргументов -
значение переменной $# посредством if - оператора.
   Пример: (измененной процедуры makelist):
   if test $# -eq 0
   then echo "You must give a filename"
   exit 1
   else sort +1 -2 $1 | tr ... | lpr
   fi
   Здесь test и exit - команды проверки (см.  раздел 7.11) и
выхода.
   Таким образом, синтаксис оператора if:
   if <если эта команда выполняется успешно, то>;
   then <выполнить все следующие команды до else или, если
его нет, до fi>;
   [else <иначе выполнить следующие команды до fi>]
Ключевые слова if, then, else и fi пишутся с начала строки.
   Успешное выполнение процедуры означает, что она возвраща-
ет значение true = 0 (zero) (неуспех - возвращаемое значение
не равно 0).
   Оператор exit 1 задает возвращаемое значение 1  для  неу-
дачного выполнения makelist и завершает процедуру.
   Возможны вложенные if.  Для else if есть сокращение elif,
которое одновременно сокращает fi.

7.11. Команда "test"
   Не является частью Shell,  но применяется  внутри  Shell-
процедур.

                                  - 39 -
   Имеется три типа проверок:
   - оценка числовых значений;
   - оценка типа файла;
   - оценка строк.
   Для каждого типа свои примитивы (операции op).
   Для чисел синтаксис такой:
   N op M, где N, M - числа или числовые переменные;
   op принимает значения: -eq, -ne, gt, -lt, -ge, -le (с
обычным смыслом, как, например, в ФОРТРАН).
   Для файла синтаксис такой:
  op filename,
где op принимает значения:
   -s (файл существует и не пуст);
   -f (файл, а не каталог);
   -d (файл-директория (каталог);
   -w (файл для записи);
   -r (файл для чтения).

                                  - 40 -
   Для строк синтаксис такой:
   S op R, где S, R - строки или строковые переменные
или op1 S
   op принимает значения:
   = (эквивалентность);
   != (не эквивалентность);
   op1 принимает значения:
   -z (строка нулевой длины);
   -n (не нулевая длина строки).
   Наконец, несколько проверок разных типов могут быть  объ-
единены логическими операциями
   -a (AND) и -o (OR).
   Примеры:
   $ if test -w $2 -a -r S1
   > then cat $1 >> $2
   > else echo "cannot append"
   > fi
   $
   В некоторых вариантах ОС UNIX вместо команды test исполь-
зуются квадратные скобки, т.е. if [...] вместо if test
... .

7.12. Оператор цикла while
   Синтаксис:
   while <команда>
   do
   <команды>
   done
   Если "команда" выполняется успешно,  то выполнить "коман-
ды", завершаемые ключевым словом done.

                                  - 41 -
   Пример:
   if test $# -eq 0
   then echo "Usage: $0 file ..." > &2
        exit
   fi
   while test $# -gt 0
   do if test -s $1
   then echo "no file $1" > &2
   else sort + 1 - 2 $1 | tr -d ... (процедуры)
   fi
   shift (* перенумеровать аргументы *)
   done
   Процедуры выполняются над всеми аргументами.

7.13. Оператор цикла until
   Инвертирует условие повторения по сравнению с while
   Синтаксис:
   until <команда>
   do
   <команды>
   done
   Пока "команда" не выполнится успешно,  выполнять команды,
завершаемые словом done.
   Пример:
   if test S# -eq 0
   then echo "Usage $0 file..." > &2
        exit
   fi
   until  test  S# -eq 0

                                  - 42 -
   do
          if test -s $1
          then echo "no file $1" > &2
          else sort +1 -2 $1 | tr -d ... (процедура)
          fi
          shift                  (сдвиг аргументов)
   done
   Исполняется аналогично предыдущему.

7.14. Оператор выбора case
   Синтаксис:
   case  in
   string1) <если string = string1, то выполнить все следую-
щие команды до ;; > ;;
   string2) <если string = string2, то выполнить все следую-
щие команды до ;; > ;;
   string3) ... и т.д. ...
   esac
   Пример:
   Пусть процедура имеет опцию -t, которая может быть подана
как первый параметр:
   .................
   together = no
   case  $1  in
   -t)  together = yes
        shift ;;
   -?)  echo  "$0: no option $1"
        exit ;;
        esac

                                  - 43 -
        if test $together = yes
        then sort ...
        fi
   где ?  - метасимвол (если -?, т.е. "другая" опция, отлич-
ная  от  -t,  то ошибка).  Можно употреблять все метасимволы
языка Shell, включая ?, *, [-].
   Легко добавить (в примере) другие опции,  просто расширяя
case.

7.15. Использование временных файлов в каталоге /tmp
   Это специальный каталог,  в котором все файлы доступны на
запись всем пользователям.
   Если некоторая процедура,  создающая временный файл,  ис-
пользуется несколькими пользователями, то необходимо обеспе-
чить уникальность имен создаваемых файлов. Стандартный прием
- имя временного файла $0$$,  где $0 - имя процедуры, а $$ -
стандартная переменная, равная уникальному идентификационно-
му номеру процесса, выполняющего текущую команду.
   Хотя администратор периодически удаляет временные файлы в
/tmp, хорошей практикой является их явное удаление после ис-
пользования.


                                  - 44 -
7.16. Комментарии в процедурах
   Они начинаются с двоеточия :,  которое считается нуль-ко-
мандой,  а текст комментария - ее аргументом. Чтобы Shell не
интерпретировал  метасимволы  ($,  * и т.д.),  рекомендуется
заключать текст комментария в одиночные кавычки.
   В некоторых  вариантах  ОС  UNIX примечание начинается со
знака #.

7.17. Пример процедуры
:'Эта процедура работает с файлами,  содержащими имена'
: 'и номера телефонов,'
:'сортирует их вместе или порознь  и печатает результат на'
:'экране или на принтере'
:'Ключи процедуры:'
:'-t (together) - слить и сортировать все файлы вместе'
:'-p (printer) - печатать файлы на принтере'
if test $# - eq 0
then  echo  "Usage: $ 0 file ... " > & 2
      exit
fi
together = no
print = no
while  test  $# -gt 0
do  case   $1  in
-t) together = yes
     shift ;;
-p) print = yes
     shift ;;

                                  - 45 -
-?) echo "$0: no option $1"
     exit ;;
*)   if test $together = yes
     then sort -u +1 -2 $1 | tr ... > /tmp/$0$$
          if $print = no
          then cat /tmp/$0$$
          else lpr -c /tmp/$0$$
          fi
          rm /tmp/$0$$
          exit
     else if test -s $1
          then echo "no file $1" > &2
          else sort +1 -2 $1 | tr...> /tmp/$0$$
            if $print = no
            then cat /tmp/$0$$
            else lpr -c /tmp/$0$$
            fi
          rm /tmp/$0$$
          fi
          shift
     fi;;
     esac
done.
   Процедура проверяет число параметров $#, и если оно равно
нулю, завершается. В противном случае она обрабатывает пара-
метры (оператор case).  В качестве параметра может выступать
либо ключ  (символ,  предваряемый  минусом),  либо имя файла
(строка, представленная метасимволом *).  Если ключ  отличен

                                  - 46 -
от допустимого  (метасимвол ?  отличен от t и p),  процедура
завершается. Иначе в зависимости от наличия ключей t и p вы-
полняются действия, заявленные в комментарии в начале проце-
дуры.

7.18. Обработка прерываний в процедурах
   Если при выполнении процедуры получен  сигнал  прерывания
(от клавиши BREAK или DEL,  например), то все созданные вре-
менные файлы останутся неудаленными (пока это не сделает ад-
министратор) ввиду немедленного прекращения процесса.
   Лучшим решением является обработка прерываний внутри про-
цедуры оператором trap:
   Синтаксис: trap 'command arguments' signals...
   Кавычки формируют первый аргумент из  нескольких  команд,
разделенных точкой с запятой. Они будут выполнены, если воз-
никнет прерывание, указанное аргументами signals (целые):
   2 - когда вы прерываете процесс;
   1 - если вы "зависли" (отключены от системы)
и др.
   Пример (развитие  предыдущего):
   case $1 in
   .....
   *) trap 'rm /tmp/*; exit' 2 1 (удаление временных файлов)
   if test -s $1
   ..............
   rm /tmp/*

                                  - 47 -
   Лучше было бы:
   trap 'rm /tmp/* > /dev/null; exit' 2 1
так как  прерывание  может  случиться  до  того,  как   файл
/tmp/$0$$  создан и аварийное сообщение об этом случае пере-
направляется на null-устройство.

7.19. Выполнение арифметических операций: expr
   Команда expr вычисляет значение  выражения,  поданного  в
качестве  аргумента  и посылает результат на стандартный вы-
вод.  Наиболее интересным  применением  является  выполнение
операций над переменными языка Shell.
   Пример суммирования 3 чисел:
   $ cat sum3
   expr $1 + $2 + $3
   $ chmod 755 sum3
   $ sum3  13  49  2
   64
   $
   Пример непосредственного использования команды:
   $ expr 13 + 49 + 2 + 64 + 1
   129
   $
   В expr  можно применять следующие арифметические операто-
ры:  +, -, *, /, % (остаток). Все операнды и операции должны
быть разделены пробелами.
   Заметим, что знак умножения следует заключать  в  кавычки
(одинарные  или двойные),  например:  '*',  так как символ *
имеет в Shell специальный смысл.

                                  - 48 -
   Более сложный пример expr в процедуре (фрагмент):
   num = 'wc -l < $1'
   tot = 100
   count = $num
   avint = 'expr $tot / $num'
   avdec = 'expr $tot % $num'
   while test $count -gt 0
   do ...
Здесь wc -l осуществляет подсчет числа строк в файле,  а да-
лее это число используется в выражениях.

7.20. Отладка процедур Shell
   Имеются три средства, позволяющие вести отладку процедур.
   1) Размещение в теле процедуры команд echo для выдачи со-
общений, являющихся трассой выполнения процедуры.
   2) Опция -v (verbose = многословный) в команде Shell при-
водит к печати команды на экране перед ее выполнением.
   3) Опция -x (execute) в команде Shell приводит  к  печати
команды на экране по мере ее выполнения с заменой всех пере-
менных их значениями; это наиболее мощное средство.

8. C-SHELL
   Язык и интерпретатор языка C-Shell появился в версии сис-
темы UNIX Калифорнийского университета в Беркли UNIX  BSD4.2
для  VAX-11.  Основные достоинства этой версии заключаются в
добавлении  в  UNIX  редакторов  ex  и  vi,   интерпретатора
C-Shell,  реализации  языков  ПАСКАЛЬ  и  ЛИСП,  базы данных
INGRES и других возможностей.


                                  - 49 -
8.1. Специальные символы в C-Shell
   Стандартным знаком  подсказки  является процент (%).  При
желании его можно заменить.
   Восклицательный знак  ( ! )  выполняет многие специальные
функции, в частности ( !! ) означает вызов предыдущей коман-
ды.
   Знак крышка  ( ^ )  используется для разделения строк при
коррекции части текста предыдущей команды.
   Знак тильда  ( ~ ) в качестве префикса имени пользователя
расширяет его до полного имени его рабочего каталога.
   Фигурные скобки  ({  })  группируют  список имен файлов в
группу имен файлов.

8.2. Стандартные файлы в C-Shell
   Когда вы входите в C-Shell, он ищет в вашем рабочем ката-
логе файлы .login и .cshrc.  Если такие файлы у вас есть, он
выполняет все команды,  расположенные в них. Файл .login ис-
пользуется только при входе в C-Shell с терминала;
.cshrc - при любом входе.

8.3. Механизм истории
   Встроенный механизм истории интерпретатора C-Shell хранит
заданное число последних введенных вами команд. Число храни-
мых   команд   равно  значению  предопределенной  переменной
history,  которую вы можете установить в файле .cshrc коман-
дой set:
   % set history = 15
(в отличие от Shell при установке переменной требуется слово
set).

                                  - 50 -
   Чтобы посмотреть  хранимые  команды,  надо распечатать на
экране буфер механизма истории командой history, например:
   % history
   1 ls -l
   2 mail
   3 history
   %
   Механизм истории обеспечивает возможность  вызвать  любую
из хранимых команд, печатая восклицательный знак и номер ко-
манды, например:
   % ! 1
   ls -l
   . . . .
   %

8.4. Коррекция предыдущей команды
   Имеются различные средства для повторного исполнения пре-
дыдущих команд, возможно, с изменением части повторяемой ко-
манды.
   Для коррекции  непосредственно  предыдущей  команды  есть
следующие средства редактирования.
   Пример:
   % cd /users/peter/shels
   /users/peter/shels: No such file or directory.

                                  - 51 -
   Допущена ошибка: shels вместо shells. Она исправляется
следующим образом:
   %^shels^shells^
   cd/users/peter/shells
   %
   Исправленная команда заносится в буфер истории:
   % history
   1 ls -l
   2 mail
   3 history
   4 cd /users/peter/shels
   5 cd /users/peter/shells
   6 history
   Чтобы редактировать произвольную предыдущую команду, мож-
но воспользоваться  командой  s  (substitution)  подстановки
(см. раздел 8.6).

8.5. Повторное исполнение предыдущих команд
   Исполнение предыдущих команд,  сохраненных в буфере исто-
рии,  без  повторного их набора можно осуществить различными
способами.
   Первый способ:  напечатать восклицательный знак и имя ко-
манды. Исполняется самая последняя команда из буфера истории
с этим именем. Например:
   % !cd
   cd /users/peter/shells.
   Необязательно печатать полное имя. Достаточно минимально-
го количества символов начала имени, необходимого для одноз-
начного его опознания в буфере истории, например:

                                  - 52 -
   % !c
   cd /users/peter/shells.
   Второй способ:  напечатать и номер команды в буфере исто-
рии без пробела между ними. Например:
   % !1
   ls -l
   <вывод команды ls -l>
   %
   Наконец, имеется возможность использования последнего
слова непосредственно предыдущей команды вводом двух зна-
ков !$, например:
   % mv /users/wowa/spasewar.c space.c
   % pr  !$ | lpr
     pr  space.c | lpr
   %

8.6. Изменение и повторное исполнение предыдущих команд
   Для исполнения частично измененных предыдущих команд  ис-
пользуется  средство  подстановки  :s  (substitution)  части
текста (похожее на аналогичное средство в редакторе ex).
   Пусть имеется следующий буфер истории:
   %  history
   1  ls -l
   2  mail
   3  cd /users/peter/shels
   4  cd /users/peter/shells

                                  - 53 -
   5  history
   6  cd /users/peter/shells
   7  ls -l
   8  mv /users/wowa/spacewar.c space.c
   9  pr  space.c | lpr
   10 history
   Используем средство подстановки для изменения и испол-
нения команды mv:
   % !8 : s /spacewar/empire/
   mv /users/wowa/empire.c space.c.

8.7. Ссылка на рабочий каталог пользователя
   Знак тильда  (~)  используется  в  C-Shell  для ссылки на
собственный рабочий  каталог  или  рабочий  каталог  другого
пользователя, указанного именем пользователя.
   Примеры:
   % cd progs
   % mv ~/test.c
   Последняя точка означает текущий каталог progs. Чтобы уз-
нать,  что же в действительности выполнено,  посмотрим буфер
истории:
   % !h
   . . . . . . .
   . . . . . . .
   11 mv /users/wowa/empire.c  space.c
   12 cd progs
   12 mv /users/peter/test.c .

                                  - 54 -
   Пусть имеется  пользователь  с именем nick.  Чтобы узнать
его рабочий  каталог,  можно  использовать  команду  echo  и
средство знака тильда:
   % echo ~nick
   /users/nick
   %

8.8. Использование групп имен файлов
   Кроме средств метасимволов для ссылки на множество файлов
в C-Shell применяется средство группирования имен файлов для
явного  указания множества файлов в виде спискф имен файлов,
заключенного в фигурные скобки.
   Пример:
   % cp /users/peter/animals/{cats, dogs, birds}
Или: % cp ~mary/animals/{cats, dogs, birds}.
   Эта команда копирует множество из трех файлов с именами:
   /users/peter/animals/cats
   /users/peter/animals/dogs
   /users/peter/animals/birds
   В одной команде можно  использовать  более  одной  группы
файлов, например:
   % echo ls{/bin, /usr/ucb}{pi, is}
   ls /bin/pi /bin/is /usr/ucb/pi /usr/ucb/is

8.9. Механизм переименования
   Этот механизм,  называемый alias, позволяет дать дополни-
тельные  (обычно  короткие) имена часто используемым (обычно

                                  - 55 -
длинным) командам.
   Пример:
   % alias cdm1 cd /users/sys/doce/mans/man/man1
   % alias cdm2 cd /users/sys/doce/mans/man/man2
   % alias cdm3 cd /users/sys/doce/mans/man/man3
   Чтобы изменить  текущий каталог,  например,  на ...man 2,
достаточно ввести соответствующую команду по ее дополнитель-
ному имени:
   % cdm2
   % pwd
   /users/sys/doce/mans/man/man2.
   Те же переименования можно выполнить короче с использова-
нием ссылки !$ на последнее слово команды:
   % alias cdm cd /users/sys/docs/mans/man/man \!$
   % cdm 3
   % pwd
   / users/sys/docs/mans/man3.
   Обратный слэш  перед  восклицательным  знаком   исключает
действие восклицательного знака как специального символа.
   Отмена переименования производится командой unalias, нап-
ример:
   % unalias  cdm.

8.10. Переменные в C-Shell
   Подобно языку Shell, C-Shell имеет встроенные переменные,
установка которых может влиять на поведение  интерпретатора.
Установка  значения  переменной  производится  командой set,
имеющей следующий синтаксис:


                                  - 56 -
   set <переменная> = <значение>
   Рассмотрим наиболее  употребительные  встроенные перемен-
ные.
   Переменная history  задает  количество предыдущих команд,
сохраняемых в буфере истории, например: set history = 30.
   Переменная path устанавливает каталоги для поиска команд.
Список каталогов, разделенных пробелами, заключается в скоб-
ки:
   set path = (/bin /usr/ucb $Home/bin .)
   Переменная prompt  задает строку подсказки перед выполне-
нием очередной команды.  При этом символы \ ! (обратный слэш
и  восклицательный  знак)  в строке подсказки задают текущий
номер команды, используемый в механизме истории.
   Пример:
   % set prompt =  "ed \ ! >"
   ed5> history
   . . . . . . . .
   5 history
   Переменная Shell указывает, какой интерпретатор вы хотите
в  качестве  начального.  Возможные  значения:  /bin/csh или
/bin/sh.
   Булевская переменная  noclobber  используется  для защиты
уже существующего файла от случайной потери путем перезаписи
в него при перенаправлении стандартного вывода. Для этого ее
надо установить в значение "истина":


                                  - 57 -
   % set noclobber
   % fgrep ounds /usr/dict/words > shells
   Shells: File exists -
(файл с  именем  shells  уже существует и его текущая версия
была бы потеряна).  Если вы тем не менее хотите перезаписать
этот  файл,  используйте  перенаправление  с восклицательным
знаком (>!):
   % fgrep ounds /usr/dict/words >! shells
   В этом  случае перезапись состоится.  Установка булевской
переменной в противоположное значение "ложь" выполняется ко-
мандой:
   unset noclobber.
   Переменные home  и  cwd,  устанавливаемые  автоматически,
равны полным именам собственного и текущего каталогов  соот-
ветственно.
   Переменная status автоматически возвращает нулевое значе-
ние,  если  текущая команда завершена без ошибок.  Ненулевое
значение указывает ошибочное завершение.
   Переменная argv содержит аргументы командной строки с ну-
мерацией аргументов следующим образом:  argv [0] -  команда,
argv [1] - первый аргумент и так далее (как в языке C).
   Доступ к переменным обеспечивается  ссылкой  на  имена  с
предшествующим знаком $, например, $cwd, $argv [0] и т.д.
   Посмотреть текущие значения встроенных  переменных  можно
командой set без параметров:

                                  - 58 -
   % set
   Пользователь может определить свои переменные типа строка
знаков. Например:
   % set wd = `pwd`
   % echo $wd
   /users/sys/docs.
   Здесь результат выполнения команды  pwd  (строка  полного
имени  рабочего  каталога  пользователя) присвоен переменной
wd, значение которой проверено командой echo.
   Кроме строковых  переменных можно определить числовые пе-
ременные,  принимающие значения типа целое, вещественное или
булевское.  Целое и вещественное значение начинающееся с ну-
ля,  считается восьмеричным,  иначе - десятичным.  Установка
значения  числовой переменной выполняется командой @ (аналог
set для строковых переменных).
   Пример:
   % @ sum = (1 + 4)
   % echo $sum
   5
   В общем случае синтаксис команды @ такой:
   @ <переменная>  ,
   где C-операция - один из операторов присваивания,  приня-
тых в языке C (=, +=, -=, *=, /=, %=), а C-выражение - выра-
жение в синтаксисе языка C.


                                  - 59 -
8.11. Метасимволы в C-Shell
   Метасимволами называются  символы,  имеющие   специальное
значение для интерпретатора.
   В C-Shell имеются следующие метасимволы:
   - синтаксические;
   - именования файлов;
   - кавычки;
   - ввода - вывода;
   - подстановки;
   - прочие.
   Многие из них сходны по функциям с аналогичными функциями
метасимволов обычного Shell.

   Синтаксические метасимволы:
   ; - разделяет команды, которые будут выполнены последова-
тельно;
   ╨ - разделяет команды, соединенные каналом, так что стан-
дартный вывод левой является стандартным вводом правой;
   ╨& - аналогично ╨, однако диагностический вывод тоже нап-
равляется на ввод следующей команды;
   ( ) - объединяют команды,  разделенные предыдущими знака-
ми,  в единое целое для использования  в  последовательности
или с каналом;
   & - предписывает выполнение команды на заднем  плане  па-
раллельно со следующей командой, например:
   cat  letter>/dev/lp &

                                  - 60 -
   ╨╨ - аналогичен знаку ╨, однако правая команда выполняет-
ся, только если левая завершилась аварийно;
   && - аналогичен знаку ╨, однако правая выполняется, толь-
ко если левая завершилась нормально.

   Метасимволы именования файлов:
   ? -  любой  символ в имени файла.  Например,  файлы fa.o,
fb.o, fc.o могут быть напечатаны одной командой:
   $ cat f?.o > total.o
   * - любая строка в имени файла.  Например,  удаление всех
файлов, имена которых начинаются с old:
   % rm old*
   [] -  любая одна буква из указанного в квадратных скобках
диапазона. Например:
   % ls  f.[a  -  z] - печать всех файлов типа f.x,  где x -
буква из диапазона a - z;
   {} - аналогичны квадратным скобкам [], однако вместо диа-
пазона указано множество букв. Например, печать файлов list,
last, lost:
   % ls l{iao}st;
   ~ - полное имя рабочего каталога пользователя (см.выше);
   / - разделяет имена каталогов и файла в полном имени
файла или каталога.

                                  - 61 -
   Метасимволы - кавычки:
   \ - отменяет мета-значение следующего за ним одного мета-
символа. Например:
   % ls \*
   * not found
   (в то время как %  ls * - печать всех файлов текущего ка-
талога)
   ' ' - отменяет мета-значения группы символов. Пример:
   % set string = 'ws - l $dir / $file'
   " " - аналогичны одиночным кавычкам,  однако  подстановка
значений переменных и команд выполняется. Пример:
   % echo "$dir is not a directory."

   Метасимволы ввода - вывода:
   < - перенаправление ввода;
   > - перенаправление вывода (если переменная noclobber ус-
тановлена, перезапись существующего файла вывода не происхо-
дит);
   >& - перенаправление диагностического вывода;
   >! - перенаправление вывода (с  обязательной  перезаписью
существующего файла вывода);
   >&! - аналогично >! для диагностического вывода;
   >> - аналогично >,  однако вывод добавляется в конец  су-
ществующего файла вывода; если файл не существует и перемен-
ная noclobber установлена, возникает ошибка;
   >>& -  аналогично  >&,  однако  вывод добавляется в конец
файла вывода;
   >>! - аналогично >>,  однако, если файл вывода не сущест-
вует, он создается (ошибки не возникает);

                                  - 62 -
   >>&! - комбинация >>& и >>!

   Метасимволы подстановки:
   $ - указывает подстановку значения переменной, например:
   % set M1 = /usr/man/man3
   % cd $M1
   ! - указывает подстановку команды из буфера истории;
   : - указывает подстановку строк в команде из буфера исто-
рии;
   ? - используется в специальных случаях подстановок команд
из буфера истории.

   Прочие метасимволы:
   # (диез) - указывает комментарий C-Shell;  начинает имена
временных файлов;  должен быть  первым  символом  командного
файла в C-Shell;
   % - указывает номер процесса, например:
   kill %1.

8.12. Некоторые команды C-Shell
   В добавление к командам языка Shell  в  C-Shell  появился
ряд полезных команд. Рассмотрим некоторые из них.
   Команда ls с ключом -F позволяет получить листинг катало-
га с указанием знаком * исполнимых файлов и знаком / катало-
гов.
   Пример:

                                  - 63 -
   % ls -F
   mail help lint1* tabset/
   Команда head,  симметричная команде tail,  позволяет пос-
мотреть на экране заданное количество первых строк файла (по
умолчанию 10 строк), например:
   % head -2 people
   Mary  Clark  101
   Sally Smith  113
   Листание файла  на  экране  позволяет осуществить команда
more, например:
   % more somefile
   <первая страница фала>
   - - More - - (3 %)
   %
   Процент в  скобках указывает уже просмотренную часть фай-
ла.  Для последовательного постраничного  просмотра  нажмите
клавишу пробела, для построчного - клавишу возврата каретки.
   Можно задать начало просмотра со строки с заданным  номе-
ром или заданным значением. Примеры:
   % more +194 somefile
   . . . . .
   % more +'more then' somefile
   В общем  случае  значение задается регулярным выражением,
как в ed или grep (см. раздел 10.5).
   Команда apropos позволяет найти разделы руководств, ка-
сающиеся заданного ключевого слова.

                                  - 64 -
   Пример:
   % apropos sort
   ddsort (3/21/80) - sort DDBS files
   look (1)         - find lines in a sorted list
   . . . . . . . . . . . . . . .
   tsort (1)        - topological sort
   % man look
   <руководство по look (1)>
   Просмотреть заголовки руководств можно командой whatis,
   например:
   % whatis mv ln cp
   cp (1)  - copy
   ln (1)  - make links
   mv (1)  - move or rename files
   Команда whereis  позволяет найти специальные файлы,  свя-
занные с указанной командой (опция -m находит файл руководс-
тва, опция -b - файл кода команды).
   Пример:
   % wheris -m rm
   rm: /usr/man/man1/rm.1
   % wheris -b rm
   rm: /bin/rm
   Команда strings позволяет просмотреть в любом (в том чис-
ле выполнимом) файле все строки (в коде ASCII).


                                  - 65 -
8.13. Оценка состояния файла
   Выражение, возвращающее значение,  зависящее от состояния
файла,  используется в условных операторах (см.ниже). Значе-
ние равно единице (1),  если выражение истинно,  и ноль (0),
если оно ложно или файл не существует.
   Синтаксис выражения:
   -op <имя файла>,
где op принимает значения:
   d - является ли файл каталогом?
   e - файл существует?
   f - является ли файл простым файлом?
   o - это мой собственный файл?
   r - имею ли я право чтения файла?
   w - имею ли я право записи файла?
   x - могу ли я выполнить файл?
   z - файл пуст (длина ноль байтов)?
   Пример:
   if (-d $dir) then
   echo "**** $dir is a directory"

8.14. Работы
   Любая последовательность команд, разделенных метасимвола-
ми ; или ╨, а также отдельная команда является работой. Каж-
дая работа выполняется отдельным процессом.
   Заканчивая такую последовательность команд или  отдельную
команду знаком &, можно задать выполнение работы  на  заднем

                                  - 66 -
плане, то есть параллельно с будущими работами.  В этом слу-
чае система сообщает вам номер работы в скобках и номер про-
цесса, например:
   % du > usage &
   [1] 503
   % ls -al
   <Содержание текущего каталога>
   %.
   По окончании работы система сообщает о  завершении  (нор-
мальном  или  аварийном),  указывая номер работы и процесса,
например:
   .....
   [1] 503 - Done  du > usage
   %.
   Чтобы посмотреть,  какие работы активны в данный  момент,
используйте команду jobs -l.
   Эта команда распечатает список работ с указанием их  сос-
тояния:
   Running (выполняется) или Stopped (остановлена).

8.15. Командные файлы (скрипты) в C-Shell
   Командный файл (скрипт) - это файл,  состоящий из команд,
выполняемых группой. Примеры скриптов - файлы .login,.cshrc,
.logout. Прежде  чем  писать  свой  скрипт,  проверьте  UNIX
Reference используемой Вами версии UNIX, нет ли там команды,
уже решающей вашу задачу.


                                  - 67 -
   Первый способ выполнения скрипта - ввести команду:
   % csh sname arg1 arg2 ...,
где sname - имя скрипта; arg1, arg2 ... - аргументы скрипта.
   Аргументы скрипта  автоматически помещаются во встроенные
переменные $argv[1], $argv[2] и так далее.
   Кроме того, аргументы доступны по ссылкам $n, где n - це-
лое,  равное позиции аргумента;  $0 означает sname. Различие
между $argv[n] и $n заключается в том, что первая ссылка да-
ет ошибку при выходе значения n  за  допустимые  пределы,  а
вторая - нет.
   Второй способ выполнения скрипта в C-Shell  -  обеспечить
его выполнимость (командой chmod) и позаботиться о том, что-
бы он начинался с символа #(диез); в противном случае скрипт
будет выполняться обычным Shell.
   Пример:
   % chmod a+x sname
   % sname arg1, arg2, ...
   При выполнеии  скрипта  производится подстановка значений
переменных,  ссылки на которые указывает знак $.  Переменная
должна обладать значением в момент ссылки на нее, иначе воз-
никает ошибка.
   Узнать, присвоено ли значение переменной, можно с помощью
выражения $?<имя> (1 - присвоено,  0 -  нет),  а  количество
компонентов значения дает выражение $#<имя>.
   На компоненты   значения   можно   ссылаться   выражением
$<имя>[n], где n - номер компоненты.   Компоненты   значения

                                  - 68 -
разделяются пробелами, а многокомпонентное значение заключа-
ется в скобки.
   Пример:
   % set sum1 = (a b c)
   % echo $?sum1
   1
   % echo $#sum1
   3
   % echo $sum1[2]
   b
   % unset sum1
   % echo $?sum1
   0.
   Другими полезными подстановками,  начинающимися знаком $,
являются:
   $* - эквивалентно $argv;
   $$ - номер процесса; поскольку он уникален в системе, его
удобно  использовать для генерации уникального имени времен-
ного файла;
   $< - заменяется строкой последующего ввода со стандартно-
го ввода (клавиатура терминала), что очень полезно при напи-
сании интерактивных скриптов.
   Пример:
   echo "yes or no?"
   set a = ($<)
   На экране  высветится  запрос  (yes or no?),  затем будет
прочитан ответ и присвоен переменной a.

                                  - 69 -

8.16. Выражение в скриптах
   Допускается использование  выражений  над  переменными по
правилам операций в языке C.  Например, операции '==' и '!='
сравнивают  строки,  операции  '&' и '╨' реализуют булевские
операции 'и' и 'или' и так далее.  Введены также специальные
операции '=~' и '!~', подобные операциям '==' и '!=', однако
в правой строке допускаются метасимволы C-Shell (*, ? и []).
   Кроме того, допустимы выражения для оценки состояния фай-
ла (см. раздел 8.13).
   Результат выполнения  предыдущей  команды (нормальное или
аварийное завершение) можно получить в виде  значения  пере-
менной
   $status (ноль - без ошибок, не ноль - авария).

8.17. Управляющие структуры скриптов
   Допустимые в C-Shell управляющие структуры взяты из языка
C. Напомним, что скрипт в C-Shell должен начинаться с симво-
ла #(диез). Этим же символом вводится комментарий, продолжа-
ющийся до конца строки.

8.17.1. Оператор foreach
   Оператор цикла foreach имеет синтаксис:
   foreach <индекс> (<список значений индекса через пробелы>)
   <команда 1>

                                  - 70 -
   <команда 2>
   ..........
   end.
   Все команды  выполняются  для каждого значения индекса из
списка значений.
   Внутри цикла можно использовать команду break для прекра-
щения выполнения цикла и команду continue для  преждевремен-
ного прекращения одной текущей итерации.
   При выходе из цикла индекс имеет значение последнего эле-
мента из списка значений.

8.17.2. Оператор if-then-endif
   Условный оператор имеет синтаксис:
   if (<выражение>) then
   <команда 1>
   <команда 2>
   ..........
   else
   <команда A>
   <команда Б>
   ..........
   endif
   Если альтернатива else пуста (команды А,  Б,  ... отсутс-
твуют),  else  можно  опустить.  Реализация C-Shell требует,
чтобы if и then были обязательно на одной строке.


                                  - 71 -
   Допустимы вложенные условные операторы, например:
   if (<выражение 1>) then
   <команда 1>
   ..........
   else if (выражение 2> then
   <команда А>
   ..........
   else
   <команда X>
   ..........
   endif
   endif

   Если в первой альтернативе только одна команда,  допуска-
ется следующий синтаксис:
   if (<выражение>) <команда 1>
   или: if (выражение>\
   <команда>
   где символ  \  должен предшествовать символу перевода ка-
ретки.
8.17.3. Оператор while
   Оператор цикла while имеет синтаксис:
   while (<выражение>)
   <команда 1>
   <команда 2>
   ..........
   end.
   Внутри цикла  допустимы  операторы   break   и   continue
(см.foreach).

                                  - 72 -

8.17.4. Оператор switch
   Оператор выбора имеет синтаксис:
   switch (<переменная>)
   case <значение 1>:
   <команды>
   ........
   breaksw
   case <значение 2>:
   <команды>
   ........
   breaksw
   ........
   case <значение n>:
   <команды>
   ........
   breaksw
   default:
   <команды>
   ........
   breaksw
   endsw
   В отличие от аналогичного оператора в языке C  здесь  ис-
пользуется  специальный  оператор breaksw для выхода из аль-
тернативы.

                                  - 73 -
   Выполнение осуществляется следующим образом: значение пе-
ременной сравнивается последовательно со  значениями  1,  2,
..., n, и выполняются команды первой из альтернатив, для ко-
торых значения совпали.  Если таких значений  не  оказалось,
выполняются команды из альтернативы по умолчанию (default).

8.17.5. Оператор goto
   Допускаются метки операторов и оператор goto.
   Например:
   loop:
   <команда 1>
   <команда 2>
   ..........
   goto loop
Ъ8.18. Ввод в командах скрипта
   Обеспечение ввода в командах скрипта в C-Shell из  потока
символов текста скрипта вместо стандартного ввода (использу-
емого по умолчанию),  потребовало введения специального син-
таксиса. Рассмотрим пример скрипта:
   #
   foreach i ($argv)
   ed -$i << 'STOP'
   1, $s/wine/water/g
   w
   q

                                  - 74 -
   'STOP'
   end
   Строка 'STOP',  появляющаяся в тексте скрипта дважды, яв-
ляется меткой,  ограничивающей текст ввода,  и означает, что
стандартный ввод для команды ed заменяется посредством меха-
низма перенаправления (знак <<) вводом текста из файла само-
го  скрипта.  Ограничитель 'STOP' заключен в кавычки,  чтобы
предотвратить подстановку переменных и команды внутри  него.
В примере  редактор ed выполняет глобальную подстановку всех
вхождений строки wine на строку water (см. раздел 12.4).

8.19. Обработка прерываний в скриптах
   Если ваш скрипт создает временные файлы,  вы можете захо-
теть уничтожить их, даже если прерывание скрипта не позволит
вам выполнить скрипт до конца (предполагается,  что в  конце
скрипта временные файлы всегда уничтожаются).
   Для этого вам нужно в начале  скрипта  выполнить  команду
onintr label,  где label - произвольная метка, начиная с ко-
торой в вашем скрипте стоят команды,  которые будут выполне-
ны,  если произойдет прерывание (так как в случае прерывания
C-Shell автоматически выполнит команду goto label, где label
- метка из команды onintr).

                                  - 75 -
   При этом вы можете предусмотреть среди выполняемых в слу-
чае  прерывания  команд в качестве последней команду exit 1,
чтобы обеспечить ненулевое значение переменной $status, сви-
детельствующей о неблагополучном завершении скрипта.

8.20. Пример скрипта
   Данный скрипт выполняет сохранение файлов C-программ, ко-
торые уже сохранялись ранее. Файлы сохраняются в подкаталоге
backup вашего рабочего каталога.
   #
   foreach i ($argv)
   if ($i \ !~  ~/*.c)
   then # является ли файл $i файлом С-программы ?
   echo файл $i не является файлом С-программы
   continue
   else
   echo файл $i является файлом С-программы
   endif
   echo check file ~/backup/$i
   if (-e ~/backup/$i)
   then # находится ли файл $i в подкаталоге  backup?
   echo  файл $i не находится в подкаталоге  backup
   continue
   endif
   echo compare two files $i and ~/backup/$i
   cmp -s $i ~/backup/$i



                                  - 76 -
   if ($status != 0) then
   echo новая копия файла $i
   cp $i ~/backup/$i
   endif
   end.
   Собственно копирование делается командой cp,  а  все  ос-
тальные строчки  скрипта организуют цикл и осуществляют про-
веркия.

9. СВЯЗЬ ПОЛЬЗОВАТЕЛЬ-ПОЛЬЗОВАТЕЛЬ
   Система UNIX предполагает возможность коллективной работы
и кооперации пользователей.  Это  требует  развитых  средств
связи пользователей между собой. В системе имеются следующие
средства:
   - команда  write  для  непосредственной посылки сообщения
другому пользователю;
   - средство mail, реализующее электронную почту.
9.1. Посылка сообщений командой write
   Команда write  посылает сообщение указанному пользователю
в момент исполнения этой команды.  Это означает, что адресат
должен работать в системе в этот момент. Не многим нравится,
когда сообщение приходит,  как в данном случае,  в случайный
момент,  в  особенности во время набора собственного текста.
Поэтому вы должны быть уверены в необходимости такого немед-
ленного взаимодействия.
   Типичный пример:
   $ write boris
   Спасайся, красные окружили Белый Дом!!!
   ^D
   $

                                  - 77 -
   Сообщение заканчивается    вводом   знака   конца   файла
control-D.
   Адресат увидит у себя на экране:
   Message from george tty 00 ...
   Спасайся, красные окружили Белый Дом!!!
   EOF
   Если вы  намерены  ждать ответа и вести диалог,  можно не
вводить знак конца файла до конца диалога.
   Пример:
   $ write mary
   Поужинаем сегодня вечером?
   Извини, сегодня я иду громить памятники.          (ответ)
   Тогда завтра?
   И завтра не могу. Давай на следующей неделе?      (ответ)
   Ну, хорошо.
   EOF                                               (ответ)
   ^D
   $
   Получаемые от абонента тексты помечены словом  (ответ).
   На стороне абонента на экране будет:
   $ Massage from peter tty 03 ...
   Поужинаем сегодня вечером?
   Извини, сегодня я иду громить памятники.
   Тогда завтра?
   И завтра не могу. Давай на следующей неделе?      (ответ)
   Ну, хорошо.
   ^D
   $

                                  - 78 -

   Чтобы узнать,  работает ли абонент в системе в данный мо-
мент, введите команду who.
   Пример:
   $ who
   george tty  00  08:30
   peter  tty  03  08:31
   boris  tty  07  04:12
   mary   tty  08  09:01
   Текст сообщения можно взять из файла, перенаправляя стан-
дартный ввод для write из этого файла.
   Пример (сообщение из файла message):
   write peter < message
   Текст сообщения можно формировать, выполняя команды внут-
ри текста.  В этом случае команде предшествует восклицатель-
ный знак, например:
   $ write peter
   Нужные тебе файлы в каталоге:
   !pwd
   /users/mary/docs/specs
   !
   /users/mary/docs/specs
   ^D
   $

                                  - 79 -
   Ответ команды завершается тоже восклицательным знаком. Ни
команда, ни ответ в текст сообщения не попадают.
   Если вы не уверены,  что полученные сообщения не  нарушат
вашу  работу  (например,  ввод текстового файла),  вы можете
закрыться от посылаемых вам сообщений командой mesg:
   $ mesg n
   $
где n - от no (нет).
   Когда вы решите, что уже способны получать сообщения, по-
дайте:
   $ mesg y
где y - от yes (да).
   Эта же команда без параметров подскажет вам, в каком сос-
тоянии по приему сообщений вы находились (no или yes),  нап-
ример:
   $ mesg
   is y
   т.е. прием разрешен.  При входе в систему устанавливается
состояние y.

9.2. Электронная почта (mail)
   Электронная почта - это средство, позволяющее пользовате-
лям посылать друг другу сообщения,  которые  складываются  в
почтовые ящики, реализованные внутри системы.
   Когда вы входите в систему,  вас извещают о  наличии  для
вас почты, например:

                                  - 80 -
   login: mary
   password: ...
   you have mail
   $
   В отличие от write в системе mail о приходе для вас почты
вас известят, когда вы закончите текущую работу, печатая со-
общение:
   you have mail          (для вас есть почта).
   Для получения почты введите команду mail без параметров:
   $ mail
   Form peter Wed Jun 9 17:58:23   1991
   Завтра в 16:30 можно поиграть в теннис.
   Где встретимся?
   ?
   Подсказка (?) означает,  что система mail ждет указания о
том,  что делать с почтой:  печатать,  сохранить, уничтожить
или выйти из команды mail.
   Введя знак вопроса, вы получите меню возможных действий:
   ??
   q quit                       - закончить;
   x exit without changing mail - выйти без изменения почты;
   p print                      - печатать;
   s [file] save                - сохранить в файле;
   w [file] same without header - то же без заголовка;
   - print previous             - печатать предыдущее;
   d delete                     - уничтожить;

                                  - 81 -
   + next (no delete)           - следующее (не уничтожать);
   m user mail to user          - переправить другому
                                  пользователю;
   !cmd execute cmd             - выполнить команду;
   ?
   Кроме этих  десяти  действий  вы  можете   также   ввести
control-D  (то же,  что и q) или нажать клавишу возврата ка-
ретки.
   При сохранении почты в файле на экране высвечивается сле-
дующее письмо, если оно есть:
   ? s from_peter
   From peter
   ...........
   ?
   Можно переслать данное письмо другим пользователям.
   Например:
   ? m mary boris george
   ?
   Для посылки  почты  введите  команду  mail с параметром -
именем пользователя и введите текст письма,  заканчивая  его
знаком конца файла (control-D).
   Например:
   $ mail peter
   Извини, я не смогу играть завтра.
   Мне надо получить талоны на сахар и табак.
   ^D
   $

                                  - 82 -
   Посылка ответа может быть произведена при просмотре почты.
   Например:
   ?! mail peter
   Извини, я .....
   ..........
   ^D
   !
   ?
   Для просмотра почты из файла введите команду mail с  клю-
чом - f:
   $ mail -f from_peter
   Для выхода из системы mail наберите q.
   Например:
   ? q
   you have mail
   $.
   Работа с почтой закончена.

10. РАБОТА С ТЕКСТОВЫМИ ФАЙЛАМИ
   При разработке и документировании программного  обеспече-
ния  неожиданно  большое  время занимает работа по созданию,
анализу, проверке и исправлению текстовых файлов. Она выпол-
няется достаточно простыми средствами печати файлов,  поиска
строк,  замены букв и строк,  сравнения файлов и тому подоб-
ное.  Соответствующие утилиты весьма эффективны для выполне-
ния таких работ по сравнению с обычным текстовым редактором.


                                  - 83 -
10.1. Печать файла
   Простейший способ печати - это перенаправление  стандарт-
ного вывода команды cat на терминал,  имеющий устройство пе-
чати.
   Например:
   $ cat file > /dev/lp.
   Однако не  все терминалы имеют собственное устройство пе-
чати. В случае общего устройства печати система обеспечивает
его  коллективное  использование,  при котором заявка на пе-
чать,  заставшая устройство занятым,  ставится в очередь  до
момента  освобождения  устройства,  после чего ее требование
удовлетворяется автоматически.  В этом  случае  используется
команда lpr или lp.
   Например:
   $ lpr file1  file2  file3
   Имеются также команды просмотра очереди заявок на  печать
lpstat и удаления заявки из очереди (cancel).  Команды lpr и
lp не обеспечивают разбиение печати на страницы.  Это  может
быть  сделано  командой  pr  подготовки  (prepare) файла для
постраничной печати, которая предшествует печати.
   Пример:
   $ pr myfyle | lpr.
   Размеры страницы  по  умолчанию равны 66 строкам (длина -
length) по 72 знака (ширина - width).  Ключами -w и -l можно
задать другие размеры.
   Примеры:
   $ pr -w 132 -h"Conversion program" conv.c | lpr
   $ pr -l 25 addr | lpr

                                  - 84 -
   Ключ -h  (head) вводит заголовок печати.  Двойные кавычки
требуются при наличии в заголовке пробелов,  иначе они могут
быть опущены.

10.2. Разборка и сборка файла
   Многие команды ограничивают размеры  файла,  который  они
могут  обработать.  Если  ваш файл слишком велик,  вы можете
разбить его на части командой split,  а  впоследствии  после
обработки собрать из этих частей командой cat.  Каждая часть
становится независимым файлом с именами  по  умолчанию  xaa,
xab, xac, ..., xzz. Размер части по умолчанию - 1000 строк.
   Пример:
   $ split bigfile.
   Можно изменить  размер  по  умолчанию,  задавая его явно,
например, 500 строк:
   $ split -500 bigfile.
   Можно задавать имена частей, например:
   $ split bigfile ribs.
   В этом случае имена будут ribsaa, ribsab, ... ribszz.
   После необходимой  обработки  всех  или  некоторых частей
сборка файла из частей выполняется,  например, следующим об-
разом:
   $ cat ribs?? > bigfile.new,
где знаки вопроса - метасимволы, обозначающие любой символ.

                                  - 85 -
   Типичным примером применения технологии разборки - сборки
является печать отдельных избранных страниц файла.
   Пример:
   $ pr bigfile > bigpr
   $ split -66 bigpr
   $ lpr xaf xaj
   Здесь будут напечатаны 6-я и 10-я  страницы  размером  66
строк исходного файла.

10.3. Сортировка текстовых файлов
   Утилита sort упорядочивает записи файла в  алфавитно-циф-
ровом порядке.
   Пример:
   $ sort people
   Bill Williams  100
   Henry Morgan   112
   Mary Clark     101
   $
   Записи отсортированы по первой букве имени.  Однако можно
выполнить сортировку и по фамилиям:
   $ sort +1 people
   Mary Clark     102
   Henry Morgan   112
   Bill Williams  100
   $

                                  - 86 -
   Ключ +1 означает,  что одно поле с начала записи было иг-
норировано при сортировке.
   Сортировка по  третьему  полю с игнорированием лидирующих
пробелов выполняется с использованием ключа - b (blank):
   $ sort -b +2 people
   Bill Williams  100
   Mary Clark     101
   Henry Morgan   112
   $
   Для сохранения результата сортировки в файле используется
ключ -o (output):
   sort -o sortpeople +1 people
   Для слияния  уже отсортированных файлов используется ключ
-m.
   Пример:
   $ sort +1 admpeople > sortadm
   $ sort +1 hardpeople > sorthard
   $ sort +1 sortpeople > sortsoft
   $ sort -m +1 sortadm, sorthard, sortsoft > sortall
   $
   Имеется возможность  удаления дублированных записей,  ис-
пользуя ключ -u (uniq),  а также  сортировки  по  нескольким
несмежным полям.

10.4. Подсчет строк, слов, знаков в файле
   Подсчет числа строк,  слов и знаков в заданном файле  вы-
полняется командой wc.

                                  - 87 -
   Например:
   $ wc people
   3     9     51  people
   $
   Ключи - l (lines), - w (words) - c (character) могут ука-
зать явно объекты счета.
   Например:
   $ wc -l people
   3 people
   $ wc -lc people
   10    51  people
   $

10.5. Поиск строк в файле по образцу (grep)
   Утилита grep осуществляет поиск по одному или  нескольким
файлам и печатает все строки, содержащие предъявленный обра-
зец текста, на стандартном выводе.
   В простейшем  случае  образец задается постоянной строкой
знаков.  В общем же случае он задается регулярным выражением
(grep - акроним от global regular expression printer).
   Пример:
   $ grep Henry admpeople hardpeople softpeople
   Softpeople: Henry Morgan 112
   $
Или:

                                  - 88 -
   $ grep Henry *people
   Softpeople: Henry Morgan 112
   $
   Ключ -v (invert) предписывает печать  всех  строк,  кроме
найденных, например:
   $ grep -v "Henry Morgan" Softpeople
   Bill Williams 100
   Mary Clark    101
   $
   Двойные кавычки требуются для размещения в образце пробе-
лов.
   Регулярные выражения позволяют вести  поиск  типа:  найти
все слова из четырех букв, начинающиеся на d, или все слова,
кончающиеся на able, и тому подобное. Рассмотрим примеры за-
дания образцов посредством регулярных выражений.
   Знаки ^ и $ помечают начало и конец строки соответственно:
   "^Genesis" -   найти   все  строки,  начинающиеся  словом
Genesis;
   "eschatus$" -   найти   все  строки,  кончающиеся  словом
eschatus;
   "^Out in cold$" - найти все строки, равные образцу.
   Точка помечает любую букву:
   "d..."  - найти все слова из 4 букв, начинающиеся с d;
   "d...$" - то же в конце строки;
   "d..\ ." - найти все слова из 4 букв,  начинающиеся с d и
оканчивающиеся точкой (знак \ -  обратный  слэш  -  отменяет
специальное значение следующего символа).

                                  - 89 -
   Квадратные скобы задают возможные значения знака:
   "^ [abcxyz]"  -  найти  все  строки,  начинающиеся с букв
a,b,c,x,y или z:
   "[^Dd][a-z][a-z][a-z]" -  найти  все слова из 4 букв,  не
начинающиеся с D или d,  в которых последние три буквы - ма-
лые (от a до z).
   Фигурные скобки  задают количество повторений (замыкание)
предыдущего знака:
   "[^Dd][a-z]{3}" - то же самое, что и предыдущий пример;
   "[a-z]{3,5}" - найти все слова,  содержащие от 3 до 5 ма-
лых букв.
   Частные случаи  замыкания обозначаются специальным обра-
зом:
   * для {0} - ноль и более раз;
   + для {1} - один и более раз;
   ? для  {0,1} - ноль или один раз.
   Например:
   $ grep  ".*" people - просто напечатает все строки файла.
   Примеры использования  регулярных  выражений:
уничтожить все  пустые  строки  в файле:
   $ grep -v "^ $" file > newfile;
уничтожить все  строки,  состоящие только из пробелов:
   $ grep -v "^ *$" file > newfile.

10.6. Трансляция знаков (tr)
   Утилита tr работает со стандартным вводом и имеет два ар-
гумента, задающие упорядоченные множества знаков, в которых

                                  - 90 -
каждый знак  первого  множества  заменяется  соответствующим
знаком второго.
   Пример:
   $ tr a-z A-Z < people
   MARY CLARK     101
   HENRY MORGAN   112
   BILL WILLIAMS  100
   $
   Ключ -d позволяет задать множество символов,  которые бу-
дут уничтожены.
   Например:
   $ tr -d 0-9 < people
   Mary Clark
   Henry Morgan
   Bill Williams
   $

10.7. Команды сравнения файлов (diff, cmp, comm)
   В процессе  разработки программного обеспечения возникает
необходимость сравнения версий файла на  разных  этапах  его
разработки.  Узнать,  чем  версии  отличаются друг от друга,
удобно   командой   diff,   которая    показывает    разницу
(difference) двух файлов; сравнение файлов осуществляется по
строкам (записям). В результате выполнения команды печатают-
ся строки измененные (c), уничтоженные (d) и добавленные (a)
во втором файле-аргументе по сравнению с первым.

                                  - 91 -
   Пример:
   $ cat people
   Mary Clark    101
   Sally Smith   113
   Jane Buily    121
   $ cat people.new
   Mary Clark    101
   Sally White   113
   James Walker  112
   $ diff people people.new
     2 c 2
   Sally White  113
     3 d 2
   James Walker 112
   Знаки < и > означают удаление и добавление строк; команда
показывает также номера строк, в которых найдены отличия.
   Если строки  отличаются  только  числом разделяющих слова
пробелов, также отличия можно подавить ключом -b (blank).
   Например:
   $ diff -b oldfile newfile
   $.

                                  - 92 -
   Другая возможность быстрого сравнения  файлов  -  команда
cmp  (compare),  реализованная на основе побайтового (побук-
венного) сравнения двух файлов.
   Пример:
   $ cmp people people.new
   people, people.new differ: char 17, line 2
   В качестве результата печатается число отличающихся  бай-
тов (букв) и строк (линий).
   Ключ -l (long) позволяет распечатать разницу файлов в ви-
де байтов (адрес и отличающиеся значения).
   Например:
   $ cmp people people, new
   26   123   127
   27   155   150
   30   150   155
   - - - - - - - -
   197   60    61
   198   60    61
   Если файлы сильно отличаются друг от друга,  сравнить  их
эффективнее командой comm (common),  которая показывает, что
в двух файлах одинаковое общее.
   Например:
   $ cat people
   Mary Clark   101
   Sally Smith  113
   Jane Baily   121

                                  - 93 -
   $ cat people.new
   Mary Clark   101
   Sally White  113
   James Walker 112
   $ comm people people.new
                   Mary Clark
   Sally Smith
         Sally White
   Jane Baily
         James Walker
   Результат команды comm печатается в три  колонки:  строки
первого файла,  отсутствующие во втором: строки второго фай-
ла, отсутствующие в первом, и строки, общие для двух файлов.
   Можно подавить печать одного или двух столбцов,  указывая
его номер в виде ключа,  например  (печать  только  третьего
столбца):
   $ comm -12 people people.new
   Mary Clark
   $

10.8. Обработка текстовых файлов командой awk
   Awk - утилита, подобная grep. Однако, кроме поиска по об-
разцу,  она позволяет проверять отношения между полями строк
(записей) и выполнять некоторые действия над строками (гене-
рировать отчеты). Название не является акронимом, оно  обра-

                                  - 94 -
зовано первыми    буквами    фамилий    авторов    (A.V.Aho,
P.Y.Weinberger, B.W.Kernighan).
   Задание поиска-действия следует синтаксису:
   /<образец>/{<действие>}
   И образец,  и действие могут отсутствовать.  Найденные по
образцу строки при отсутствии заданного действия выводятся в
стандартный вывод (на экран).
   Образец задается регулярным выражением, как и в grep. Ес-
ли образец отсутствует, обрабатываются все строки.
   Рассмотрим примеры действий,  которые можно выполнить ко-
мандой awk.
   Перестановка полей строки выполняется с помощью ссылки на
поле $n, где n - номер поля.
   Например:
   $ cat people
   Mary Clark        101
   Henry Morgan      112
   Bill Williams     100
   $ awk '{print $2 "," $1 "^I" $3}' people
   Clark, Mary       101
   Morgan, Henry     112
   Williams, Bill    100
   где ^(control - I) - знак табуляции для подвода каретки к
очередной позиции табуляции (для выравнивания  третьего  по-
ля).

                                  - 95 -
   Действия для awk могут быть заданы в файле.
   Например:
   $ cat swap
   {print $2 "," $1 "^I" $3}
   $ awk -f swap people
   Awk имеет встроенные образцы и переменные.  Образцы BEGIN
и END означают начало и конец файла соответственно. Перемен-
ная  NR (Number of Records) означает число записей (строк) в
файле,  NF - число полей в записи.  Можно использовать пере-
менные,  объявленные пользователем.  Пример,  подсчитывающий
среднее значение третьего поля файла tennis (программа дейс-
твий для awk - в файле average):
   $ cat > average
   {total = total + $3}
   END {print "Average value is", total/NR}
   ^D
   $ awk -f average tennis
   Average value is 8.9
   $
   Образец поиска  в awk может содержать условные выражения.
Пример,  в котором в файле tennis пишутся все записи, значе-
ние третьего поля в которых не меньше 10:
      $ awk '$3 >= 10 {print $0}'tennis
   Steve Daniel     11
   Hank Parker      18
   Jack Austen      14
   $

                                  - 96 -
   Знак $0 (доллар-ноль) есть ссылка на всю запись (строку).
   В общем случае выражение для условия подчиняется  синтак-
сису, близкому к синтаксису выражений в языке C. Кроме того,
в команде awk допустимо указывать отрезок  образцов.  Пример
выборки всех записей, сделанных с 1976 до 1978 г.:
   $ sort -n -o chard.s chard
   $ awk '/1976/, /1978/ {if($2 < 8.00 print $0}' chard.s
   1976  7.50  Chateau
   1977  7.75  Chateau
   1978  5.99  Charles
   Как видно из примера, в программах действий для awk можно
использовать управляющие структуры с синтаксисом,  близким к
языку C.
   Пример цикла для печати полей всех записей файла в обрат-
ном порядке:
   $ awk {for (i = NF; i > 0; --i) print $i} f1,
где NF - число полей в записи.
   Полное описание  средств awk можно найти в статье авторов
[6].

11. СРЕДСТВА РАЗРАБОТКИ ПРОГРАММ
   Система UNIX обеспечивает богатый набор средств для  раз-
работки программ, включающий компиляторы, линкер, символьный
отладчик, средства ведения программных проектов и разработки

                                  - 97 -
языковых процессоров, архивные средства и другие.

11.1 Вызов компиляторов
   В системе UNIX имеются компиляторы с языков C, ФОРТРАН-77
и ПАСКАЛЬ и другие. Команды вызова компилятора имеют вид cc,
f77 или fc, pc и т.п.
   Параметрами этих  команд  являются файлы с текстами прог-
рамм на исходных языках,  имена которых должны  оканчиваться
на .c, .f, .p и т.п. соответственно.
   Примеры:
   $ cc program.c
   $ fc test.f
   $ pc example.p
   Результатом работы компилятора является файл исполняемого
кода,  имеющий по умолчанию имя a.out. Если вы хотите другое
имя,  его можно указать явно ключом -o <имя> при вызове ком-
пилятора.
   Пример:
   $ fc -o test test.f
   $ ls
   test
   test.f
   $


                                  - 98 -
11.2. Линкер
   На практике программы создаются  из  множества  раздельно
транслируемых модулей,  каждый из которых занимает отдельный
файл.  Результатом компиляции каждого модуля  является  файл
объектного (перемещяемого) кода, имя которого получается за-
меной .c (или .f, .p и т.д.) на .c. Затем все объектные фай-
лы объединяются в единую программу, помещаемую в файл испол-
няемого кода,  посредством линкера.  Линкер может вызываться
как независимой командой ld,  так и автоматически при выпол-
нении команд вызова компилятора cc,  fc, pc и т.д. В послед-
нем случае эти команды могут иметь несколько параметров-фай-
лов,  имена которых могут оканчиваться не только на .c,  .f,
.p, ..., но и на .o. Файлы исходного текста компилируются, а
затем все файлы объектного кода, как полученные в результате
компиляции,  так и параметры команды вызова компилятора, пе-
редаются линкеру.  Результатом по-прежнему является  файл  с
именем  по  умолчанию a.out,  если вы не указали явно другое
имя.
   При этом, как правило, объектные файлы уничтожаются. Что-
бы сохранить их, можно подавить автоматический вызов линкера
ключом -c (только компиляция) в команде вызова компилятора.
   Пример:
   $ fc -c test.f check prove.f
   $ ld /lib/frt0.o *.o -lF77

                                  - 99 -
   $ ls
   a.out
   check.f
   check.o
   prove.f
   prove.o
   test.f
   test.o
   $
   Здесь добавлены файл /lib/frt0.o  стартового  модуля  для
программы  на  ФОРТРАНе  (для  C /lib/crt0.o) и библиотека -
lF77 подпрограмм для ФОРТРАНа (для C - lc);  могут быть  до-
бавлены и другие библиотеки. Обозначение -lx является сокра-
щением для /lib/libx.a для любого x.  Следует заметить,  что
библиотеки  указываются  последними (не являются ключами ко-
манды ld).  При автоматическом вызове линкера стартовый  мо-
дуль и ряд библиотек вызываются по умолчанию.  Чтобы их уви-
деть, следует применить ключ -v в командах вызова компилято-
ра.

11.3. Библиотеки
   Как мы показали выше, на вход линкера могут подаваться не
только файлы объектного кода, но и библиотечные файлы, кото-
рые оказываются очень удобным средством  хранения  объектных
модулей, если их становится очень много.

                                  - 100 -
   Имя библиотечного файла обычно оканчивается на .a. Имеет-
ся  команда ar (архив) для создания,  пополнения и просмотра
библиотечных файлов.
   Пример создания библиотеки из трех объектных файлов:
   $ ar rcv exam.a test.o check.o prove.o
   a - test.o
   a - check.o
   a - prove.o
   $
   Здесь ключи команды ar означают:
   r - заменить (replace) модули в библиотеке;
   c - создать (create) библиотеку;
   v - печатать включаемые модули (verbose).
   Теперь мы можем распечатать содержимое библиотеки ко-
мандой ar с ключом t (table of content):
   $ ar t exam.a
   test.o
   check.o
   prove.o
   $
   и ссылаться на библиотеку в командах вызова  компиляторов
или линкера, например:
   $ ld -o test /lib/frt0.o exam.a -lF77
   Следует помнить, что порядок размещения модулей в библио-
теке существенен.
   Например, если  подпрограмма  test  вызывает подпрограмму
check, то test.o должен предшествовать check.o в библиотеке.

                                  - 101 -
Для выявления  и печати таких зависимостей предназначена ко-
манда lorder.

11.4. Символьный отладчик
   Как правило, имеется единый символьный отладчик для прог-
рамм на нескольких языках программирования,  компиляторы ко-
торых вырабатывают объектный код и таблицы символов в едине-
ом формате.  Символьный отладчик обычно имеет альтернативные
имена для разных языков, например, cdb, fdb и pdb для языков
C,  ФОРТРАН-77 и PASCAL соответственно. Вызов отладчика про-
изводится  одноименной командой,  в которой указывается файл
кода отлаживаемой программы, по умолчанию a.out. Для генера-
ции  и  сохранения  отладочной информации (таблиц символов и
т.п.) компиляция программы должна производиться с ключом -g.
   Пример:
   $ fc -g test.f check.f prove.f
   $ fdb
   >
   Знак > - подсказка отладчика, приглашающая вводить коман-
ды отладчика. Команды отладчика позволяют:
   - посмотреть  текущие  значения  переменных  выполняемого
оператора,  строки исходного текста, процедуры, файла в ука-
занном формате;
   - устанавливать и сбрасывать точки прерывания для пошаго-
вого  выполнения отлаживаемой программы между точками преры-
вания и/или с постоянным шагом;

                                  - 102 -
   - задавать  утверждения,  проверяемые  перед  выполнением
каждого оператора для останова перед теми  операторами,  для
которых утверждение истинно;
   - копировать все сигналы,  связанные с отлаживаемой прог-
раммой;
   - записывать и повторно использовать команды  сеанса  от-
ладки (командный файл на входе отладчика).
   Более подробную информацию о символьном  отладчике  можно
найти в руководстве по команде cdb.

11.5. Средства оценки эффективности исполнения программы
   Имеются средства, позволяющие выяснить, сколько времени и
места  требуется  для выполнения программы и ее частей.  Эти
средства полезны для сравнения качества реализации программы
на  разных языках программирования или в разных версиях сис-
темы UNIX.
   Команда time позволяет выяснить три значения потраченного
на решение указанной программы времени в секундах:  реально-
го,  равного времени, замеренному по секундомеру, зависящего
от количества пользователей в данный  момент;  пользователь-
ского, равного времени счета программы по командам пользова-
теля, и системного, равного времени системы при обслуживании
этой программы.  Команда time в Shell и в C-Shell имеет раз-
ные формы выдачи.

                                  - 103 -
   Пример (в Shell):
   $ time test
   real 30.0
   user 27.6
   sys   0.5
   $
   Команда size  показывает размер памяти в байтах трех раз-
личных  частей  программы:  выполняемого  кода  (называемого
текстом), области инициируемых данных и области неинициируе-
мых данных.
   Пример:
   $ size test
   1356 + 260 + 613 = 2226 b = 004265 b
   Общий размер программы test равен 4265 байтов.
   Если имя оцениваемого файла отсутствует,  подразумевается
a.out.
   Для программы на языке C есть более тонкое средство, поз-
воляющее получить профиль программы, показывающий для каждой
подпрограммы долю  времени  ее  выполнения  в  процентах  (%
time),  суммарное  время ее выполнения в секундах (cumsecs),
количество ее вызовов (# call) и время,  потраченное на один
вызов в миллисекундах (ms/call).  Для получения профиля сле-
дует перетранслировать программу с ключом  -p  (профиль),  а
после  запуска  программы,  во время которого статистическая
информация будет собрана в файле mon.out,  выполнить команду
prof для обработки указанного файла.

                                  - 104 -
   Пример:
   $ cc -p program.c
   $ mv a.out program
   $ program
   $ ls
   mon.out
   program
   program.c
   $ prof program
   name   % time   cumsecs   # call   ms/call
   conv   58.6     11.38     2000     5.69
   strcat 30.1      9.50      100     95.0
   main    1.1      2.1         1      2.1
   . . . . . . . . . . . . . . . . . . . . .
   atoi    0.0      0.1         1      0.0

11.6. Сопровождение программ: make
   Если программный продукт велик,  содержит много исходных,
объектных и исполняемых модулей,  задача его сопровождения и
модификации может быть облегчена утилитой make, которая поз-
воляет автоматизировать все рутинные операции по  перетранс-
ляции и перелинкированию всех или части модулей при внесении
в них изменений.
   Утилита make работает с файлом Makefile,  в который запи-
сывается необходимая информация о всех  файлах  программы  и
связях между ними.

                                  - 105 -
   Пример:
   $ cat Makefile
   FILES   = test.f  check.f  prove.f
   OBJECTS = test.o  check.o  prove.o
   test:  $ {OBJECTS}
          ld -o test/lib/frt0.o ${OBJECTS} -lF77
   $
   Как видно из примера,  в файле Makefile помещаются макро-
определения, имеющие вид:

   строка1 = строка2

и правила, имеющие вид:

   конечный файл : исходные файлы
   команда

   Первая строка  правила  называется зависимостью.  Зависи-
мость указывает,  что конечный файл является результатом ра-
боты команды, указанной во второй строке правила, над исход-
ными файлами. Внутри зависимости можно ссылаться на макрооп-
ределения в форме $(строка1).
   Подготовив такой Makefile, можно модифицировать прог-
рамму test одним вызовом команды make, например:
   $ make
   fc -c test.f
   fc -c check.f
   fc -c prove.f
   ld -o test/lib/frt0.o check.o prove.o -lF77
   $

                                  - 106 -
   Команда выполняется только в том случае, если дата созда-
ния или модификации конечного файла меньше, чем соответству-
ющая дата хотя бы одного исходного файла (то есть  если  ко-
нечный файл устарел).
   Возможно изменить только часть программы, например:
   $ make  prove.o
   fc -c  prove.f
   $
   В данном случае утилита make по  умолчанию  "знает",  что
файл  prove.o зависит от файла prove.f и реализация этой за-
висимости есть указанный вызов компилятора.
   Полезный ключ -n утилиты make позволяет не выполняя пред-
писанных действий предварительно посмотреть, что было бы вы-
полнено, если бы ключ не был подан.
   Подробнее о make можно узнать из руководства  по  команде
make и книг [7,8].

11.7. Средства реализации языков программирования
   До сих пор речь шла о разработке программ на языках прог-
раммирования, реализованных в системе (т.е. имеющих компиля-
тор и линкер).  Если вас, как опытного пользователя, не уст-
раивают  эти  предопределенные языки и вы хотите реализовать
свой язык,  то и в этом вам поможет система UNIX, предостав-
ляя утилиты lex и yacc.
   Утилита lex является текстовым  процессором,  реализующим
лексический анализ,  необходимый при создании компиляторов и
других языковых процессоров.
   Утилита yacc (yet another compiler compiler) конвертирует
безконтекстную грамматику в таблицы,  управляющие  граммати-


                                  - 107 -
ческим разбором посредством LR(1)-автомата.  Формируемые при
этом правила предшествования позволяют избавиться  от  двус-
мысленностей исходной грамматики.
   Совместное использование утилит lex и yacc является  мощ-
ным подспорьем для быстрой реализации языковых процессоров в
среде системы UNIX [9,10,11].

12. СРЕДСТВА РЕДАКТОРА EX, ДОПОЛНЯЮЩИЕ ВОЗМОЖНОСТИ РЕДАКТОРА VI
   Как уже говорилось, редактор vi тесно связан с редактором
ex, являясь по сути одним из режимов работы последнего. Поэ-
тому ряд мощных команд,  реализованных в ex, можно и полезно
выполнять и из редактора vi.

12.1. Выход из vi в ex
   Для выхода из vi в ex надо нажать клавишу (esc) для пере-
хода в командный режим,  если вы были в режиме текста, а за-
тем нажать клавишу [:] (двоеточие).  Будет напечатана  подс-
казка редактора ex - двоеточие, приглашающая вводить команды
редактора ex.

12.2. Просмотр строк текста
   Поскольку ex - строчный редактор, вводится понятие номера
строки и понятие текущей строки. Все строки текста занумеро-
ваны натуральными числами,  начиная с единицы.  Знак $ (дол-
лар) означает номер последней строки текста.
   Просмотр части  текста  на  экране  выполняется командой,
состоящей из одного (для просмотра одной  строки)  или  пары
номеров  -  номера  первой  и  номера последней строки части
текста и символа P (print),  который по умолчанию может быть
опущен. Например:

                                  - 108 -
   : 1,5p
   program (input, output)
   ......
   ......
   :
или просто :1,5
   Для просмотра всего текста надо ввести:
   : 1, $
   Чтобы напечатать строки вместе с их номерами, надо в кон-
це команды просмотра поставить знак # (диез), например:
   : 6, $#
   6 include 
   7 .......
   8 .......
   .........
   Следует помнить,  что  нумерация строк относительна.  При
удалении одной строки все строки перенумеруются.  После  вы-
полнения  команды  просмотра текущей строкой становится пос-
ледняя просмотренная строка.
12.3. Поиск строк по образцу текста
   Команда глобального поиска начинается  префиксом  g  (для
глобального  поиска  по всему тексту) и печатает все строки,
содержащие предъявляемый образец, например:
   : g/speed;
   int speed;
   d = speed x time;
   output (speed).

                                  - 109 -
   Образец может  быть  любой частью текста и запоминается в
специальном буфере искомого образца, отличном от буфера все-
го  текста.  Если  префикс g не указан,  ищется и печатается
первая найденная строка, начиная от текущей:
   : /speed;
   int speed.

12.4. Подстановка образца текста
   Подстановка образца   текста   выполняется   командой   s
(substitute),  в которой указывается искомый образец и заме-
няющий образец, например:
   : s/eed/ace/
   int space;
   Эта команда выполняет замену первого  вхождения  искомого
образца в текущей строке.
   Для замены всех вхождений в строке надо добавить  флаг  g
(global - глобальный) в конце команды:
   : s/wine/water/g
   water = water + shugar
   Чтобы выполнить подстановки в  нескольких  строках,  надо
добавить префикс адресации или поиска строк по образцу. Нап-
ример:
   : 1,10s/wine/water/g
или
   : 1, $s/wine/water/g
Примеры поиска по образцу:
   : g/speed/s/eed/ace/g

                                  - 110 -
или
   : g/speed/s//space/g.
   В последнем случае искомый образец берется из буфера  ис-
комого образца.
   Возможен интерактивный режим выполнения глобальной коман-
ды  подстановки,  при  котором редактор для каждой найденной
строки перед выполнением подстановки  требует  подтверждения
ее  необходимости в форме ввода буквы y (yes).  Для интерак-
тивной  формы  в  команде  требуется  использовать  ключ   c
(confirmation):
   : g/eed/s//ace/gc
   int speed;
         ^^^ y
   real need;
         ^^^
   d = speed x time;
         ^^^ y
   output (speed);
             ^^^ y
   Здесь три замены произведутся, а одна - нет.

12.5. Отмена последней подстановки
   Отмена последней   подстановки   выполняется  командой  u
(undo). Реализация команды u выполняется обратной подстанов-
кой, поэтому повторная подача команды отменяет первую коман-
ду u.

                                  - 111 -

12.6. Чтение и запись файлов в буфере редактирования
   Редактируемый файл  находится  в  буфере  редактирования.
Чтение содержимого другого файла в буфер редактирования пос-
ле  указанной или текущей строки можно выполнить командой r,
например:
   0r preface.
   Здесь содержимое файла чтения помещается в начале  буфера
редактирования (после несуществующей нулевой строки).  В ка-
честве файла чтения может быть файл стандартного вывода  ко-
манды, например (пробел перед ! обязателен):
   : r !date
   : 1, $p
   ----------
   Fr Jan  12   09:33   PST   1986
   Запись буфера редактирования или его  части  в  указанный
файл можно выполнить командой w, например:
   : w newfile
или
   : w >> oldfile
(добавление в существующий файл).
   Попытка записи буфера в уже существующий файл сопровожда-
ется  предупреждением  и  приглашением  повторить  команды с
восклицательным знаком:
   : w! oldfile
   Если имя опущено, подразумевается редактируемый файл.

                                  - 112 -
   Пример записи части буфера редактирования:
   : 1, 100w !lpr.
   Здесь роль файла записи играет стандартный вывод  команды
(пробел перед знаком ! обязателен).

12.7. Вызов на редактирование следующего или нового файла
   Если редактор  был  вызван  для редактирования нескольких
файлов, например:
   $ vi .*,
или
   $ ex *.c,
то переход к редактированию следующего файла выполняется ко-
мандой n (next):
   : n
   Командой e  (edit) можно вызвать на редактирование произ-
вольный файл, указанный именем
   : e another
   Если в момент подачи команд n или e буфер  редактирования
предыдущего  файла не был записан,  выдается предупреждение,
которое можно обойти,  форсировав выполнение команд  подачей
восклицательного знака : n! и : e! соответственно.

12.8. Выполнение команды системы внутри редактора ex
   Для этого используется префикс !  (восклицательный знак),
например:
   : !cc % ,

                                  - 113 -
где % - ссылка на имя текущего редактируемого файла.
   Два восклицательных знака:
   : !!
повторяют предыдущую команду.

12.9. Переход в режим редактора vi
   Выполняется командой vi, которой может предшествовать но-
мер строки, высвечиваемой в начале экрана, например:
   : 10 vi
   В режиме vi доступны все средства редактора. Выход из ре-
жима vi выполняется подачей команды Q (большое).

12.10. Выход из редактора ex
   Выход из редактора ex в режим команд системы  выполняется
командой q, например:
   : q
   Если буфер  редактирования  не был записан или еще не все
файлы отредактированы, выдается предупреждение, которое мож-
но обойти, подавая q с восклицательным знаком:
   : q!
   Команду выхода  можно для удобства комбинировать с коман-
дой записи, например:
   : wq
или
   : wq!
если есть препятствия для записи или выхода.

                                  - 114 -


13. РУКОВОДСТВО СИСТЕМНОГО АДМИНИСТРАТОРА
   В функции системного администратора системы  UNIX  входит
повседневное управление системой во всех аспектах ее сущест-
вования, таких как подключение новых пользователей, управле-
ние файловой системой, изменение конфигурации и других. Сле-
дует заметить, что на персональных ЭВМ эти функции могут ис-
полняться прикладным программистом.
   Имеется ряд команд, расположенных обычно в каталоге /etc,
рассчитанных на управление системой,  таких как fsck, mount,
chown и так далее. Как правило, каталог /etc доступен только
суперпользователю,  так  что  системный администратор должен
обладать правами суперпользователя.

13.1. Спецпользователи
   Это пользователи,  выполняющие действия над системой, не-
доступные обычным пользователям.  Один из них, имеющий неог-
раниченные полномочия, называется суперпользователем и имеет
обычно имя root.  Разные системы могут иметь и других  спец-
пользователей, например, пользователя с именем bin, обладаю-
щих меньшими полномочиями, чем суперпользователь.
   Имеются команды,  которые  может  выполнить только супер-
пользователь,  в частности,  установка даты  командой  date,
монтаж файловой системы командой mount, создание специальных
файлов командой mknod и другие.

                                  - 115 -
   Стать суперпользователем   можно  несколькими  способами.
Первый - загрузить систему в режиме единственного  пользова-
теля. Другой, применяемый на многопользовательской системе -
выполнить команду su (superuser). Администратору системы ре-
комендуется  входить в систему как обычному пользователю,  и
только в случае необходимости  становиться  временно  супер-
пользователем по команде su.

13.2. Загрузка и выключение системы
   Загрузка требуется,  когда на ЭВМ только что включили пи-
тание. Обычно процесс загрузки в большей или меньшей степени
автоматизирован  и  заключается  в  последовательном  вызове
программ, каждая из которых загружает и запускает следующую.
Первая программа, самая простая, загружена всегда и запуска-
ется при включении питания ЭВМ автоматически или вручную.
   В процессе загрузки может потребоваться ответить на  воп-
росы системы,  например,  касающиеся устройства,  на котором
находится загружаемая система. В завершение процесса загруз-
ки система выполняет командный файл /etc/rc, который, вообще
говоря,  может содержать любые команды,  но обычно  содержит
команды для выполнения следующих действий:
   - демонтаж старых файловых систем;
   - монтаж новых файловых систем;
    удаление старых журнальных учетных файлов;

                                  - 116 -
   - удаление временных файлов;
   - запуск процессов update и cron.
   Выключение многопользовательской системы производится вы-
полнением командного файла /etc/shutdown, который в типичном
случае выполняет следующие действия:
   - посылает предупреждающие сообщения всем активным  поль-
зователям командой wall;
   - убивает все процессы, кроме процесса консоли;
   - очищает все буферы обменов с файлами командой sync;
   - демонтирует файловые системы;
   - выполняет, если надо, процедуры копирования данных;
   - выключает питание ЭВМ,  если  позволяет  аппаратура;  в
противном случае, питание выключается вручную.

13.3. Пользователи и группы
   Имеется два файла с именами passwd  и  group  в  каталоге
/etc,  которые содержат информацию о пользователях и группах
пользователей соответственно.
   Одна запись в файле passwd соответствует одному пользова-
телю и имеет следующие текстовые поля,  разделенные символом
двоеточия:
   - имя пользователя;
   - пароль пользователя (в закодированном виде);
   - целочисленный идентификатор пользователя;
   - целочисленный идентификатор группы;

                                  - 117 -
   - комментарий,  который содержит сведения о месте  работы
пользователя  и может использоваться командой finger и учет-
ными программами;
   - каталог пользователя;
   - интерпретатор команд пользователя.
   Пример записи файла passwd (с пустым комментарием):
   mary:KmHu1hE:201:10::/users/mary:/bin/csh
   При наличии  комментария его синтаксис определяется учет-
ными программами.
   Для некоторых системых программ требуется,  чтобы иденти-
фикатор суперпользователя был равен нулю, а имя - root.
   Одна запись  в  файле  group соответствует одной группе и
представляет собой строку текста со следующими полями,  раз-
деленными двоеточиями:
   - имя группы;
   - пароль группы (в закодированном виде);
   - целочисленный идентификатор группы;
   - список имен пользователей группы, разделенных запятыми.
   Пример записи файла group (для группы без пароля):
   sect2115::10:mary,sas,temp,ges
   Добавление нового пользователя в системе требует выполне-
ния следующих трех действий,  которые обычно реализуются ко-
мандным файлом с именем newuser или adduser:
   - добавить запись в файл passwd с информацией о пользова-
теле;
   - создать каталог пользователя,  причем пользователь дол-
жен быть владельцем этого каталога;

                                  - 118 -
   - добавить или скорректировать запись в файле group в со-
ответствии с членством пользователя в некоторой группе.
   Добавление и  коррекция  записей  в файлах passwd и group
может выполняться текстовым редактором (если нет  командного
файла newuser).
   Каталог пользователя создается  суперпользователем  (воз-
можно,  посредством  скрипта  newuser) и вначале принадлежит
ему.  Чтобы изменить пользовательскую и групповую принадлеж-
ность каталога (и любого файла),  используются команды chown
(change own) и chgrp (change group) соответственно. Их может
выполнить только суперпользователь.
   Часто новый пользователь забывает свой пароль. Суперполь-
зователь  может  в  этом случае изменить пароль пользователя
командой passwd,  затерев забытый и сообщив пользователю но-
вый:
   # passwd mary
   New passwd : mmm
   Retype new passwd : mmm
   #
Вводимый пароль (здесь mmm) не виден.

13.4. Специальные режимы исполняемого файла
   Кроме девяти  режимов  защиты  файла имеется три дополни-
тельных режима,  которые имеют смысл только для  исполняемых
файлов.  Эти  режимы  может установить только суперпользова-
тель, используя команду chmod (change mode).

                                  - 119 -
   Специальные режимы  соответствуют  восьмеричным значениям
4000, 2000 и 1000 первого параметра этой команды:
   - 4000 - бит установки идентификатора пользователя;  ука-
зывает, что, когда программа (файл) выполняется, идентифика-
тор пользователя устанавливается равным идентификатору  вла-
дельца  этого  файла,  а не пользователя,  запустившего этот
файл на исполнение;
   - 2000 - бит установки идентификатора группы;  указывает,
что на  время  выполнения  программы  (файла)  идентификатор
группы  устанавливается равным идентификатору группы,  соот-
ветствующему групповой принадлежности этого файла;
   - 1000 - бит разделения; указывает, что выполняемая прог-
рамма (файл) разделяется многими пользователями и  свопинго-
вое пространство не сбрасывается,  даже если никто программу
не использует в данный момент.
   Установка обоих   битов  идентификаторов  пользователя  и
группы позволяет пользователю выполнять такие программы, ко-
торые  должны  иметь полномочия суперпользователя (например,
программа mail создает каталог /usr/spool/mail). В противном
случае возможности системы,  доступные пользователю, были бы
значительно ограничены.

13.5. Файловые системы
   Файловая система  имеет иерархическую структуру каталогов
и файлов,  включая корневой каталог. Файловая система распо-
лагается на устройстве,  которое является, обычно, магнитным
диском того или иного типа. Если диск  достаточно  велик, он


                                  - 120 -
может быть разбит на несколько "логических" дисков; тогда на
каждом логическом диске может быть размещена отдельная  фай-
ловая  система.  Каждая  файловая система,  прежде чем стать
доступной, должна быть смонтирована.
   Количество файлов  в  файловой  системе ограничено (65536
для UNIX, версия 7).
   Каждая файловая система имеет четыре основные части:
   - загрузочный блок; это самый первый блок диска (блок 0),
зарезервированный для системной загрузочной программы;
   - супер-блок - это первый блок собственно файловой систе-
мы (блок 1);  он содержит основные данные о файловой системе
и ее размещении на диске,  в том числе о  списках  свободных
i-узлов и блоков;
   - i-узлы - это последовательность блоков вслед за суперб-
локом;  i-узел содержит ссылки на блоки;  имеется ровно один
i-узел для каждого каталога или файла в файловой системе;
   - блоки  -  оставшееся пространство диска занимают блоки,
которые содержат либо действительные данные каталогов и фай-
лов (блоки данных), либо ссылки на блоки (косвенные блоки).
   Суперблок содержит следующие данные:
   - размер дискового пространства, доступного файловой сис-
теме (в блоках);
   - число блоков, зарегистрированных для i-узлов;
   - имя файловой системы;
   - имя тома;
   - время последнего изменения;

                                  - 121 -
   - время последнего копирования (back up);
   - ссылка на список свободных блоков;
   - ссылка на список свободных i-узлов.
   Структура файловой системы представлена на рис.13.1.

                            -------------     -------------
                          ------------- ╨   ------------- ╨
----------- ----------- ------------- ╨ ╨ ------------- ╨ ╨
╨ Загру-  ╨ ╨         ╨ ╨           ╨ ╨ ╨ ╨           ╨ ╨ ╨
╨ зочный  ╨ ╨Суперблок╨ ╨   i-узлы  ╨ ╨-- ╨   Блоки   ╨ ╨--
╨  блок   ╨ ╨         ╨ ╨           ╨--   ╨           ---
----------- ----------- -------------     -------------
               ╨  ╨ 
               ╨  ╨       -------------        -------------
               ╨  ╨     ------------- ╨      ------------- ╨
               ╨  ╨   ------------- ╨ ╨    ------------- ╨ ╨
               ╨  ╨   ╨   Список  ╨ ╨ ╨    ╨   Список  ╨ ╨ ╨
               ╨  --->╨ свободных ╨ ╨--    ╨ свободных ╨ ╨--
               ╨      ╨  i-узлов  ╨--   -->╨   блоков  ╨--
               ╨      -------------     ╨  -------------
               --------------------------

                             Рис.13.1.


   Каждый файл  (и  каталог)  в файловой системе представлен
i-узлом, содержащим указатели на блоки, составляющие файл.

                                  - 122 -
   В i-узле  содержится  также информация о правах доступа к
файлу,  число ссылок на файл из каталогов и  другие  данные.
Структура i-узла и блоков файла для UNIX,  версия 7 показана
на следующем рисунке.  Каждый i-узел содержит 13 указателей.
Первые 10 указателей непосредственно ссылаются на блоки дан-
ных файла. Поскольку блок содержит 512 байтов, то этого дос-
таточно для обработки файлов до 512х10=5120 байтов.
   Если длина файла больше,  чем  5120  байта,  используется
11-й  указатель i-узла,  который ссылается на косвенный блок
из 128 ссылок на блоки данных. Использование косвенного бло-
ка    позволяет    увеличить   длину   файла   до   величины
512х(10+128)=70656 байтов. Если и этого недостаточно, то ис-
пользуется 12-й указатель i-узла, ссылающийся на дважды кос-
венный  блок,  содержащий  128  ссылок  на  косвенные  блоки
(рис.13.2). Тогда максимальный размер файла увеличивается до
величины 512х(10+128+128**2)=8459264  байтов.  Наконец,  ис-
пользование последнего,  13-го указателя на трижды косвенный
блок из 128 ссылок на дважды косвенные блоки,  дает предель-
ную длину в файловой системе:
   512х(10+128+128**2+128***3)=1082201088 байтов
(см. рис. 13.2).
   Другие версии системы UNIX могут  отличаться  количеством
ссылок в i-узле, косвенных блоках и размером блока данных.
   Когда система загружается,  имеется только одна из файло-
вых систем, называемая корневой. В ней находятся все важней-

                                  - 123 -
                           -------                     -------
    i-узел    ------------>╨-----╨                 --->╨-----╨
------------- ╨            ╨-----╨               ╨-╨   ╨-----╨
╨ Информация╨ ╨ ---------->╨-----╨     --------  ╨ --->╨-----╨
╨  о файле  ╨ ╨ ╨          ╨-----╨  -->╨ 128  ╨--+     ╨  :  ╨
╨-----------╨ ╨ ╨ -------->╨-----╨  ╨  ╨      ╨  ╨     ╨Блоки╨       -------
╨  1        +-- ╨ ╨        ╨  :  ╨  ╨  --------  ╨ --->╨-----╨   --->╨-----╨
╨-----------╨   ╨ ╨        ╨Блоки╨  ╨ Косвенный  ╨-╨   ╨-----╨   ╨   ╨-----╨
╨  2        +---- ╨        ╨-----╨  ╨   блок       --->╨-----╨   +-->╨-----╨
╨-----------╨     ╨ ------>╨-----╨  ╨                  -------   ╨   ╨  :  ╨
╨  3        +------ ╨      ╨-----╨  ╨                            ╨   ╨-----╨
╨-----------╨       ╨ ---->╨-----╨  ╨                   -------  +-->╨-----╨
╨  :        ╨       ╨ ╨    ╨-----╨  ╨                   ╨ 128 ╨--╨   ╨-----╨
╨  :        ╨       ╨ ╨ -->╨-----╨  ╨               --->-------  --->╨-----╨
╨-----------╨       ╨ ╨ ╨  -------  ╨            ╨--╨   -------  --->╨-----╨
╨  8        +-------- ╨ ╨  ----------            ╨  --->╨ 128 ╨--╨   ╨-----╨
╨-----------╨         ╨ ╨  ╨                     ╨      -------  +-->╨-----╨
╨  9        +---------- ╨  ╨                     ╨         .     ╨   ╨-----╨
╨-----------╨           ╨  ╨                     ╨         .     ╨   ╨  :  ╨
╨ 10        +------------  ╨                     ╨         .     +-->╨-----╨
╨-----------╨              ╨                     ╨         .     ╨   ╨-----╨
╨ 11        +---------------           --------  ╨         .     --->╨-----╨
╨-----------╨                          ╨ 128  ╨--+         .         ╨-----╨
╨ 12        +------------------------->╨      ╨  ╨         .     --->╨-----╨
╨-----------╨                          --------  ╨         .     ╨   ╨-----╨
╨ 13        +----                       Дважды   ╨         .     +-->╨-----╨
-------------   ╨                      косвенный ╨         .     ╨   ╨-----╨
                ╨                        блок    ╨         .     ╨   ╨  :  ╨
                ╨                       -------  ╨      -------  +-->╨-----╨
                ╨                   --->╨-----╨  ╨      ╨ 128 ╨--╨   ╨-----╨
                ╨                   ╨   ╨-----╨  ╨  --->-------  --->╨-----╨
                ╨                   +-->╨-----╨  ---╨                ╨-----╨
   --------------          -------  ╨   ╨  :  ╨     --->------   --->╨-----╨
   ╨                       ╨ 128 ╨--+   ╨-----╨         ╨ 128 ╨--╨   ╨-----╨
   ╨                ------>-------  +-->╨-----╨         -------  +-->╨-----╨
   ╨                ╨         .     ╨   ╨-----╨                  ╨   ╨-----╨
   ╨        ------- ╨         .     --->╨-----╨                  ╨   ╨  :  ╨
   ╨     -->╨ 128 ╨-╨         .     --->╨-----╨                  +-->╨-----╨
   ╨     ╨  ------- ╨         .     ╨   ╨-----╨                  ╨   ╨-----╨
   ╨     ╨     .    ╨      -------  +-->╨-----╨                  --->╨-----╨
   ╨     ╨          ------>╨ 128 ╨--+   ╨-----╨                      -------
   ╨     ╨     .           -------  ╨   ╨  :  ╨                       Блоки
   ╨     ╨                          +-->╨-----╨
   ╨     ╨     .                    ╨   ╨-----╨
---+---  ╨                          --->╨-----╨
╨ 128 ╨--+     .                        ╨-----╨
-------  ╨                              ╨-----╨
 Трижды  ╨     .                    --->╨-----╨
косвенный╨                          ╨   ╨-----╨
  блок   ╨     .                    +-->╨-----╨
         ╨                 -------  ╨   ╨  :  ╨
         ╨     .           ╨ 128 ╨--+   ╨Блоки╨
         ╨          ------>-------  ╨   ╨-----╨
         ╨  ------- ╨         .     --->╨-----╨
         -->╨ 128 ╨-╨         .     --->╨-----╨
            ------- ╨         .     ╨   ╨-----╨
                    ╨      -------  +-->╨-----╨
                    ------>╨ 128 ╨--+   ╨-----╨
                           -------  ╨   ╨  :  ╨
                                    --->╨-----╨          Рис. 13.2.
                                        -------

                                  - 124 -
шие каталоги (/dev,/etc,  /bin и т.п.). Все остальные файло-
вые системы должны быть созданы и смонтированы.

13.5.1. Создание и монтаж файловой системы
   Команда mkfs создает новую файловую систему. Она располо-
жена в каталоге /etc и имеет два параметра:
    /etc/mkfs <имя> <размер>
   Первый параметр является именем специального файла и ука-
зывает  устройство,  на  котором создается файловая система.
Второй параметр - размер  пространства  файловой  системы  в
блоках;  используется  для определения по некоторым правилам
числа блоков после того, как размещены i-узлы.
   Пример создания файловой системы на флоппи-диске:
    /etc/mkfs /dev/flo 2000
     isize = 230
   Ответное сообщение указывает число блоков, выделенное для
размещения i-узлов.
   Далее, чтобы сделать файловую систему известной  операци-
онной системе,  надо ее смонтировать командой mount. Эта ко-
манда подключает корневой каталог монтируемой файловой  сис-
темы в один из каталогов корневой файловой системы.  Команда
расположена в каталоге /etc и имеет два параметра:
    /etc/mount <устройство> <каталог>
   Первый параметр является именем спецфайла для монтируемо-
го логического устройства, содержащего подключаемую файловую

                                  - 125 -
систему. Второй - имя уже существующего каталога,  под кото-
рым монтируется файловая система.
   Пример монтажа вновь созданной файловой системы на гибком
диске под каталогом, созданным командой mkdir в корне корне-
вой файловой системы:
    cd /
    mkdir floppy0
    /etc/mount /dev/fl0 /fioppy0
   Чтобы выяснить,  какие файловые  системы  смонтированы  в
данный момент, надо подать команду mount без параметров:
    mount
   /dev/fl0 on /floppy0
   Ответом является сообщение об этих  системах  (в  данному
случае - одной).  Оно формируется на основе данных о монтаже
файловых систем, хранимых в файле /etc/mnttab.
   Следует заботиться  о том,  чтобы права доступа корневого
каталога монтируемой файловой системы и каталога,  под кото-
рым производится монтаж,  были одинаковыми во избежание оши-
бок операционной системы.

13.5.2. Демонтаж файловой системы
   Если файловая система на съемном устройстве больше не ис-
пользуется, ее можно демонтировать командой umount, располо-
женной в каталоге /etc и имеющей один параметр:
    umount <устройство>

                                  - 126 -
   Например, демонтиж файловой системы на  гибком  диске  из
предыдущего примера выполняется командой:
    umount /dev/fl0
   Результатом демонтажа является разрыв связи между  корне-
вым  каталогом  демонтируемой  файловой  системы и каталогом
корневой файловой системы,  в котором  производился  монтаж.
При выполнении команды демонтажа текущий каталог должен быть
вне демонтируемой файловой системы, иначе будет выдано сооб-
щение:
   umount : device  busy               (устройство занято)
и команда не будет выполнена.

13.5.3. Синхронизация файловых систем
   При обменах с файлами система поддерживает в  оперативной
памяти множество буферов, свободных блоков, i-узлов, а также
супер-блок.  Для корректного завершения операций с  системой
необходимо  перед  ее  выключением  переписать все данные из
этих буферов и блоков в  дисковую  память.  Выполнение  этих
действий называется синхронизацией файловой системы и реали-
зуется командой sync:
    /etc/sync
   Команда не выдает никаких со