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

"И Н Т Е Р Ф Е Й С"













Диалоговая Единая Мобильная

Операционная Система

Демос/P 2.1










Командный язык

C-shell














Москва

1988















АННОТАЦИЯ

Описывается интерпретатор командного языка C-shell.
Описаны элементы языка, оператор И структура программ на C-
shell, а также встроенные возможности.





























































1. Командный язык C-shell

Взаимодействие пользователя и операционной системы осу-
ществляет интерпретатор команд - программа связи между поль-
зователем и операционной системой. Основная функция интерп-
ретатора - создание процессов, выполняющих задание (одну и
более команд) пользователя, сформулированное в виде предло-
жений (командных строк) некоторого формализованного языка -
языка взаимодействия с операционной системой. Такой язык
называют командным.

Командный язык позволяет выполнять различные задания
пользователя и управлять работой операционной системы.
Пользователи ДЕМОС используют несколько стандартных
командных языков, однако авторы решили ограничиться подроб-
ным описанием наиболее развитого и популярного из них -
командного языка C-shell [].

C-shell - язык управления заданиями со свойствами уни-
версального языка программирования. Совмещение свойств
языка управления заданиями и универсального языка программи-
рования делает C-shell во многом схожим как с универсальными
алгоритмическими языками, так и с наиболее развитыми команд-
ными языками. Это отражено в самом названии языка C-shell:
C - от имени универсального языка программирования Си и
shell - язык взаимодействия пользователя с системой (бук-
вально "оболочка"). В качестве программы связи между поль-
зователем и операционной системой используется интерпретатор
csh, предназначенный для разбора и выполнения предложений на
языке C-shell. Интерпретатор csh работает в двух режимах:
интерактивном и неинтерактивном.

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

В неинтерактивном режиме выполняется командный файл
(программа на языке C-shell), в котором содержатся командные
строки и управляющие конструкции (операторы языка C-shell).

1.1. Лексическая структура языка C-shell

Предложение на языке C-shell формулируется в виде
командной строки, которая может содержать команду ДЕМОС
(например, /bin/cat), внутреннюю команду интерпретатора csh
(например, cd), оператор языка программирования C-shell
(например, оператор цикла while).




- 3 -










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

Слово - это завершенная конструкция, которую распознает
интерпретатор csh. Разделителями слов в командной строке
могут быть пробелы, табуляции и перечисленные ниже символы:

; ( ) <&lt; >&gt; & |

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

! # $ % : * , ?

[ ] { } @ ~ . ^

Символ \ отменяет специальное значение части указанных мета-
символов.

После разбора командной строки и подстановки значений
переменных слово может "превратиться" в строку или остаться
словом, например именем файла. Интерпретатор csh позволяет
оперировать строками, полученными в результате интерпретации
слов в командной строке, осуществлять различные преобразова-
ния:

"строка" 'строка' `строка`

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

Строка, заключенная в двойные кавычки, интерпретируется
csh, в ней используются специальные значения метасимволов и
выполняются подстановки значений переменных.


- 4 -










Строка, заключенная в одинарные правые кавычки (апост-
рофы), не интерпретируется. Все метасимволы и их последова-
тельности теряют свое специальное значение. В некоторых слу-
чаях символы

? . * ! ~

сохраняют свое специальное значение и интерпретируются в
такой строке.

Строка, заключенная в левые одинарные кавычки, интерп-
ретируется как командная строка. Эта командная строка выпол-
няется и заменяется результатом ее выполнения.

Ниже перечислены лексемы - имена операторов языка C-
shell и внутренних команд интерпретатора csh:

alias endsw logout suspend
alloc eval newgrp switch
bg exec nice time
break exit nohup umask
breaksw fg notify unalias
case foreach onintr unhash
cd glob popd unlimit
chdir goto pushd unset
continue hashstat rehash unsetenv
default history repeat wait
dirs if set while
echo jobs setenv
else kill shift
end limit source
endif login stop

Имена предопределенных внутренних переменных интерпретатора
csh:

argv history nonomatch status
cdpath home notify time
checktime ignoreeof path verbose
child mail prompt
cwd noclobber savehist
echo noglob shell

В некоторых случаях одна лексема определяет и имя перемен-
ной, и имя внутренней команды интерпретатора csh. Тип лек-
семы определяется по контексту. Например, команда time хро-
нометрирует выполнение простой командной строки, а предопре-
деленная переменная с именем time используется для указания
интерпретатору, о каких заданиях выводить результаты хроно-
метрирования.





- 5 -










1.2. Форматы командных строк, перемещения по файловой сис-
теме

Интерпретатор csh получает задание в виде командной
строки или командного файла. Последовательность символов от
приглашения до символа перевод строки (\n) является команд-
ной строкой. Командная строка может включать простую
команду, последовательность команд, группу команд, конвейер.
Задание может выполняться в синхронном или асинхронном режи-
мах. В результате разбора командной строки интерпретатор csh
запускает на выполнение один или более процессов.

Командой мы называем любой объектный или командный
файл, который может быть выполнен под управлением ДЕМОС.
Например, команда

pr -2 -w39 -l24 -t file

выведет на экран дисплея содержимое файла file в две
колонки, строками по 39 символов и страницами по 24 строки.
Команда pr (объектный выполняемый файл которой размещен в
каталоге /bin) выполняет собственно форматирование перед
выводом файла. Режимы работы команды pr задаются ключами, им
в командной строке предшествуют знаки минус или плюс. Знак
используется, чтобы можно было ключ отличить от имени файла.
Кроме того, в командной строке указано имя файла file, кото-
рый необходимо обработать команде pr. Прежде чем команда pr
начнет выполняться, интерпретатор выполнит следующую работу:

проанализирует ошибки в командной строке;


найдет выполняемый файл в одном из каталогов (в данном
случае - в /bin);


передаст его на выполнение операционной системе вместе
с ключами и именем файла.


По завершению выполнения командной строки интерпретатор
csh напечатает приглашение (форма приглашения устанавлива-
ется пользователем). Это значит, что можно вводить следую-
щую командную строку. Командная строка объединяет несколько
слов, разделенных пробелами, первое из которых - собственное
имя команды.

Часто бывает необходимо выполнить последовательность
команд, в этом случае можно использовать символ ;, например:

cat <&lt; file ; pr -2 -w39 -l24 -t file

Эта командная строка приводит к выполнению двух команд:


- 6 -










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

Для управления последовательностями команд допускается
использование логических связок && и ||, например:

cat <&lt; file && pr -2 -w39 -l24 -t file

В этом случае вторая команда выполнится, если успешно выпол-
нится первая, т.е. если file существует и его разрешено
читать.

cat <&lt; file1 || pr -2 -w79 -l24 -t file

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

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

ls -l; ( cat <&lt; f1 && cat <&lt; f2 ) && date

Сначала выдается листинг рабочего каталога, затем выполня-
ется группа команд в скобках и, если оба файла существуют и
разрешено их чтение, выполняется команда date. Для безоши-
бочного разбора командной строки интерпретатором csh требу-
ется, чтобы около скобок находились либо ;, либо &&, либо |,
либо ||, либо метасимволы перенаправления ввода-вывода.

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

cat -n <&lt; file | pr -2 -w39 -l24 -t

Команда cat проставляет номера строк в file (ключ n), и ее
вывод передается команде pr для форматирования. Результат
выводится на экран дисплея.

sort file | cat -n | pr -2 -w39 -l24 >&gt;>&gt; file2

Команда sort сортирует файл; cat - проставляет номера строк;
pr - форматирует вывод и дописывает его в file2. Команды в


- 7 -










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

( cat <&lt; f1 && date ) && ( cat -n <&lt; f1 | sort ); date

Если имеется файл f1, он выводится на дисплей, затем выво-
дится дата, а команда cat, пронумеровав строки, направляет
файл на сортировку. На экран выводятся результат сортировки
и дата. Если f1 отсутствует или его нельзя читать, то выво-
дится только дата.

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

cat -n <&lt; f1 | pr -2 -w39 -l24 -t >&gt; f2 &

Команда cat выводит строки с номерами, команда pr формати-
рует их, вывод направляется в f2.

Часто при наборе командной строки возникают ошибки,
которые можно исправить простыми средствами.

Клавиша ЗБ (DEL) дисплея используется для удаления сим-
вола, около которого находится курсор.

Символ СУ/W (CTRL/W) позволяет удалить последнее слово
командной строки.

Символ СУ/U (CTRL/U) позволяет удалить всю строку.

Перемещения по файловой системе выполняются командами
cd, popd и pushd. Интерпретатор хранит путь от регистраци-
онного к рабочему каталогу (его имя хранится в предопреде-
ленной переменной cwd), а также поддерживает стек каталогов,
содержимое которого выводится по команде dirs. Команды
pushd и popd используются для переходов по дереву каталогов
файловой системы и модификации содержимого стека каталогов.
Команда cd не меняет содержимого стека каталогов. Элементы
стека нумеруются от 1, начиная от вершины стека.

Команда popd без аргументов равносильна команде cd
имя_номер_2 стека имен каталогов, т.е. осуществляется пере-
ход в новый каталог, имя которого определяется автомати-
чески. Имя_номер_1 из стека имен каталогов удаляется,
остальные элементы стека сохраняются с новыми номерами.
Команда popd +число удаляет имя_номер_(1+число) из стека,
остальные элементы стека сохраняются с новыми номерами. При
этом переход в другой каталог не осуществляется.


- 8 -










Команда pushd меняет порядок имен в стеке имен катало-
гов и увеличивает их число на 1. Команда pushd без аргумен-
тов равносильна команде cd имя_номер_2 стека. При этом
имя_с_номером_2 ставится в вершину, а имя_с_номером_1 - на
его место в стеке (остальные элементы стека остаются на
своих местах). Команда pushd каталог равносильна команде cd
каталог, при этом каталог записывается в вершину стека,
остальные элементы стека сохраняются с новыми номерами.
Команда pushd +число равносильна команде cd
имя_с_номером_(1+число). При этом имя_с_номером_(1+число)
ставится в вершину стека, а число имен переписывается в
конец стека в том порядке, в котором они следовали от вер-
шины стека. Другие элементы стека остаются без изменений.

1.3. Управление вводом и выводом

В ДЕМОС используются так называемые стандартный ввод,
стандартный вывод и стандартный вывод диагностических сооб-
щений. Стандартный ввод определяет источник данных для
команды, стандартный вывод - приемник данных, стандартный
вывод диагностических сообщений - приемник сообщений об
ошибках.

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

<&lt;, <&lt;<&lt;, <&lt;<&lt; слово

Если разделитель не указан, ввод осуществляется с клавиатуры
дисплея (стандартный ввод).

Для указания направления вывода (приемника) использу-
ются следующие разделители:

>&gt; >&gt;>&gt; |
>&gt;& >&gt;>&gt;& |&
>&gt;! >&gt;>&gt;!
>&gt;&! >&gt;>&gt;&!

Если разделитель не указан, вывод осуществляется на экран
дисплея (стандартный вывод и стандартный вывод ошибок).

Метасимвол & используется, когда необходимо сообщения
об ошибках выводить вместе со стандартным выводом, а не на
экран. Метасимвол ! используется, когда необходимо временно


- 9 -










отменить действие некоторых ключей.

Для управления режимами ввода-вывода используются зна-
чения ключей noclobber, noglob и nonomatch. Если ключи уста-
новлены, то выполняется особый режим выполнения операций
ввода-вывода. Установку и отмену ключей выполняют с помощью
команд set и unset. Например:

set noclobber или unset noclobber


Рассмотрим подробнее управление вводом:

<&lt; имя_файла
открывается файл, который читается вместо чтения с кла-
виатуры дисплея;

<&lt;<&lt; слово
в качестве ввода используется ввод с клавиатуры дисп-
лея. Ввод прекращается, когда введенная строка будет
идентична слову. Например:

cat >&gt; file <&lt;<&lt; mmm
0123
3456
6789
mmm

Команда cat создает file и ждет ввода с клавиатуры
дисплея. Каждая введенная строка сравнивается с mmm.
Если она отличается от mmm, то записывается в file.
Если она идентична mmm, ввод прекращается и file закры-
вается. Строка mmm в выходной файл не вводится. Ана-
логичную конструкцию можно использовать в командном
файле.


Рассмотрим подробнее управление выводом:

>&gt; имя_файла
результат направляется в указанный файл.

>&gt;! имя_файла
восклицательный знак отменяет действие ключа noclobber.
Ключ запрещает вывод в файл, если он к этому моменту
существует и не является специальным файлом (например,
/dev/tty*). Допустим, существуют файлы с именем file1
и file2 и выполнена команда

set noclobber

Тогда команда



- 10 -










cat <&lt; file2 >&gt; file1

не выполнится, а команда

cat <&lt; file2 >&gt;! file1

выполнится. Предопределенная переменная noclobber
используется как ключ, запрещающий случайное поврежде-
ние существующих файлов. Конструкции >&gt;!, >&gt;>&gt;!, >&gt;&! и
>&gt;>&gt;&! отменяют действие этого ключа для указанного в
командной строке файла.

>&gt;& имя_файла или >&gt;&! имя_файла
в первом случае диагностические сообщения направляются
в файл, во втором - будет сделано то же, но с отменой
действия ключа noclobber.

>&gt;>&gt; имя_файла или >&gt;>&gt;! имя_файла
вывод помещается в конец файла. Если файл отсутствует,
то он создается, во втором - будет сделано то же, но с
отменой действия ключа noclobber.

>&gt;>&gt;& имя_файла или >&gt;>&gt;&! имя_файла
в первом случае csh добавит диагностические сообщения в
файл, во втором случае будет сделано то же, но с отме-
ной действия ключа noclobber.


Можно запретить изменение расширения имени файла. Для
этой цели используется ключ noglob. В общем случае имя
файла имеет вид: основа_имени.суффикс. Если установлен ключ
noglob, изменение суффиксов имен существующих файлов будет
порождать состояние ошибки. Чтобы отменить действие этого
ключа для конкретных файлов, в командных строках можно ука-
зывать те же конструкции, что и при использовании ключа
noclobber.

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

cat <&lt; file1 |& pr -w79 -l24 >&gt; file2

будут направлены не на стандартный вывод (экран дисплея), а
через pr в file2.

1.4. Управление процессами

Процесс является основным объектом ДЕМОС, может выпол-
няться синхронно и асинхронно. Синхронный процесс - это


- 11 -










процесс, который на все время выполнения прерывает связь
между пользователем и интерпретатором, асинхронный процесс
выполняется параллельно с csh. Командная строка может
порождать несколько процессов, каждому из которых присваива-
ется уникальный номер - идентификатор. Идентификатор исполь-
зуется для управления процессом. Существуют два типа иденти-
фикаторов процесса: системный и внутренний. Системный иден-
тификатор процесса выводится командой ps и относится к каж-
дому процессу. Каждому системному идентификатору процесса
ставиться в соответствие уникальный внутренний идентифика-
тор. Внутренний идентификатор процесса известен только
пользователю, относится ко всем процессам, порожденным одной
командной строкой, и используется для управления процессом в
командах fg, bg, stop, kill, notify. Процесс может нахо-
диться в двух состояниях - выполняться или быть приостанов-
ленным. Механизм управления процессом включает следующие
средства:

завершение выполнения синхронного (асинхронного) про-
цесса;


приостановление (возобновление) выполнения синхронного
(асинхронного) процесса;


изменение режима выполнения процесса с синхронного на
асинхронный и наоборот;


вывод сообщения о состояниях асинхронного процесса
после его завершения или в момент изменения;


управление вводом-выводом при выполнении процесса;


послать сигнал процессу;


управление ресурсами процесса.


Сведения о процессах хранятся интерпретатором в виде
таблицы. Актуальное состояние таблицы можно получить,
выполнив команду jobs или jobs -l. Во втором случае выво-
дится более подробная информация. После выполнения команды
jobs получим, например:







- 12 -










[1] Остановлен cc -c *.o
[2] - Остановлен make install
[3] + Остановлен red file
[4] Выполняется sort file >&gt; result &
[5] Выполняется mx -q -N -u -s *.m >&gt; out &

Каждая строка таблицы содержит сведения о конкретном про-
цессе. В квадратных скобках указан внутренний идентификатор
процесса. Существует несколько способов указания идентифи-
катора в командной строке при ссылке на элемент таблицы про-
цессов:

% или %+
последний из приостановленных;

%-
предпоследний из приостановленных;

%номер
любой с таким внутренним идентификатором;

%символы
любой с такими первыми символами строки;

%?шаблон?
любой процесс с таким шаблоном в строке.


Запуск синхронного процесса осуществляется в результате
выполнения командной строки, на конце которой нет символа &.
Чтобы прекратить выполнение синхронного процесса, необходимо
напечатать символ СУ/C (CTRL/C). Если нужно прекратить
выполнение синхронного процесса с сохранением в файле образа
памяти, то необходимо напечатать символ СУ/\ (CTRL/\). При
этом в рабочем каталоге будет записан файл с именем core.
Файл core является копией памяти, которую занимал в ОЗУ про-
цесс в момент, когда был послан сигнал СУ/\.

Синхронный процесс может выводить информацию на экран
дисплея. В этом случае, чтобы приостановить вывод, необхо-
димо напечатать символ СУ/S (CTRL/S), чтобы продолжить
выполнение, необходимо напечатать символ СУ/Q (CTRL/Q).
Если синхронный процесс не выводит информацию на дисплей,
чтобы его приостановить, необходимо напечатать символ СУ/Z
(CTRL/Z), а чтобы продолжить - напечатать fg или %. Описан-
ные способы управления синхронным процессом существенно раз-
личны. Первый используется только в случае вывода на дисп-
лей, второй можно использовать в любом случае. Кроме того,
при использовании СУ/Z синхронный процесс приостанавливается
с возобновлением работы csh, а при использовании СУ/S этого
не происходит. Существует возможность перевести процесс из
синхронного в асинхронный режим выполнения. Для этого необ-
ходимо приостановить его, используя СУ/Z, затем напечатать


- 13 -










bg. С этого момента и до своего завершения процесс будет
выполняться асинхронно.

Запуск асинхронного процесса осуществляется в резуль-
тате выполнения командной строки, в конце которой указан
символ &. После запуска асинхронного процесса на экран
дисплея выводится сообщение вида

[число] число

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

stop %идентификатор_процесса
или
stop %строка

В формате stop %строка в качестве строки используется одна
из форм ссылки на таблицу процессов. Допустим, имеется нес-
колько асинхронно выполняемых процессов:

1 sort file >&gt; /tmp/result &
2 cc *.c >&gt;& errors &
3 lint *.c >&gt;& mymsg &

Первый можно остановить так: stop %1 или stop %sort; второй
- stop %2 или stop %c; третий - stop %3 или stop %li, или
stop %?mymsg?. Чтобы возобновить выполнение приостановлен-
ного процесса, используется команда fg для запуска его как