Командный язык C-shell Производственно-внедренческий кооператив "И Н Т Е Р Ф Е Й С" Диалоговая Единая Мобильная Операционная Система Демос/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 для запуска его как синхронного и bg для запуска его как асинхронного. Варианты запуска на асинхронное выполнение приостановленного про- цесса: %идентификатор_процесса & %строка & bg %идентификатор_процесса bg %строка fg %идентификатор_процесса & fg %строка & Варианты запуска на синхронное выполнение приостановленного процесса: %идентификатор_процесса %строка fg %идентификатор_процесса fg %строка Часто возникает необходимость принудительно (до нор- мального окончания) завершить работу асинхронного процесса. - 14 - При этом не важно, выполняется он или приостановлен. В этом случае процессу необходимо послать сигнал принудительного завершения: kill -KILL %идентификатор_процесса или kill -KILL %строка или kill -KILL системный_идентификатор_процесса Для приостановки интерпретатора используется команда suspend, так как команду СУ/Z интерпретатор игнорирует. Асинхронные процессы производят вывод стандартным обра- зом. Вывод можно запретить, выполнив команду stty tostop Если установлен ключ терминала tostop, все асинхронные про- цессы будут останавливаться при попытке использовать стан- дартный вывод. При попытке чтения с терминала асинхронный процесс останавливается в любом случае. Пример: stty tostop cat <&lt; file & [1] 285 jobs [1] + Ждет (вывод на терминал) cat <&lt; file Чтобы возобновить вывод, необходимо выполнить команду fg %1 или fg %cat Чтобы отменить ключ tostop, следует выполнить команду stty -tostop Команда kill используется для посылки сигнала процессу. Форматы команды kill: kill -l вывести список сигналов; kill %номер или kill %строка послать сигнал TERM (окончить) процессу; kill системный_идентификатор_процесса послать сигнал TERM процессу; - 15 - kill -SIG процесс послать сигнал SIG процессу. Сигналы задаются либо по их номерам, либо по их именам (как они заданы в /usr/include/signal.h без префикса SIG). Обычно все сообщения об изменении состояний процесса выво- дятся на экран дисплея после вывода приглашения (не в момент выполнения другого процесса). Переменная notify, если она установлена, обеспечивает вывод всех сообщений асинхронно. Можно установить режим notify для всех процессов или для конкретного процесса: notify - установлен для всех процессов; unset notify - отмена режима; notify %номер - установлен для процесса с номером. Для 32-битных машин возникает проблема ограничения ресурсов, выделенных процессу. Имеется возможность ограни- чивать следующие типы ресурсов: cputime максимальное число секунд центрального процессора, отводимое каждому процессу; filesize максимальный размер файла, который можно создать; datasize максимальное увеличение области (данные + стек) с помощью sbrk(2) за границу текста программы; stacksize максимальный размер автоматически расширяемой области стека; coredumpsize максимальный размер дампа, который будет создан. Для определения размера ресурса используется команда limit, для отмены - команда unlimit. Для всех типов ресур- сов, кроме cputime, используется размерность k - Килобайты или m - Мегабайты. Для cputime используются ss - секунды, m - минуты, h - часы. Для указания типа ресурсов используются приведенные выше ключевые слова. Примеры: - 16 - limit cputime 1m (1 минута) limit cputime 05:30 (5минут 30 секунд) limit filesize 2m (размер файла до 2 Мбайт) 1.5. Шаблоны имен файлов и каталогов Если слово содержит один из символов *, ?, [, ], {, } или начинается с символа ~ (надчеркивание), то оно стано- вится кандидатом на подстановку имени файла. При этом дан- ное слово рассматривается как шаблон, который заменяется отсортированным в алфавитном порядке списком имен файлов, которые соответствуют шаблону. Если ни для одного возможного варианта подстановки имени по шаблону не находится, то порождается состояние ошибки. Ниже раскрыты значения симво- лов в шаблонах имен файлов и каталогов. * соответствует любой последовательности символов. Напри- мер, по команде echo * будут показаны имена всех файлов рабочего каталога, по команде echo */*/f* будут прос- мотрены входящие каталоги и выведен список всех файлов, имена которых начинаются на f. ? соответствует одному любому символу. Пример: % ls f.? f.c f.o f.s будут выведены имена всех файлов каталога, которые в качестве основы имени имеют символ f, а в качестве рас- ширения имени - один любой символ. [последовательность_символов] соответствует любому символу указанной последователь- ности. Пример: % ls f.[cso] f.c f.o f.s [символ-символ] соответствует любому символу из лексикографически упо- рядоченного диапазона. Пример: - 17 - % ls f.[a-z] f.c f.o f.s Выводятся все файлы, расширение имени которых - любая строчная буква латинского алфавита. ~ (надчеркивание) регистрационный каталог, например по команде ls -l ~ будет выведено содержимое каталога, в который вы попа- даете при входе в систему. Такой каталог принято назы- вать регистрационным. ~регистрационное_имя_пользователя регистрационный каталог пользователя. Пример: % ls ~Иванов будет выведено содержимое регистрационного каталога пользователя с именем Иванов. {список_символов_через_запятую} соответствует любому из перечисленных символов. Пример: % ls f.{c,s,o} f.c f.o f.s слово1{список_слов_через_запятую}слово2 к слово1 добавляется первое слово из списка слов и добавляется слово2. Далее повторяется для второго слова из списка слов и так далее. Не допускаются пробелы. Слово1 и/или слово2 могут отсутствовать. Пример: % ls aaa{ddd,ccc,bbb}eee aaadddeee не найден aaaccceee не найден aaabbbeee не найден При поиске файлов формировались их имена комбинациями указанных последовательностей. Сообщение не найден выводится, когда такой файл командой ls не обнаружен. Описанная конструкция используется не только для подс- тановки имен файлов, но и для генерации различных слов, нап- ример: - 18 - % echo Та{ня,ню,не,тьяна,тьяну,тьяне} Таня Таню Тане Татьяна Татьяну Татьяне Возможны и более сложные применения, например: %echo Та{ня,тьяна,нечка}{' Иванова',' Петрова'} Таня Иванова Таня Петрова Татьяна Иванова Татьяна Петрова Танечка Иванова Танечка Петрова При создании шаблона имени файла особое место занимает символ точка в первой позиции имени. Если имя файла имеет вид .имя, то точку необходимо указать явно. В ряде случаев метасимволы шаблонов имен файлов и ката- логов не экранируются символом \. Необходима определенная осторожность при использовании этих символов там, где по контексту не следует выполнять подстановки имен файлов и каталогов. Выше было сказано, что если указанному шаблону не соот- ветствует ни одно имя, то порождается состояние ошибки. В некоторых случаях это может привести к нежелательному прек- ращению выполнения задания. Существует ключ, связанный с шаблонами и именами файлов, - nonomatch. Если он установ- лен, интерпретатор csh сообщает, что указанному в командной строке шаблону не соответствует ни один файл в каталоге и этот шаблон выводится на стандартный вывод. Пусть, например, имеются файлы f.1, f.2 и f.3. Выполним команду echo f.[4- 9], получим сообщение об ошибке: echo: Нет таких имен. Теперь выполним команды set nonomatch; echo f.[4-9] получим сообщение: f.[4-9]. В первом случае было выведено сообщение команды echo об ошибке. Во втором случае был выведен шаблон f.[4-9], относительно которого не удалось подобрать имя файла. Принципиальное отличие второго случая от первого заключается в том, что не порождалось состояние ошибки - просто был выведен шаблон. 1.6. Подстановки значений переменных В языке C-shell определены следующие типы переменных: слово, строка, массив слов, позиционная переменная. В отличие от других языков программирования, когда ука- зание имени переменной (например, в выражении) приводит к подстановке ее значения, в языке C-shell требуется явно - 19 - указывать, когда собственно необходимо использовать значение переменной. Определить переменную и присвоить ей значение можно с помощью команды set или присвоив переменной значение выражения (например, @ a = 5). Подстановка значений пере- менных выполняется после подстановки имен команд и файлов, если перед именем переменной указан без пробела символ $. Символы ?, # используются для управления режимами подстано- вок. Имеются следующие типы подстановок: подстановка собственного значения переменной; подстановка собственного значения позиционной перемен- ной; подстановка информации о переменной, например опреде- лена она или нет. Позиционные переменные инициализируются в командной строке при запуске командного файла на выполнение. Например, comfile aaa bbb ccc ddd каждое слово этой командной строки доступно внутри команд- ного файла comfile. Чтобы получить значение слова, доста- точно указать его номер в строке, например вместо $0 подста- вится comfile, вместо $3 - ccc. Рассмотрим примеры простых подстановок. % set a = 5 % echo a a % echo $a 5 Действие символа $ можно отменить, указав перед ним символ \. Например: % set a = 5 % echo \$a $a % echo $a 5 В последовательности символов, взятых в двойные кавычки, всегда действует символ $, например: - 20 - % set a = 5 % echo \$a $a % echo "\$a" \5 % set b = "Миша, Валера, $a." % echo $b Миша, Валера, 5. % % set b = "Миша, Валера, \$a." % echo $b Миша, Валера, \5. В последовательности символов, взятых в одинарные пра- вые кавычки, действие символа $ отменяется, например: % set a = 5 %set b = 'Миша, Валера, $a.' % echo $b Миша, Валера, $a. % % set b = 'Миша, Валера, \$a.' % echo $b Миша, Валера, \$a. В последовательности символов, взятых в одинарные левые (обратные) кавычки, символ $ приводит к подстановке перемен- ной. Подстановка происходит непосредственно перед выполне- нием команды, взятой в лев