Командный язык shell
          Производственно-внедренческий кооператив
                    "И Н Т Е Р Ф Е Й С"
                Диалоговая Единая Мобильная
                    Операционная Система
                        Демос/P 2.1
                       Командный язык
                           SHELL
                           Москва
                            1988
                        АННОТАЦИЯ
     Описывается интерпретатор командного языка shell.  Опи-
саны элементы языка, оператор И структура программ на shell,
а также встроенные возможности.
1.  ВВЕДЕНИЕ
     В семействе операционных систем, совместимых с ОС UNIX,
язык SHELL используется в качестве стандартного языка управ-
ления заданиями, т.е. является основным языком общения поль-
зователя с системой.  Он предоставляет средства для описания
таких действий, как, например, запуск  какого-либо  компиля-
тора или программы, создание, копирование и уничтожение фай-
лов, опрос состояния процессов.  Кроме  того,  SHELL  широко
применяется  и в качестве языка разработки особых программ -
командных файлов.  Последнее свойство объясняется  тем,  что
SHELL имеет много общего с универсальными языками программи-
рования, в частности, конструкции, которые позволяют  созда-
вать программы, содержащие проверки условий и циклы.
     Важным достоинством  языка,  является  возможность  его
поэтапного  изучения.   Для  того чтобы начать работу в сис-
теме,  пользователю  достаточно  ознакомиться   с   разделом
"Основные понятия" данного документа.
2.  ОСНОВНЫЕ ПОНЯТИЯ
     После регистрации пользователя вся дальнейшая работа  с
системой  выполняется под управлением программы sh - интерп-
ретатора командного языка SHELL.
     Во время работы пользователь выдает команды и  получает
сообщения системы о результатах их выполнения.  Как правило,
при получении команды интерпретатор  определяет  имя  файла,
содержащего   программу,  которую  необходимо  выполнить,  и
порождает процесс, который работает под управлением заданной
программы.   Исключения  составляют случаи, когда вызываются
встроенные команды языка SHELL, при этом указанные  действия
выполняются  непосредственно  интерпретатором без порождения
нового процесса.  Поскольку, в качестве имени команды  может
указываться  любой  файл,  содержащий исполняемую программу,
существует практически безграничная  возможность  расширения
набора команд.
     С понятием процесса  в  ДЕМОС  связано  понятие  среды.
Среда  формируется  процессом-родителем  и содержит дополни-
тельную информацию о способе выполнения  процесса.   Каждому
процессу ставится в соответствие три файла: стандартный файл
ввода, стандартный файл вывода и файл диагностических  сооб-
щений.  При запуске команды пользователь может указать файлы
которые будут применяться в качестве стандартных.  По  умол-
чанию,  ввод/вывод  информации  осуществляется  с  терминала
пользователя.
     Характерной чертой систем, совместимых с ОС UNIX, явля-
ется  естественная  возможность работы с несколькоми процес-
сами одновременно.  Пользователь может  указать  в  команде,
что  соответствующий  процесс  должен  работать  как фоновый
                           - 3 -
(т.е. переход к приему следующей команды осуществляется  без
ожидания  окончания  данного процесса).  Кроме того, сущест-
вует возможность  задания  команд,  для  выполнения  которых
интерпретатор  порождает несколько взаимодействующих процес-
сов.  При этом создается  цепочка  процессов  (конвейер),  в
которой  обрабатываемая информация передается от одного про-
цесса другому по каналу межпроцессной связи.
2.1.  Простые команды
     Простые команды состоят из одного или нескольких  слов,
разделенных пробелами. Первое слово является именем выполня-
емой команды;  все  остальные  слова  передаются  команде  в
качестве параметров.  Например,
                             who
представляет собой  команду,  которая  выдает  информацию  о
пользователях, зарегистрированных в системе.  Команда
                            ls -l
выдает список файлов текущего справочника.  Параметр -l ука-
зывает  команде  ls, что нужна информация о характеристиках,
размере и дате создания каждого файла.
2.2.  Фоновые процессы
     Для того, чтобы выполнить команду, интерпретатор  языка
SHELL  обычно  создает  новый процесс и ждет его завершения.
Пользователь может запускать процессы в фоновом режиме,  при
этом  интерпретатор  переходит к обработке следующей команды
сразу после запуска  процесса,  не  ожидая  окончания  ранее
запущенного.  Например, команда:
                       cc program.c &
вызывает компилятор для обработки файла  program.c.   Символ
&,  завершающий строку, указывает интерпретатору команд, что
следует перейти к обработке следующей команды  без  ожидания
окончания  трансляции.  Для последующего наблюдения за ходом
процесса система  сообщает  уникальный  номер,  по  которому
можно запрашивать информацию о его состоянии.
2.3.  Задание имен файлов
     В  языке  SHELL  предусмотрен  механизм  для  генерации
списка   имен   файлов,   которые  соответствуют  некоторому
образцу.  Например, при выполнении команды:
                          ls -l *.c
в  качестве  параметров  ls  передаются  имена  всех  файлов
                           - 4 -
текущего  справочника,  которые оканчиваются на .c. Символ *
имеет специальное значение (т.е. является метасимволом языка
SHELL), ему соответствует любая строка (в том числе пустая).
При задании образцов могут использоваться следующие метасим-
волы:
*      соответствует любой строке символов  (включая  пустую
       строку);
?      соответствует любому одиночному символу;
[...]  соответствует любому из перечисленных  внутри  скобок
       символов;  пара  символов,  разделенных знаком минус,
       будет соответствовать  любому  символу  из  заданного
       лексического промежутка.
     Например, образцу
                           [А-Я]*
соответствуют все имена в текущем справочнике, которые начи-
наются с прописной русской буквы, а образцу
                      /usr/nata/test/?
соответствуют  все  односимвольные  имена   из   справочника
/usr/nata/test.  Если не найдено ни одного файла, соответст-
вующего заданному образцу, то в качестве  параметра  команде
передается сам образец.
     Описанный механизм  сокращает  время  набора  команд  и
позволяет  выбирать  имена,  отвечающие  нужному образцу. Он
также может  использоваться  при  поиске  файлов.  Например,
команда
                    echo /usr/nata/*/core
находит и печатает полные имена всех файлов core из подспра-
вочников  справочника /usr/nata (команда echo является стан-
дартной командой ДЕМОС,  которая  печатает  свои  параметры,
разделяя их пробелами).
     Из  общих  правил,  указанных  для  образцов,   имеется
единственное  исключение.  Символ  '.'  в начале имени файла
должен указываться явно.  Поэтому команда:
                           echo *
будет выдавать все имена файлов в текущем справочнике, кото-
рые не начинаются с точки, а команда:
                           echo .*
                           - 5 -
напечатает имена файлов, начинаюшиеся с точки.   Это  позво-
ляет исключить неумышленную подмену имен "." и "..", которые
соответственно означают текущий справочник и основной  спра-
вочник.
2.4.  Отмена специального значения метасимволов
     Для языка  SHELL  символы  имеют  специальное  значение
(полный  список  метасимволов приведен в табл.2 Приложения).
Любой  метасимвол,  которому  предшествует  обратная  черта,
теряет  свое  специальное значение (действие \ распространя-
ется только на следующий за ним символ, при этом сам знак  \
игнорируется).  Так, команда:
                          echo \?
напечатает только знак вопроса '?', а команда:
                           echo \\
выдаст лишь один символ \.  Для записи  длинных  конструкций
более чем в одной строке, специальное значение символа новой
строки \n отменяется.
     Знак \ удобен для отмены специального значения  отдель-
ных  символов.  Когда  же необходимо экранировать сразу нес-
колько метасимволов, такой механизм оказывается слишком гро-
моздким. В этом случае последовательность знаков заключается
в апострофы. Например, команда:
                       echo хх'****'хх
напечатает
                          хх****хх
     Символ новой строки \n, заключенный в апострофы, теряет
свое специальное значение. Однако, экранировать сам апостроф
таким способом нельзя.
     Еще одним механизмом отмены специального значения  сим-
волов является заключение их в двойные кавычки.
2.5.  Задание файлов ввода/вывода
     Результаты работы  большинства  команд  записываются  в
стандартный файл вывода. По умолчанию вся выдаваемая процес-
сом информация отображается на терминал  пользователя.   При
необходимости она может быть записана и в обычный файл. Так,
в следующем примере:
                           - 6 -
                       ls -l > filels
конструкция "> filels" рассматривается как указание  исполь-
зовать  в  качестве  стандартного вывода команды ls заданный
файл (в данном случае файл filels).  Если файл с данным име-
нем отсутствует, интерпретатор команд создает его. Если файл
существует, то его исходное содержимое  заменяется  информа-
цией, выдаваемой командой.
     Если требуется сохранить содержимое  файла,  добавив  в
него  поступающую  информацию, вместо символа >> используется
конструкция >>>>. Например:
                        ls >>>> filels
В данном случае, если файл не существует, он также предвари-
тельно создается системой.
     Аналогичные возможности предоставляются и для переопре-
деления  стандартного  файла ввода (по умолчанию данные вво-
дятся с терминала).  Для этой цели  используется  символ  <<.
Например, команда:
                        wc << filels
выдает количество строк файла filels.
     Далее перечислены  основные  конструкции,  используемые
для задания файлов ввода/вывода.
>> файл
     В качестве стандартного файла вывода используется файл,
     который  перезаписывается  заново  или  создается, если
     ранее не существовал.
>>>> файл
     Поступающая информация добавляется к содержимому файла.
     Если файл не существует, он предварительно создается.
<< файл
     В качестве стандартного файла ввода используется файл.
<<<< файл
     Чтение локального файла (см. раздел 4.8).   Последующие
     строки  передаются  команде в качестве информации стан-
     дартного файла ввода до тех  пор,  пока  не  встретится
     строка,  содержащая  последовательность  символов файл.
     Если специальное значение первого символа  строки  файл
     отменено,  выполняются  подстановки значений макропере-
     менных и результатов выполнения команд.
>>& цифра
     Информация, записываемая в файл с  дескриптором  цифра,
                           - 7 -
     передается в стандартный файл вывода.
<<& цифра
     Стандартным файлом ввода является файл  с  дескриптором
     цифра.
<<&-  Файл стандартного ввода закрыт на запись.
>>&-  Файл стандартного вывода закрыт на чтение.
2.6.  Связь процессов, конвейеры и фильтры
     Информация, выдаваемая в стандартный файл вывода  одной
командой,  может непосредственно передаваться другой команде
в качестве содержимого стандартного файла ввода.   Например,
в результате работы команд:
                           ls | wc
будет выдано общее число символов в именах текущего справоч-
ника.   Составная  команда,  образованная с помощью операции
"|", называется конвейером. В данном  случае  она  выполняет
действие эквивалентное командам:
                     ls >> filels
                     wc << filels
                     rm filels
за тем исключением, что для хранения промежуточных результа-
тов  не  используется  никаких  файлов.   В конвейере каждая
команда  работает  как  параллельный  независимый   процесс,
информация передается в одном направлении. Если входные дан-
ные процесса-получателя еще не готовы, или  выходные  данные
процесса-источника не успевают обрабатываться, то выполнение
соответствующего процесса приостанавливается.
     Фильтром называется команда, которая, получая данные из
стандартного  файла  ввода,  производит  какую-либо работу и
выдает результат в стандартный файл вывода.  Типичным приме-
ром  фильтра может служить команда grep, которая, читая дан-
ные из стандартного файла ввода, выбирает строки, содержащие
указанную  последовательность  символов  и выдает их в стан-
дартный файл вывода.  Например, команда:
                       ls | grep old
выдает только те имена файлов текущего справочника,  которые
содержат  последовательность  символов  old.   Конвеер может
состоять более чем из двух процессов.   Например,  конструк-
ция:
                   ls | grep bak | wc -l
                           - 8 -
может использоваться для подсчета числа имен файлов в  теку-
щем  справочнике, которые содержат последовательность симво-
лов bak.
2.7.  Макропеременные
     Имя макропеременной представляет  собой  последователь-
ность  букв,  цифр  и символов подчеркивания, начинающуюся с
буквы.
     При выполнении оператора присваивания в командную среду
текущего  процесса  заносится  запись  типа  имя=значение, в
левой части которой стоит имя макропеременной, а в правой  -
последовательность  символов,  являющаяся  ее  значением.  В
командной строке все вхождения вида $имя заменяются значени-
ями  соответствующих  макропеременных (исключение составляют
случаи, когда подобные  конструкции  заключены  в  апострофы
'...' или символу $ предшествует знак \).
     Примеры:
USER=nata HOME=/usr/nata
     присваивание значений макропеременным USER и HOME;
null=
     присваивание макропеременной значения пустой строки;
echo $USER
     выполнение   подстановки    значения    макропеременной
     (результат - строка nata).
     Переменные могут использоваться для  введения  сокраще-
ний.  Так, при выполнении команд:
           b=/usr/nata/bin
           mv pgm $b
файл pgm будет перемещен из текущего справочника в  справоч-
ник /usr/nata/bin.
     В более общем виде  макровызов  записывается  следующим
образом:
           ${имя_макропеременной}
Фигурные скобки в данном случае играют роль  разделителей  и
используются тогда, когда за именем следует буква или цифра.
Например, в результате выполнения группы команд:
          П=ПРОБ
          ПА=ПЕРА
          echo  ${П}А $ПА
                           - 9 -
будет выдан текст:
          ПРОБА ПЕРА
     В языке SHELL существуют  специальные  макропеременные,
которые  определяются перед началом выполнения команды (иск-
лючение составляет макропеременная ?, которая получает  зна-
чение после выполнения команды):
?    Десятичное  целое  число  -  код  завершения  последней
     выполненной  команды. В большинстве случаев, при успеш-
     ном выполнении команд, значение кода  завершения  равно
     нулю.  В  противном случае, если команда закончилась не
     удачно, код завершения не равен нулю.
#    Количество полученных параметров.
$    Номер данного процесса. Поскольку для каждого  процесса
     существует  свой  номер,  то  эта макропеременная часто
     используется для  создания  уникальных  имен  временных
     файлов. Например:
                ps a >>/tmp/ps$$
                . . .
                rm /tmp/ps$$
!    Номер последнего процесса, запущенного в качестве фоно-
     вого.
-    Текущие ключи (установленные режимы) интерпретатора  sh
     типа -x и -v.
     Перечисленные далее макропеременные языка SHELL,  имеют
для системы особый смысл и не должны использоваться в других
целях:
MAIL  Перед тем как выдать  первую  подсказку  интерпретатор
      просматривает  файл,  имя  которого является значением
      этой макропеременной. Если  данный  файл  изменялся  с
      момента  последнего просмотра, будет выданно сообщение
      you have mail (вам пришла почта).  Значение этой  мак-
      ропеременной  обычно  устанавливается  при  выполнении
      файла .profile.
      Например:
                     MAIL=/usr/mail/nata
HOME  Имя справочника для команды cd без параметров.   Поиск
      файлов,  имена  которых  не  начинаются  с  символа /,
                           - 10 -
      осуществляется в текущем справочникe.  Для смены теку-
      щего  справочника  применяется  команда cd.  Например,
      команда:
                      cd /usr/nata/bin
      назначает текущим справочник /usr/nata/bin.  Команда:
                          cat show
      выводит на терминал содержимое файла show из  справоч-
      ника  /usr/nata/bin. Команда cd без параметров эквива-
      лентна команде:
                          cd $HOME
      значение этой макропеременной также  обычно  определя-
      ется в файле .profile.
PATH  Эта макропеременная  определяет  список  справочников,
      просматриваемых  при  поиске  команды.   Если значение
      макропеременной PATH  не  определено,  то  принимается
      следующий порядок просмотра: текущий справочник, спра-
      вочник /bin и справочник /usr/bin.  При явном  задании
      значения  макропеременной PATH имена справочников раз-
      деляются символом :.  Например:
                   PATH= :/usr/nata/bin:/bin:/usr/bin
      означает, что просмотр справочников  будет  вестись  в
      следующем  порядке: текущий справочник (пустая позиция
      перед  первым  символом  :),  /usr/nata/bin,  /bin   и
      /usr/bin. Таким образом, конкретные пользователи могут
      иметь свои личные  команды,  доступные  независимо  от
      того,  какой  справочник  является  текущим.  Если имя
      команды начинается с символа /  (т.е.  заданно  полное
      имя  исполняемого  файла),  то поиск в справочниках не
      ведется.  В этом случае делается  всего  одна  попытка
      выполнить указанную команду.
PS1   Подсказка интерпретатора (по  умолчанию  для  обычного
      пользователя - $).
PS2   Подсказка интерпретатора, означающая продолжение ввода
      (по умолчанию >>).
IFS   Множество символов-разделителей, интерпретируемых  как
      пробелы.
                           - 11 -
TERM  Тип связанного с процессом терминала.
2.8.  Выдача подсказок
     При работе с терминала, когда интерпретатор готов  при-
нять  следующую  команду, по умолчанию выдается подсказка $.
Она может быть изменена командой:
                          PS1=ввод:
после выполнения которой подсказка будет  иметь  вид  строки
ввод:.
     Если введенная строка содержит  синтаксически  незавер-
шенную  конструкцию,  для  продолжения  ввода  интерпретатор
выдаeт в качестве подсказки символ >>.  Подсказка, обозначаю-
щая продолжение ввода, может быть изменена с помощью команды
присваивания нового значения макропеременной PS2.
Например, команда:
                      PS2=Продолжение:
установит в качестве подсказки строку Продолжение:.
2.9.  Составные команды
     Существует два способа объединения нескольких команд  в
одну составную команду:
                     { список_команд; }
                      (список_команд)
В первом случае указанный список_команд просто  выполняется.
Во  втором - заданный список_команд тоже выполняется, но уже
как отдельный процесс.
     Например, конструкция:
                       (cd x; rm junk)
выполняет команду rm junk в справочнике x, не изменяя  теку-
щего справочника, а команды
                     { cd x; rm junk; }
дают тот же самый  результат,  но  справочник  x  становится
текущим.
2.10.  Встроенные команды
     Как правило, при выполнении  какой-либо команды интерп-
ретатор порождает отдельный процесс.  Однако, существует ряд
                           - 12 -
функций, выполнение которых в качестве  отдельного  процесса
либо  неэффективно, либо невозможно.  Прежде всего это отно-
сится к командам, выполнение которых  зависит  от  состояния
локальных переменных интерпретатора.  Команды, выполняющиеся
непосредственно интерпретатором (без  порождения  процесса),
называются  встроенными  командами  языка.   С  точки зрения
пользователя встроенные команды практически не отличаются по
своим  свойствам от остальных команд системы, за исключением
того, что для них обычно нельзя  переопределить  стандартные
файлы ввода/вывода.
     Далее приводится список  встроенных  команд  с  кратким
описанием выполняемых функций:
:    Эта команда  не  выполняет  никаких  действий,  ее  код
     завершения  равен нулю. Тем не менее производится подс-
     тановка значений макропеременных.
. файл
     Считывает и выполняет команды из файла.  Для нахождения
     справочника,  содержащего файл, используется макропере-
     менная PATH.
cd [справочник]
     Объявить указанный справочник текущим.   Если  параметр
     не  задан,  в  качестве  имени справочника используется
     значение макропеременной HOME.   Синонимом  команды  cd
     является команда chdir.
eval [команда ...]
     Выполняются все  макроподстановки,  после  чего,  слово
     eval  отбрасывается  и остальные символы обрабатываются
     как обычная командная строка.
exec [команда ...]
     Текущий процесс замещается процессом выполненя  указан-
     ной  команды.   Допускается переопределение стандартных
     файлов ввода/вывода.
exit [N]
     Прерывание выполнение  текущего  процесса.   Сообщается
     код  завершения  N.  Если  параметр  N  отсутствует, то
     используется  код  завершения   последней   выполненной
     команды.
export [имя ...]
     Перечисленные макропеременные автоматически вводятся  в
     среду порождаемых процессов.  Если параметры не заданы,
     выдается список экспортируемых макропеременных.
login [параметр ...]
     Регистрация пользователя в системе без создания  нового
     процесса (эквивалент команды exec login параметр ...).
                           - 13 -
newgrp [параметр ...]
     Замена  текущего  идентификатора  группы  пользователей
     (эквивалент команды "exec newgrp параметр ...").
read имя ...
     Из стандартного файла ввода  считывается  одна  строка.
     Затем  макропеременным имя ... последовательно присваи-
     ваются значения слов,  составляющих  эту  строку.   Код
     завершения  команды  равен  нулю во всех случаях, кроме
     тех, когда список параметров длиннее, чем число слов  в
     считанной строке.
readonly [имя ...]
     Запрещается переопреление  перечисленных  макроперемен-
     ных.   Если  параметры  не заданы, выдается список всех
     макропеременных, определенных как readonly (только  для
     чтения).
set [-ekntuvx [параметр ...]]
     Устанавливает режимы работы интерпретатора языка SHELL.
     Могут задаваться следующие ключи:
      -e  В неинтерактивном режиме вызывает немедленное пре-
          рывание процесса при обнаружении ошибки в выполне-
          нии команды.
      -k  Все определенные макропеременные экспортируются  в
          среду запускаемых процессов.
      -n  Производит только синтаксический контроль команд.
      -t  Прерывает  выполнение  процесса  после  того,  как
          будет считана и выполнена одна команда.
      -u  Устанавливает режим диагностики ошибки при попытке
          использовать неопределенные макропеременные.
      -v  Устанавливает режим печати вводимых строк.
      -x  Распечатывает  команды  и  их  параметры  по  мере
          выполнения.
      -   Отменяет ключи -v и -x.
     Установленные ключи  содержатся  в  макропеременной  -.
     Остальным параметрам команды set присваиваются значения
     позиционных параметров "1, 2, ...".  Если параметры  не
     заданы,  печатается  список значений всех макроперемен-
     ных.
shift
     Позиционным параметрам "2, 3, ..." присваиваются значе-
     ния параметров "1, 2, ..." соответственно.
                           - 14 -
times
     Выдается время, затраченное пользователем и системой на
     выполнение процесса.
trap [команда] [N ...]
     При получении перечисленных сигналов  выполняется  ука-
     занная команда.
umask [ddd]
     При формировании дескрипторов вновь создаваемых  файлов
     признаки разрешение чтения и разрешение записи устанав-
     ливаются согласно маске ddd.  Цифра '0' в соответствую-
     щем  разряде  означает установку признака. Формат маски
     совпадает с форматом дескриптора, задаваемым в  команде
     chmod.   Рассматриваются  только  те  позиции,  которые
     определяют разрешение чтения записи rw.  Если  параметр
     отсутствует,  выдается  текущее значение маски.  Напри-
     мер, команда umask 000  установит  режим,  при  котором
     всем  порождаемым файлам будет устанавливаться признаки
     разрешения чтения записи для всех пользователей.
wait [N]
     Ожидает окончания выполнения процесса с номером  (N)  и
     присваивает его код завершения макропеременной ?.
3.  КОМАНДНЫЕ ФАЙЛЫ
     Последовательность  команд  можно  записать  в  файл  и
выполнить, указав имя этого файла.  Таким образом, обеспечи-
вается возможность создания достаточно сложных  программ  на
языке  SHELL.  В языке существуют операторы управления (опе-
ратор цикла, условного перехода, выбора) и аппарат  передачи
параметров.
     Выполнение командного файла может осуществляться  двумя
способами.   В первом случае, указывается имя интерпретатора
языка SHELL - sh, режимы его работы, имя и параметры команд-
ного  файла.  Во втором - только имя файла и параметры (ана-
логично вызову любой команды системы).  При этом предполага-
ется, что файл имеет признак "выполнение разрешено".
     Результат работы  команды  не  зависит  от  способа  ее
выполнения,  поэтому, как правило, используется второй вари-
ант.  Запуск команды с явным указанием имени  интерпретатора
часто  применяется для отладки командных файлов, когда необ-
ходимо задавать различные режимы работы sh.
     Например, команда:
                     sh file [параметры]
вызывает интерпретатор для выполнения команд из файла  file.
Если  в  командной  строке  заданы параметры, они передаются
                           - 15 -
порождаемому процессу в виде значений  макропеременных  "1",
"2" и т.д.
     Например, если файл wg содержит строку:
                        who | grep $1
то команда
                         sh wg nata
выполняет действие эквивалентное
                       who | grep nata
     Признак того, что файл можно выполнять обычно  устанав-
ливает  компонента, создавшая данный файл (например компиля-
тор). Командные файлы, как  правило,  создаются  непосредст-
венно пользователем и данного признака не содержат.  Поэтому
возникает необходимость установить для файла признак  выпол-
нение разрешено. Для этого можно использовать команду chmod.
Например, в результате работы команды:
                         chmod +х wg
файл wg получает признак выполнение разрешено.
     Обработка параметров при запуске команды выполняется по
следующим правилам:
-    Обрабатываются все имеющиеся метасимволы языка.
-    Командная строка разбивается на слова -  последователь-
     ности  символов, не содержащие символов-разделителей, к
     которым относятся пробел, символ начала строки  и  знак
     табуляции.   Если  в качестве параметра требуется пере-
     дать текст, который  содержит  пробелы,  он  берется  в
     кавычки.
-    Выделенные слова последовательно присваиваются макропе-
     ременным с именами "0", "1", "2", и т.д.
-    В качестве значения макропеременной "#" устанавливается
     число параметров.
-    Значения  всех  параметров  (за  исключением  нулевого)
     присваиваются  макропеременой  *.   Т.е.  макровызов $*
     будет заменяться на строку,  содержащую  значения  всех
     параметров.
     Например, если командный файл show имеет вид:
                           - 16 -
           echo '
           Команда  $0 =' $0 '
           Значение $1 =' $1 '
           Значение $2 =' $2 '
           Число параметров =' $# '
           Значение $* =' $*
то в результате выполнения команды:
                     show первый второй
будет получен следующий текст:
           Команда  $0 = show
           Значение $1 = первый
           Значение $2 = второй
           Число параметров = 2
           Значение $* = первый второй
3.1.  Комментарии
В командной строке языка SHELL можно использовать  коммента-
рий,  который служит для улучшения читаемости командных фай-
лов.  Комментарий должен начинаться символом  #  и  распола-
гаться в конце командной строки.  Так как часть строки, сле-
дующая за символом #, не рассматривается интерпретатором,  в
ней могут встречаться любые символы.
     Например:
     #   Это   пример   комментария
     ls    #  Будет выполнена команда
           #  ls (это тоже комментарий)
Следует помнить, что если # является первым  символом файла,
ему  придается  особый  смысл - это признак того, что должен
использоваться интерпретатор языка csh.
3.2.  Команда test
     Команда test, хотя и  не  является  конструкцией  языка
SHELL,  необходима при создании командных файлов.  В резуль-
тате выполнения команды  осуществляется  проверка  заданного
условия  и  сообщается  код  ее  завершения,  который  может
использоваться в операторах условного перехода и цикла.
     Например, код завершения команды
                        test -f file
равен нулю, если файл file существует, и не равен нулю  -  в
противном случае.
                           - 17 -
     Основные возможности команды можно проиллюстрировать на
следующих примерах:
test s
     истинно, если аргумент s не является пустой строкой;
test -f file
     истинно, если файл существует;
test -r file
     истинно, если файл можно читать;
test -w file
     истинно, если в файл можно писать;
test -d file
     истинно, если файл является справочником.
3.3.  Оператор for
     В языке SHELL существует возможность  последовательного
повторения  какой-либо  группы  команд  для каждого элемента
указанного списка.   Для  этой  цели  используется  оператор
цикла for, который имеет следующий формат:
       for имя [in слово1 слово2 ...]
          do список_команд
          done
где список_команд - это последовательность  одной  или  нес-
кольких простых команд, разделенных символами ; или перечис-
ленных на разных строках.  Зарезервированные слова do и done
распознаются только в том случае, если они следуют за симво-
лом новой строки или точки с запятой. Имя -  это  макропере-
менная   языка   SHELL,   которая   в   процессе  выполнения
списка_команд  последовательно  принимает  значения   слово1
слово2  ....  Если конструкция in слово1 слово2 ... отсутст-
вует, то цикл выполняется один  раз  для  каждого  заданного
параметра  (т.е.  по  умолчанию  предполагается  in  $*).  В
качестве примера можно привести команду tel,  которая  прос-
матривает файл /usr/lib/pfone, содержащий строки вида:
             ...
             Иванов И.И.   224 01 01
             Петров П.П.   123 07 07
             Сизов  В.И.   224 44 94
             ...
     Текст процедуры tel:
          for i
          do grep $i usr/lib/pfone; done
                           - 18 -
     В результате выполнения команды:
                         tel Петров
будут напечатаны те  строки  файла  /usr/lib/pfone,  которые
содержат последовательность символов Петров, а команда:
                      tel Иванов Петров
напечатает  сначала  строки,  содержащие  последовательность
символов Иванов, а затем те строки, которые содержат символы
Петров.
     Еще одним примером  использования  цикла  for  является
командный файл create:
                     for i do >> $i; done
Результатом выполнения команды
                      create alpha beta
является создание двух пустых файлов alpha и beta.
3.4.  Оператор case
     Рассмотрим  в  качестве  примера  командный  файл  add,
содержащий следующий текст:
     case $# in
          1) cat >>>> $1;;
          2) cat >>>> $2 << $1;;
          *) echo 'Формат: add [откуда] куда';;
     esac
При вызове команды с одним аргументом, например:
                          add file
параметр $# получает значение '1', и  команда  cat  копирует
информацию  из  стандартного файла ввода в конец файла file.
Команда:
                       add file1 file2
допишет содержимое файла file1 в конец  файла  file2.   Если
число  параметров,  передаваемых команде add, отлично от 1 и
от 2, то печатается сообщение "Формат: add куда [откуда]".
     Формат оператора case:
                           - 19 -
    case слово in
     [образец[|образец] ...) список_команд;;]
     ...
     [образец[|образец] ...) список_команд[;;]]
    esac
     Интерпретатор последовательно сравнивает слово с каждым
из указанных образцов. При обнаружении соответствия выполня-
ется записанный при образце список_команд, после чего, обра-
ботка  оператора  завершается.   Символ * представляет собой
образец,  который  соответствует   любой   строке.    Каждый
список_команд  (за исключением последнего) необходимо завер-
шать символами ;;.
     Первое же совпадение слова с образцом полностью опреде-
ляет  множество  выполняемых  команд.  В  следующем  примере
команды, указанные за вторым символом  *,  не  будут  выпол-
няться никогда:
         case $# in
              *) ...;;
              *) ...;;
         esac
     Оператор case часто используется для проверки  коррект-
ности параметров. Это можно проиллюстрировть следующим фраг-
ментом команды cc:
    for i
     do case $i in
       -[ocs]) ...;;
           -*) echo 'неизвестный ключ $i';;
          *.c) lib/c0 $i ...;;
            *) echo 'неизвестный параметр $i';;
        esac
    done
     Если  условием  выполнения  какого-либо   списка_команд
является  группа  образцов, то при их перечислении в команде
case в качестве разделителя  используется  символ  |.   Так,
оператор:
         case $i in
            -х) echo $i
            -y) echo $i
         esac
может быть записан слудующим образом:
                           - 20 -
         case $i in
            -х|-y) echo $i
         esac
     При поиске соответствующего образца применимы  основные
соглашения об отмене специального значения метасимволов, так
образец в конструкции:
         case $i in
            ?) ...
будет соответствовать символу ?.
3.5.  Операторы while и until
     Оператор while  предназначен  для  организации  циклов,
выполнение  которых производится до тех пор, пока код завер-
шения указанного списка команд равен нулю.
     Общая форма оператора while:
           while список_команд_1
           [do список_команд_2]
           done
     В каждом цикле выполняются команды из  списка_команд_1.
Оператор  while  проверяет  код завершения последней простой
команды из этого списка: если  он  равен  нулю,  выполняется
список_команд_2 и цикл повторяется, иначе - выполнение цикла
завершается.
     Например, при выполнения следующих операторов:
           while test $1
           do ...
              shift
           done
и
           for i
           do ...
           done
будет получен одинаковый результат.
     Оператор shift  переименовывает  позиционные  параметры
"2, 3, ..." в параметры "1, 2, ..." соответственно; значение
параметра "1" теряется.
                           - 21 -
     Другим способом организации цикла является  использова-
ние оператора until:
           until список_команд_1
           [do список_команд_2]
           done
В отличие от while цикл until будет выполняться до тех  пор,
пока  код  завершения  последней  команды списка_команд_1 не
будет иметь нулевое значение.
3.6.  Операторы break и continue
     Операторы break и continue используются в  конструкциях
for, while и until.
     Оператор break прерывает работу цикла, в теле  которого
он  выполняется.   В  качестве  примера можно привести прог-
рамму, которая выдает значения своих параметров, расположен-
ных до символа %:
    for i
    do
    case $i in
      %) break;;
      *) echo $i;;
    esac
    done
     Оператор continue осуществляет переход к следующей ите-
рации цикла.  Для примера рассмотрим командный файл, который
выводит только те параметры, которые начинаются с буквы:
     for i
     do
       case $i in
            [А-Яа-я]*) echo $i;;
            [A-Za-z]*) echo $i;;
                    *) continue;;
       esac
     done
3.7.  Оператор if
     Условный оператор вида:
            if  список_команд_1
            then список_команд_2
            [else список_команд_3]
            fi
                           - 22 -
проверяет   код   завершения   последней   простой   команды
списка_команд_1:    если    он   равен   нулю,   выполняется
список_команд_2, иначе - список_команд_3.
     Команда if может использоваться  совместно  с  командой
test, например, для проверки существования файла:
           if test -f $1
           then  echo "ФАЙЛ $1 СУЩЕСТВУЕТ"
           else  echo "ФАЙЛ $1 НЕ СУЩЕСТВУЕТ"
           fi
     При многократном повторении условного оператора, напри-
мер:
            if ...
            then    ...