Командный язык 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

В данном случае, если файл не существует, он также предвари-
тельно создается системой.

Аналогичные возможности предоставляются и для переопре-
деления стандартного файла ввода (по умолчанию данные вво-
дятся с терминала). Для этой цели используется символ <&lt;.
Например, команда:

wc <&lt; filels

выдает количество строк файла filels.

Далее перечислены основные конструкции, используемые
для задания файлов ввода/вывода.

>&gt; файл
В качестве стандартного файла вывода используется файл,
который перезаписывается заново или создается, если
ранее не существовал.

>&gt;>&gt; файл
Поступающая информация добавляется к содержимому файла.
Если файл не существует, он предварительно создается.

<&lt; файл
В качестве стандартного файла ввода используется файл.

<&lt;<&lt; файл
Чтение локального файла (см. раздел 4.8). Последующие
строки передаются команде в качестве информации стан-
дартного файла ввода до тех пор, пока не встретится
строка, содержащая последовательность символов файл.
Если специальное значение первого символа строки файл
отменено, выполняются подстановки значений макропере-
менных и результатов выполнения команд.

>&gt;& цифра
Информация, записываемая в файл с дескриптором цифра,


- 7 -










передается в стандартный файл вывода.

<&lt;& цифра
Стандартным файлом ввода является файл с дескриптором
цифра.

<&lt;&- Файл стандартного ввода закрыт на запись.

>&gt;&- Файл стандартного вывода закрыт на чтение.

2.6. Связь процессов, конвейеры и фильтры

Информация, выдаваемая в стандартный файл вывода одной
командой, может непосредственно передаваться другой команде
в качестве содержимого стандартного файла ввода. Например,
в результате работы команд:

ls | wc

будет выдано общее число символов в именах текущего справоч-
ника. Составная команда, образованная с помощью операции
"|", называется конвейером. В данном случае она выполняет
действие эквивалентное командам:

ls >&gt; filels
wc <&lt; 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 >&gt;/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 Подсказка интерпретатора, означающая продолжение ввода
(по умолчанию >&gt;).

IFS Множество символов-разделителей, интерпретируемых как
пробелы.



- 11 -










TERM Тип связанного с процессом терминала.

2.8. Выдача подсказок

При работе с терминала, когда интерпретатор готов при-
нять следующую команду, по умолчанию выдается подсказка $.
Она может быть изменена командой:

PS1=ввод:

после выполнения которой подсказка будет иметь вид строки
ввод:.

Если введенная строка содержит синтаксически незавер-
шенную конструкцию, для продолжения ввода интерпретатор
выдаeт в качестве подсказки символ >&gt;. Подсказка, обозначаю-
щая продолжение ввода, может быть изменена с помощью команды
присваивания нового значения макропеременной 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 >&gt; $i; done

Результатом выполнения команды

create alpha beta

является создание двух пустых файлов alpha и beta.

3.4. Оператор case

Рассмотрим в качестве примера командный файл add,
содержащий следующий текст:

case $# in
1) cat >&gt;>&gt; $1;;
2) cat >&gt;>&gt; $2 <&lt; $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 ...
else ...
if ...
then ...
else if ...
...
fi
fi
fi

можно использовать сокращенную запись:

if ...
then ...
elif ...
then ...
elif ...
...
fi


Конструкция

if команда1
then команда2
fi

может быть записана в виде:

команда1 && команда2

В конструкции

команда1 || команда2

команда2 выполняется только в том случае, если команда1 не


- 23 -










была выполнена успешно. Кодом завершения обеих конструкций
является код завершения последней простой команды.

3.8. Локальный файл

В процедуре tel, рассмотренной в ранее, исходные данные
для команды grep берутся из файла /usr/lib/pfone. Обрабаты-
ваемые данные могут непосредственно включаться в командный
файл. Для этого они оформляются в виде локального файла. В
следующем примере:

for i
do grep $i <&lt;<&lt;!
...
Иванов И.И. 224 01 01
Петров П.П. 123 07 07
Сизов В.И. 224 44 94
...
!
done

строки, заключенные между символами <&lt;<&lt;! и !, передаются
команде grep в качестве данных стандартного файла ввода.
Строка-ограничитель ! выбрана здесь произвольно: главное,
чтобы она совпадала с последовательностью символов, стоящей
за знаками <&lt;<&lt;.

Если следующая за <&lt;<&lt; последовательность символов не
начинается со знака \, то прежде чем локальный файл станет
доступным командe, в нем выполняются все подстановки пара-
метров.

Например, пусть файл edg содержит строки вида:

ed $3 <&lt;<&lt; %
g/$1/s//$2/g
w
%

при вызове:

edg строка1 строка2 file

будет достигнут результат, который можно получить при выпол-
нении следующей последовательности команд:

ed file <&lt;<&lt; %
g/строка1/s//строка2/g
w
%





- 24 -










3.9. Отладка командных файлов

В SHELL используются два механизма отладки командных
файлов. Первый из них:

set -v

выводит строки командного файла по мере их чтения. Этот
режим применяется при поиске синтаксических ошибок. Для его
использования не требуется производить модификацию команд-
ного файла, например:

sh -v proc...

здесь proc - имя командного файла. Ключ -v может использо-
ваться вместе с ключом -n, предотвращающим выполнение следу-
ющих за ним команд (команда set -n блокирует терминал до тех
пор, пока не вводится признак конца файла EOF).

Команда

set -х

выводит команды по мере их выполнения. Для отмены ключей -x
и -v можно воспользоваться командой

set -

а для установки - присвоить соответствующее значение макро-
переменной -.

4. ПАРАМЕТРЫ И ОБЛАСТЬ ДЕЙСТВИЯ МАКРОПЕРЕМЕННЫХ

Макропеременные, определенные в одном процессе, при
отсутствии явных указаний не доступны в других процессах.
Для того чтобы обеспечить возможность передачи порождаемому
процессу какой-либо информации, в языке предусмотренны
средства, которые позволяют:

- передавать команде параметры;

- экспортировать определения макропеременных из среды
текущего процесса в среду порождаемого;

- определять макропеременные и передавать их определения
в среду порождаемого процесса без изменения среды теку-
щего.

Так, в следующем примере:

USER=nata команда

перед выполнением файла команда макропеременная USER


- 25 -










принимает значение nata. При использовании флага -k опера-
торы вида имя=значение могут вставляться в любое место
списка параметров. Такие имена называются ключевыми пара-
метрами. Значения параметров присваиваются макропеременным
с именами "1", "2", ... N (поскольку число в имени макропе-
ременной указывает позицию параметра в командной строке,
такие параметры называются позиционными).

Для того чтобы присвоить значения позиционным парамет-
рам непосредственно из командного файла используется команда
set. Так, в следующем примере

set *

параметру "1" будет присвоено значение имени первого файла
текущего справочника, параметру "2" - имя второго файла и
т.д.

При выполнении команд интерпретатор производит следую-
щие действия:

- Подстановка значений параметров, например:

$user


- Подстановка результатов выполнения команд, например:

`pwd`


В тех случаях, когда в строке требуется выполнить нес-
колько вложенных макроподстановок, используется встро-
енная команда eval. Например, если значением макропере-
менной X является строка $y, а макропеременной y - pqr,
то команда

eval echo $X


выдаст строку pqr.

Результаты выполнения команды eval являются входными
данными для SHELL, который считывает их и выполняет в
качестве команд. Таким образом, конструкция

wg='eval who | grep'
$wg fred


эквивалентна команде

who | grep fred


- 26 -










В этом примере без команды eval не обойтись, так как
метасимвол | при последующей макроподстановке не
интерпретируется.

- Интерпретация символов-разделителей.

Символы, полученные в результате выполнения указанных
выше подстановок, разбиваются затем на слова, не содер-
жащие разделителей. Пробелами здесь названы символы,
являющиеся разделителями слов. Список этих символов
содержится в макропеременной IFS; по умолчанию к ним
относятся пробел, символы горизонтальной табуляции и
новой строки. Если специальное значение пробела отме-
нить одним из существующих способов, то он будет
интерпретироваться соответствующей последовательностью
символов. Например, командa

echo ''


будет выдавать пустую строку, поскольку она является
первым аргументом команды echo, в то время как вызов
команды

echo $null


будет осуществляться без аргументов, если значение мак-
ропеременной null не определено или определено как
пустая строка.

- Задание имен файлов.

На этом этапе в словах осуществляется поиск символов *,
? и [...] (являющихся образцами имен файлов) и замена
каждого слова списком имен файлов, расположенных в
алфавитном порядке. Каждое имя файла рассматривается
как отдельный параметр.

Над словами, содержащимися в операторе цикла for,
выполняются все перечисленные действия. В опрераторе case
выполняется только подстановка значения параметра, указывае-
мого после ключевого слова case.

Как отмечалось, в языке SHELL существуют три механизма
экранирования метасимволов (с использованием символов \,
'...' и "..."). Внутри строк, заключенных в двойные кавычки,
выполняются только подстановки значений параметров и резуль-
татов выполнения команд. Далее перечислены символы, которые
при заключении их в двойные кавычки не теряют своего специ-
ального значения:




- 27 -










$ подстановка значений параметров;

` подстановка результатов выполнения команд;

ограничитель экранируемой строки;

\ экранирует метасимволы $, `, " и \.

Например, в команде

echo $х

значение макропеременной x является единственным аргументом.
Аналогично, в команде

echo $*

все позиционные параметры рассматриваются в качестве единст-
венного аргумента; эта команда эквивалентна следующей:

echo $1 $2 ...

Макровызовы $@ и $* идентичны, за исключением способов их
экранирования. Команды

echo $@

и

echo $1 $2 ...

эквивалентны. В результате их выполнения будут выдаваться
значения всех позиционных параметров.

На рисунке 1 показано воздействие механизмов экраниро-
вания на каждый из метасимволов языка SHELL.

Метасимволы

$ * ` " '
-|------------------|
' | - - - - - t |
` | + - - t - - |
" | + + - + t - |
_|__________________|

+ метасимвол экранируется;
- метасимвол не экранируется;
t ограничитель экранируемой строки.

Рис.1




- 28 -










4.1. Передача параметров

Как позиционные, так и ключевые параметры могут быть
получены в процессе вызова командного файла. Ключевые пара-
метры, кроме того, можно сделать доступными еще одним спосо-
бом: нужно явно указать, чт

Подякувати Помилка?

Дочати пiзнiше / подiлитися