 
 
 
 
 
 Утвержден
 
 2б.00152-01 97 04-ЛУ


 







 

 
                    Операционная система
 
                           МОС ВП
 
 
                   Подсистема управления

 
          ИСПОЛЬЗОВАНИЕ ДИАЛОГОВОГО КОМАНДНОГО ЯЗЫКА
  
                  И КОМАНДНЫХ ПРОЦЕДУР
 
 
                    Справочный материал
 
                     2б.00152-01 97 04
 
                      Листов 228/3K
 

 

 

 

 

 

 

 

                            1987
 Перв. Примен.                                   Литера
 2б.00152-01
 

                             
 
 
 
 
  
  
   
  
  
  
   
  
  
  
                    Oперационная система
  
                          МОС ВП
  
  
                   Подсистема управления
  
  
        ИСПОЛЬЗОВАНИЕ ДИАЛОГОВОГО КОМАНДНОГО ЯЗЫКА
  
                  И КОМАНДНЫХ ПРОЦЕДУР
  
  
                   Справочный материал
  
                      00152-01 97 04
  
                        Листов 225
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
                          1987
 

 
                               2 
 
                        000152-01 97 04
 
 
 
 
 
 
                            АННОТАЦИЯ
 
 
 
         В настоящем документе представлены ключевые понятия  и

   методы программирования командных процедур с помощью диало-
 
   гового командного (DCL) языка в операционной системе МОС ВП
 
   (далее - система). Kомандные  процедуры  предназначены  для
 
   программирования  заданий  пользователей  в  системе.   Для
 
   демонстрации описанных понятий и методов представлено много
 
   примеров, включая примеры завершенных  командных  процедур.
 
   Примеры, приведенные в  документе,  включают  элементарные,
 
   средние по сложности и сложные командные процедуры.
 
        Руководство содержит восемь разделов и три приложения.
 
        Раздел 1 является введением в использование и програм-
 
   мирование командных процедур.
 
        В разделе 2 приводится описание некоторых понятий диа-
 
   логового командного языка, которые используются  при  прог-
 
   раммировании командных процедур.
 
        В разделе 3 описаны ввод и вывод для командных  проце-
 
   дур.
 
        В разделе 4 описаны использования символов и лексичес-
 
   ких функций в командных процедурах.
 
        В разделе 5 описаны понятия, используемые при создании
 
   командных процедур.
 
        В разделе 6 приводится описание доступа к  файлам  для
 
   ввода и вывода в командных прцедурах.
 
        В разделе 7 приводится описание обработки ошибок внут-
 
   ри командных процедур.
 
 
 
                               3 
 
                        000152-01 97 04
  
 
        В разделе 8 приводится описание использования  команд-
 
   ных процедур в процессе пакетной обработки.
 
        Приложение 1 содержит аннотированные типовые командные
 
   процедуры.
 
        В приложении 2 представлена сводка  лексических  функ-
 
   ций.
 
        В приложении 3 дается  список  команд,  которые  часто
 
   используются в командных процедурах.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                               4 
 
                        000152-01 97 04
 
 
 
 
 
 
                           СОДЕРЖАНИЕ
 
 
 
 
 
   1.  Программирование командных процедур                  11
 
 
   1.1.    Создание командных процедур                      12
 
   1.1.1.    Документирование командных процедур            14
 
   1.1.2.    Использование  нескольких   строк   для
 
             одиночной команды                              15
 
   1.1.3.    Ввод имен команд и квалификаторов              15
   
   1.1.4.    Использование меток                            16
 
   1.2.    Выполнение командных процедур                    17
 
   1.2.1.    Выполнение   командных    процедур    в
 
             диалоговом режиме                              17
 
   1.2.2.    Запуск    командных    процедур     для
   
             выполнения в пакетном режиме                   18
 
   1.2.3.    Изменение командных уровней                    19
 
   1.3.    Командные процедуры регистрации                  20
 
   1.3.1.    Системный    или     групповой     файл
 
             регистрации                                    20
 
   1.3.2.    Персональный      файл      регистрации
 
             пользователя                                   21
 
   1.4.    Использование  командных  процедур  для
 
           определения       параметров        или
 
           квалификаторов                                   23
 
   1.5.    Проверка и отладка командных процедур            24
 
   1.6.    Обслуживание командных процедур                  25
 
 
                               5 
   
                        000152-01 97 04
 
 
   2.  Понятия языка DCL                                    25
 
 
   2.1.    Логические имена                                 26
 
   2.1.1.    Создание и удаление логических имен            27
 
   2.1.2.    Использование логических имен                  27
 
   2.1.3.    Таблицы логических имен                        28
 
   2.1.4.    Отображение логических имен                    31
   
   2.1.5.    Режимы доступа и атрибуты                      32
 
   2.1.6.    Списки поиска                                  32
 
   2.1.7.    Логические имена, определенные системой        33
 
   2.2.    Постоянные файлы процесса                        34
   
   2.2.1.    Постоянные файлы процесса по умолчанию         34
 
   2.2.2.    Переопределение  системных   логических
 
             имен по умолчанию                              37
 
   2.3.    Символы                                          37
   
   2.4.    Выражения                                        40
 
   2.4.1.    Величины в выражениях                          41
 
   2.4.1.1.  Символьные строки                              41
 
   2.4.1.2.  Целые                                          42
 
   2.4.1.3.  Символы                                        42
 
   2.4.1.4.  Лексические функции                            43
 
   2.4.2.    Операторы, используемые в выражениях           46
 
   2.5.    Замена символов                                  48
 
   2.5.1.    Использование   знаков   апострофа    в
 
             качестве операторов замены                     49
 
   2.5.2.    Использование   знаков   амперсенда   в
 
             качестве операторов замены                     51
 
   2.5.3.    Различие между символами и  логическими
 
             именами                                        52
 
   
   3.  Ввод-вывод командных процедур                        53
 
 
                               6 
 
                        000152-01 97 04
 
   
   3.1.    Передача данных в командные процедуры            53
 
   3.1.1.    Передача параметров                            54
 
   3.1.2.    Подсказки для ввода                            57
 
   3.2.    Передача данных в команды и образы               59
   
   3.2.1.    Включение данных в командную процедуру         59
 
   3.2.2.    Передача данных в вызываемый образ             61
 
   3.2.3.    Определение SYS$INPUT в качестве файла         63
 
   3.3.    Перенаправление  вывода  из   командных
 
           процедур                                         64
 
   3.3.1.    Перенаправление  вывода  из   командных
 
             процедур                                       64
 
   3.3.2.    Перенаправление  вывода  из  команд   и
 
             образов                                        65
 
   3.3.3.    Перенаправление сообщений об ошибках           68
 
   3.3.4.    Использование глобальных  символов  для
 
             возврата данных                                69
 
   3.3.5.    Использование   логических   имен   для
 
             возврата данных                                71
 
   3.3.6.    Проверка выполнения командных процедур         72
 
   3.4.    Запись данных на терминал                        73
 
   3.4.1.    Использование команды WRITE                    74
 
   3.4.2.    Использование команды TYPE                     75
 
 
   4.  Использование символов и лексических функций         76
 
 
   4.1.    Получение   информации    о    процессе
 
           пользователя                                     77
 
   4.1.1.    Изменения установок проверки                   79
 
   4.1.2.    Изменение защиты по умолчанию                  81
 
   4.2.    Получение информации о системе                   81
 
   4.2.1.    Определение имени узла пользователя            82
 
 
                               7 
 
                        000152-01 97 04
 
 
   4.2.2.    Получение информации о процессах               83
 
   4.3.    Получение   информации   о   файлах   и
 
           устройствах                                      84
 
   4.3.1.    Поиск файла в каталоге                         85
 
   4.3.2.    Удаление старых версий файлов                  86
 
   4.4.    Трансляция логических имен                       86
 
   4.5.    Операции над строками                            88
 
   4.5.1.    Определение наличия строки или символа         89
 
   4.5.2.    Выделение части строки                         89
 
   4.5.3.    Форматирование выходных строк                  92
 
   4.6.    Операции с типами данных                         94
 
   4.6.1.    Преобразование типов данных                    95
 
   4.6.2.    Вычисление выражений                           95
 
   4.6.3.    Определение существования символа              96
 
 
   5.  Разработка и логика командных процедур               97
 
 
   5.1.    Разработка командной процедуры                   97
 
   5.2.    Программирование                                 99
 
   5.2.1.    Получение переменных                           99
 
   5.2.2.    Программирование общей схемы  командной
 
             процедуры                                      99
 
   5.2.3.    Проверка и отладка                            102
 
   5.2.4.    Заполнение "заготовок" программы              103
 
   5.3.    Методы управления потоком выполнения            104
 
   5.3.1.    Команда IF                                    104
 
   5.3.2.    Команда GOTO                                  108
 
   5.3.3.    Циклы                                         109
 
   5.3.4.    Переход по условию                            112
 
   5.4.    Завершение командной процедуры                  113
 
   5.4.1.    Использование команды EXIT                    114
 
 
                               8 
 
                        000152-01 97 04
 
 
   5.4.2.    Передача значений состояния  с  помощью
       
             команды EXIT                                  115
 
   5.4.3.    Использование команды STOP                    116
 
 
   6.  Ввод-вывод файлов                                   117
 
 
   6.1.    Команды ввода-вывода для файлов                 117
 
   6.1.1.    Команда OPEN                                  117
     
   6.1.1.1.  Открытие файла для чтения                     118
 
   6.1.1.2.  Открытие файла для записи                     119
 
   6.1.1.3.  Открытие файла для чтения и записи            120
 
   6.1.1.4.  Открытие разделяемых файлов                   120
      
   6.1.2.    Команда READ                                  121
 
   6.1.2.1.  Создание циклов чтения                        122
 
   6.1.2.2.  Произвольное чтение записей из файлов с
 
             индексно-последовательным       методом
 
             доступа                                       123
 
   6.1.3.    Команда WRITE                                 123
 
   6.1.4.    Команда CLOSE                                 126
 
   6.2.    Модификация файлов                              127
 
   6.2.1.    Корректировка записей в файле                 127
 
   6.2.2.    Создание нового выходного файла               129
 
   6.2.3.    Добавление записей к файлу                    131
 
   6.3.    Обработка ошибок ввода-вывода                   132         
                     
 
 
   7.  Управление условиями ошибок и прерываниями CTRL/Y   134
 
 
   7.1.    Обнаружение    ошибок    в    командных
                                        
           процедурах                                      134
 
   7.1.1.    Коды  условия   и   глобальный   символ
 
             $STATUS                                       134
 
   7.1.2.    Уровни серьезности ошибки и  глобальный
 
 
                               9 
                                                    
                        000152-01 97 04
 
 
             символ $SEVERITY                              135
 
   7.1.3.    Команды,   которые   не   устанавливают
 
             символ $STATUS                                136
 
   7.2.    Обработка условия ошибок                        137
 
   7.2.1.    Команда ON                                    139
 
   7.2.2.    Блокировка проверки ошибок                    141
 
   7.3.    Обработка прерываний YC/Y                       144
 
   7.3.1.    Прерывание командной процедуры                144
 
   7.3.2.    Установка    подпрограммы     обработки
 
             прерывания CTRL/Y                             146
 
   7.3.3.    Запрещение и выполнение прерываний YC/Y       152
 
                                           
   8.  Работа с пакетными заданиями                        153
 
 
   8.1.    Представление пакетного задания                 154
 
   8.1.1.    Проверка   для   пакетных   заданий   в
 
             командном       файле       регистрации
 
             пользователя                                  155
 
   8.1.2.    Представление   нескольких    командных
 
             процедур                                      156
 
   8.1.3.    Управление пакетным заданием                  157
 
   8.2.    Передача данных в пакетное задание              159
 
   8.3.    Вывод из пакетного задания                      160
 
   8.3.1.    Сохранение файла регистрации                  161
 
   8.3.2.    Чтение файла регистрации                      162
 
   8.3.3.    Включение вывода  всех  команд  в  файл
 
             регистрации пакетного задания                 162
 
   8.4.    Контроль за очередью пакетных заданий           163
 
   8.4.1.    Изменение характеристик задания               165
 
   8.4.2.    Удаление и останов пакетных заданий           166
 
   8.5.    Повторный запуск пакетных заданий               167
 
 
                              10 
                                              
                        000152-01 97 04
 
 
   8.6.    Синхронизация    выполнения    пакетных
 
           заданий                                         168
 
 
   Приложение 1.                                           172
 

  1.   Примеры командных процедур                          172

  1.1. Командная процедура CONVERT.COM                     173

  1.2. Командная процедура REMINDER.COM                    173
             
  1.3. Командная процедура DIR.COM                         173

  1.4. Командная процедура SYS.COM                         173

  1.5. Командная процедура GETPARMS.COM                    174

  1.6. Командная процедура EDITALL.COM                     174

  1.7. Командная процедура FORTUSER.COM                    174

  1.8. Командная процедура LISTER.COM                      174

  1.9. Командная процедура CALC.COM                        175

  1.10. Командная процедура BATCH.COM                      175

          
   Приложение 2. Сводка лексических функций                217
                                                  
 
   Приложение 3. Краткий список команд                     221
 
     
       Перечень ссылочных документов                       225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              11 
 
                        000152-01 97 04
 
 
             1. Программирование командных процедур
             
                                                            
 
        Командная процедура является файлом, в котором  содер-
 
   жится список команд  диалогового  командного  языка  (DCL).
 
   Когда выполняется командная процедура, интерпретатор команд
 
   DCL читает и выполняет команды, которые в нем содержатся.
 
        Можно использовать командные процедуры для автоматиза-
 
   ции выполнения последовательностей  команд,  которые  часто
 
   используются. Например, если после  перехода  в  подкаталог
 
   всегда  используется  команда  DIREсTORY,  можно  составить
 
   командную процедуру с именем GO_DIR.сом, как в примере 1.
 
 
        П р и м е р 1.
 
           $ SET DEFAULT [PERRY.ACCOUNTS]                 
           $ DIREсTORY
 
        Вместо ввода каждой команды отдельно, можно  выполнить
 
   GO_DIR.COM: $ @GO_DIR
 
        Эта команда дает указание  интерпретатору  команд  DCL
 
   прочитать файл GO_DIR.COM и выполнить его команды, то есть,
 
   интерпретатор команд  устанавливает  каталог  по  умолчанию
 
   [PERRY.ACCOUNTS] и выполняет команду DIRECTORY.
 
        Можно составлять сложные командные процедуры,  похожие
 
   на программы, написанные на языках программирования высоко-
 
   го уровня.
 
        Например, можно изменить файл GO_DIR.COM, чтобы  полу-
 
   чить возможность  установки  любого  каталога  и  получения
 
   списка файлов в каталоге, как в примере 2.
                                           
 
 
 
 
 
 
 
 
 
                              12 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
                    
 
   $ INQUIRE DIR_NAME "DIREсTORY NAME"
   $ SET DEFAULT 'DIR_NAME'
   $ DIREстоRY 'DIR_NAME'
 
        Когда выполняется файл GO_DIR.COM примера  2,  команда
 
   INQUIRE  выводит  подсказку  имени  каталога,  команда  SET
 
   DEFAULT устанавливает данный каталог, а  команда  DIRECTORY
 
   выводит список имен файлов.
 
 
 
        1.1. Создание командных процедур
 
        
        Для создания командной процедуры используется  тексто-
 
   вый редактор или команда CREATе языка DCL. По умолчанию тип
 
   файла командной процедуры COM. Если используется  этот  тип
 
   файла, то при выполнении процедуры тип файла  указывать  не
 
   обязательно.
 
        Командная процедура содержит команды DCL, которые дол-
 
   жен выполнить интерпретатор команд DCL,  и  строки  данных,
 
   которые используются командами. Команды  должны  начинаться
 
   со знака '$'. Можно начинать командную  строку  непосредст-
 
   венно после знака '$', либо ввести один или несколько  про-
 
   белов или табуляций перед командной строкой,  чтобы  облег-
 
   чить ее прочтение.
       
        Строки данных, в отличие от команд, не  начинаются  со
 
   знака '$'. Строки данных используются  в  качестве  входных
 
   данных для команд (или образов). Строки данных используются
 
   предыдущими введенными командами; эти строки  не  обрабаты-
 
   ваются интерпретатором команд DCL.
 
        В примере 1 иллюстрируются командные строки  и  строки
 
   данных в командной процедуре.
 
 
 
 
                              13 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
                    
 
   $ MAIL
   SEND
   THOMAS
   MY MEMO
   $! у вас есть время для обсуждения идей,
   $! которые я представил в моем послании?
   $ SHOW USERS THOMAS
 
        Первая строка в примере 1 является командой и,  следо-
 
   вательно, должна начинаться со знака '$'. Следующие  строки
 
   являются строками данных, которые используются  обслуживаю-
 
   щей программой MAIL; эти строки  не  должны  начинаться  со
 
   знака '$'. Строки данных должны  соответствовать  правилам,
 
   по которым образ (вызванный командой) ожидает вводимые дан-
 
   ные. Когда интерпретатор команд находит новую строку, кото-
 
   рая начинается со знака '$', выполнение обслуживающей прог-
 
   раммы MAIL завершается.
 
 
        П р и м е ч а н и е.  Если  необходимо  начать  строку
 
   данных со знака '$', используются команды DECK и EOD. Более
 
   подробная информация содержится в разделе 3.
 
        Для облегчения чтения и обслуживания командных  проце-
 
   дур используются следующие соглашения:
 
        1) для документирования командных процедур используют-
 
   ся комментарии;
 
        2) если командная строка является слишком длинной  или
 
   включает много квалификаторов, командная строка продолжает-
 
   ся на следующей строке;
 
        3) имена команд и квалификаторы вводятся без  сокраще-
 
   ний;
 
        4) метки для идентификации групп команд и метки циклов
 
   и переходов рекомендуется обозначать смысловыми именами для
 
   облегчения чтения процедуры.
 
 
                              14 
 
                        000152-01 97 04
 
 
        1.1.1. Документирование командных процедур
 
 
        Хорошей практикой в программировании является докумен-
 
   тирование командных процедур, для облегчения их прочтения и
 
   обслуживания. В начале  командной  процедуры  рекомендуется
                                                  
   использовать комментарии для описания процедуры и  парамет-
 
   ров, которые передаются в нее.  Кроме  того,  рекомендуется
 
   использовать комментарии в начале каждого блока команд  для
 
   описания данной секции процедуры.
 
        В командной процедуре комментарии разделяются  воскли-
 
   цательным знаком.
 
        DCL обрабатывает все, что помещено справа от восклица-
 
   тельного знака в  качестве  комментария  и  игнорирует  эту
 
   информацию при обработке строки.
 
        В примере 1 используются комментарии для  документиро-
 
   вания команды и облегчения ее чтения.
 
 
        П р и м е р 1.
 
 
   $! эта процедура отправляет почтовую корреспонденцию
   $! для пользователя с именем THOMAS и определяет,
   $! зарегистрирован ли он в  системе
   $!
   MAIL
   SEND
   THOMAS
   MY MEND
   у вас есть время для обсуждения идей,
   которые я предствил в моем послании?
   $!
   $ SHOW USERS THOMAS
 
        Пустую строку в командной процедуре  необходимо  начи-
 
   нать со знака '$'. Если  опущен  знак  '$',  то  DCL  будет
 
   интерпретировать строку как данные. Также полезно  помещать
 
   после знака '$' восклицательный знак. Хотя он и не требует-
 
   ся, но это  поможет  ускорить  прогон  процедуры,  так  как
 
   интерпретатор команд проигнорирует строку как комментарий.
 
 
                              15 
 
                        000152-01 97 04
 
 
        Если необходимо использовать литерал  восклицательного
 
   знака в командной строке, то  необходимо  заключить  его  в
 
   кавычки, так чтобы интерпретатор команд не  интерпретировал
 
   восклицательный знак в качестве  ограничителя  комментария.
 
   Символ восклицательного знака можно использовать  в  строке
 
   данных, так как строки данных не обрабатываются интерпрета-
 
   тором команд.
 
 
 
        1.1.2. Использование  нескольких   строк   для
  
               одиночной команды
 
 
        При написании команды, включающей  много  квалификато-
 
   ров, можно сделать командную процедуру более читаемой путем
                                      
   перечисления квалификаторов на отдельных строках.
 
        Для этого используется дефис в качестве  символа  про-
 
   должения, так как это делалось для  продолжения  команды  в
 
   диалоговом режиме.
 
        Строка продолжения не начинается со знака '$'. Исполь-
 
   зование строк продолжения иллюстрирует следующий пример.
 
 
        П р и м е р.
 
 
   $ PRINT TEST.OUT -
           /AFTER=18:00 -
           /COPIES=10 -
           /QUEUE=LPB0:
 
 
        1.1.3. Ввод имен команд и квалификаторов
 
 
        Даже если правила синтаксиса DCL разрешают сокращения,
 
   необходимо вводить полные имена  команд,  квалификаторов  и
 
   ключевых слов в командных процедурах. Это помогает докумен-
                                                
   тировать командную процедуру, так как команды и  квалифика-
 
   торы DCL обычно находятся в соответствии с выполняемыми ими
 
 
                              16 
 
                        000152-01 97 04
 
 
   функциями.
 
        Для примера рассмотрим следующие командные строки.
 
 
        П р и м е р.
 
   $ PRINT ALPHA.LIS/COPIES=2
   $ PR ALPHA/C=2
 
        Первая командная строка в примере 1 ясно выражает зап-
 
   рос на печать двух копий  файла  ALPHA.LIS.  Вторая  строка
 
   является сокращенной и  не  может  легко  читаться  другими
 
   пользователями.
 
        Кроме того, использование сокращений может привести  к
 
   ошибкам при выполнении командной  процедуры  в  последующих
 
   реализациях МОС ВП.
 
 
 
        1.1.4. Использование меток
 
 
        Улучшить читаемость командных процедур можно используя
 
   метки для идентификации связанных групп команд. Когда метки
 
   помечают запуск цикла, необходимо использовать пробелы  или
                                  
   пропуски для смещения  команд  в  цикле.  Когда  выделяются
 
   команды, в первой колонке должен присутствовать знак '$'.
 
 
        П р и м е р.
 
 
   $! эта процедура модифицирует пятую запись в файле
   $! EMPLOYEES.DAT
   $!
   $ OPEN/READ/WRITE IN_FILE EMPLOYEES.DAT
   $ COUNT = 1
   $ FIND_RECORD:
   $    IF COUNT .GT. 5 THEN GOTO REVISE
   $    READ IN_FILE RECORD
   $    COUNT = COUNT + 1
   $    GOTO FIND_RECORD
   $!
   $ REVISE:
 
        В примере метка FIND_RECORD ограничивает начало цикла,
 
   используемого для поиска пятой записи в файле, а команды  в
 
 
                              17 
 
                        000152-01 97 04
 
 
   цикле выделяются пробелами.
 
        Команды IF и GOTO, а также методы для создания  циклов
 
   в командных процедурах описаны в разделе 5.
 
 
 
        1.2. Выполнение командных процедур
 
 
        Командные процедуры можно выполнять двумя способами: в
 
   диалоговом и пакетном режимах. В диалоговом режиме  команды
 
   процедур выполняются, как если бы пользователь вводил их  с
                                          
   терминала. При этом, пока процедура не  закончится,  нельзя
 
   выполнять другие команды  с  этого  терминала.  В  пакетном
 
   режиме создается процесс для прогона  командной  процедуры.
 
   После того, как пакетное задание запущено, можно продолжить
 
   использование терминала во время выполнения пакетного зада-
 
   ния.
 
 
 
        1.2.1. Выполнение   командных    процедур    в
 
               диалоговом режиме
 
 
        Для выполнения командной процедуры в диалоговом  режи-
 
   ме, необходимо ввести символ '@' с  последующей  специфика-
 
   цией файла процедуры. Если вводится  неполная  спецификация
                                
   файла, интерпретатор использует текущий диск, каталог и тип
 
   файла по умолчанию COM. Например, следующая команда  выпол-
 
   няет командную процедуру WEATHER.COM, размещенную в текущем
 
   каталоге по умолчанию: $ @WEATHER.
 
        Каждая  командная   строка   в   командной   процедуре
 
   WEATHER.COM выполняется последовательно и в конце процедуры
 
   интерпретатор команд выводит  на  терминал  подсказку  DCL.
 
   Затем можно возобновить работу в диалоговом режиме.
 
 
 
 
                              18 
 
                        000152-01 97 04
 
 
        Если командная процедура находится не  в  каталоге  по
 
   умолчанию или отсутствует файл типа COM, необходимо  ввести
 
   спецификацию файла, как показано в примере.
 
 
        П р и м е р.
 
 
   $ @DISK2:[COMMON]SETUP.CMD
 
        Для командных  процедур,  которые  выполняются  часто,
 
   можно определить символическое имя в качестве синонима  для
 
   полной командной строки. Например:
 
   $SETUP = "DISK2:[COMMON]SETUP"
 
        В дальнейшем  можно  использовать  символ  SETUP,  как
 
   команду:
 
   $ @SETUP
 
        Интерпретатор команд транслирует SETUP в его  значение
 
   DISK2:[COMMON]SETUP.COM и затем выполняет процедуру.
 
 
 
        1.2.2. Запуск    командных    процедур     для
 
               выполнения в пакетном режиме
 
 
        Если  используются  процедуры,  требующие  длительного
 
   времени выполнения  (например,  компиляция  или  трансляция
 
   больших исходных  программ),  рекомендуется  запускать  эти
                                           
   процедуры в качестве пакетных заданий.
 
        С помощью команды SUBMIT  командная  процедура  запус-
 
   кается в качестве пакетного задания. Команда SUBMIT  подра-
 
   зумевает текущие диск и каталог по умолчанию и тип файла по
 
   умолчанию сом для командной процедуры.
 
        Например, для запуска командной процедуры  WEATHER.COM
 
   (в каталоге по умолчанию) в  пакетном  режиме  используется
 
   следующая командная строка, показанная в примере.
 
 
 
                              19 
 
                        000152-01 97 04
 
 
        П р и м е р.
 
 
   $ SUBMIT WEATHER 
     JOB WEATHER (QUEUE SYS$BATCH, ENTRY 210) STARTED
     ON SYS$BATCH
   $
 
        В примере система распечатывает сообщение, указывающее
 
   на то, что задание поставлено в очередь; сообщение содержит
 
   номер задания (210) и имя  системной  очереди,  на  которой
 
   введено задание (SYS$BATCH). Затем выводится подсказка  DCL
 
   и можно продолжить использование терминала.
 
        Задание находится в очереди до тех пор,  пока  система
 
   не будет готова к прогону задания.  Затем  система  создает
 
   для  пользователя  другой  процесс,  используя  значения  и
 
   характеристики процесса. Система выполняет  прогон  задания
 
   из этого процесса и удаляет процесс после завершения  зада-
 
   ния. Более подробная информация приведена в разделе 8.
 
 
 
        1.2.3. Изменение командных уровней
 
 
        Командный уровень - это уровень DCL, на котором выпол-
 
   няются команды. При  регистрации  пользователя  в  системе,
 
   ввод команд с терминала выполняется  на  уровне  ноль.  При
                                          
   выполнении командной процедуры, ее команды  выполняются  на
 
   уровне 1. Когда процедура завершается и на экране терминала
 
   повторно появляется подсказка DCL, пользователь возвращает-
 
   ся на командный уровень ноль.
 
        Можно  организовать  вложенную  командную   процедуру,
 
   используя команду ее запуска внутри другой процедуры. Когда
 
   выполняется вложение командной процедуры, происходит увели-
 
   чение командного уровня на единицу. Максимальный  командный
 
   уровень,  который  можно  достигнуть  с  помощью   вложения
 
 
 
                              20 
 
                        000152-01 97 04
 
 
   командных процедур, равен 16.
 
        В пакетном задании командный уровень ноль определяется
 
   как командная процедура, которая запущена для  обработки  в
 
   пакетном режиме. Если  пакетное  задание  содержит  команду
 
   запуска вложенной процедуры, то команды во вложенной проце-
 
   дуре выполняются на командном уровне 1.  В  пакетных  зада-
 
   ниях, как и в диалоговом  режиме,  можно  создавать  до  16
 
   командных уровней.
 
 
 
        1.3. Командные процедуры регистрации
 
 
        Всякий раз при входе в систему, система  автоматически
 
   выполняет командные процедуры  регистрации.  Система  также
 
   выполняет эти процедуры в начале каждого запущенного пакет-
                                            
   ного задания. Система выполняет два типа командных процедур
 
   регистрации:
 
        1)  системная  (или  групповая)  командная   процедура
 
   регистрации;
 
        2) персональная командная процедура регистрации  поль-
 
   зователя.
 
        Эти командные процедуры регистрации описаны в пп.1.3.1
 
   и 1.3.2
 
 
 
        1.3.1. Системный    или     групповой     файл
 
               регистрации
 
 
        Если создан системный (групповой) файл регистрации, то
 
   он выполняется перед файлом регистрации пользователя. Когда
 
   системный файл регистрации  завершается,  управление  пере-
                          
   дается на персональный файл регистрации пользователя.  Сис-
 
   темный и групповой файлы регистрации предоставляют  возмож-
 
 
                              21 
 
                        000152-01 97 04
 
 
   ность системному администратору быть уверенным в  том,  что
 
   определенные команды всегда  выполняются,  когда  осуществ-
 
   ляется вход в систему.
 
        Для установки системного или группового файла  регист-
 
   рации,  администратор  системы  назначает  логическое   имя
 
   SYS$LOGIN на определенный файл  регистрации.  Администратор
 
   системы определяет выполнение этого файла  регистрации  для
 
   всех пользователей  системы  или  для  определенной  группы
 
   пользователей.
 
 
 
        1.3.2. Персональный      файл      регистрации
 
               пользователя
 
 
        После  выполнения  системного  или  группового   файла
 
   регистрации система выполняет персональный файл регистрации
 
   пользователя. Персональный  файл  регистрации  пользователя
 
   используется для выполнения команд, которые требуются  вся-
 
   кий раз при входе в систему. Командная процедура  регистра-
 
   ции должна иметь имя LOGIN.COM  и  размещаться  в  каталоге
 
   регистрации по умолчанию.
 
        В примере 1  приведен  персональный  файл  регистрации
 
   LOGIN.COM.
 
 
        П р и м е р 1.
 
 
   $! выход, если это пакетное задание или другой тип
   $! не интерактивного процесса
   $!
   $ IF F$MODE() .NES. "INTERACTIVE" THEN EXIT
   $!
   $! выполнить командные процедуры, которые содержат
   $! определения символа, логического имени и клавиатуры
   $!
   $ @DISK3:[MARCIA]SYMBOLS
   $ @DISK3:[MARCIA]LOGIсаLS
   $ @DISK3:[MARCIA]KEYDEF
   $!
 
 
                              22 
 
                        000152-01 97 04
 
 
   $! изменить строку подсказки на сокращенное
   $! имя своего узла
   $!
   $ NODE = F$GETSYI("NODENAME")
   $ PROMPT = F$EXTRACT(0,3,NODE)
   $ SET PROMPT = "''PROMPT'>"
   $!
   $! вывод системного об'явления
   $  TYPE SYS$SYSTEM:NOTICE.TXT
   $! запуск программы, печатающей сегоднешние назначения
   $  RUN DISK3:[MARCIA.PROG]REMINDER
 
        В примере 2 показаны определения глобальных  символов,
 
   которые выполняются в командной процедуре SYMBOLS.COM.
 
 
        П р и м е р 2.
 
 
   $ DISPLAY == "MONITOR PROCESSES/TOPCPU"
   $ GO == "SET DEFAULT"
   $ LP == "SHOW QUEUK/ALL SYS$PRINT"
   $ SS == "SHOW SYMBOL"
   $ REM == "GDISK3:[MARCIA.TOOLS]REMINDER"
   $ MAIN == "SET DEFAULT DISK3:[MARCIA]"
 
        На  примере  3  показан  образец  командной  процедуры
 
   LOGICAL.COM.
 
 
        П р и м е р 3.
 
 
   $! каталоги
   $  DEFINE HOME DISK3:[MARCIA]
   $  DEFINE REV DISK3:[MARCIA.REVIEWS]
   $  DEFINE TOOLS DISK3:[маRсIA.TOOLS]
   $!
   $! файлы
   $  DEFINE EQUIPMENT.DAT
   $!
   $! пользователи
   $ DEFINE DAISY::HARRIS JOU
   $ DEFINE DAISY::MOORE  JANE
 
        В примере 4 показаны определения клавишей клавиатуры в
 
   файле KEYDEF.COM.
 
 
        П р и м е р 4.
 
 
   $ DEFINE PF3 "SHOW USERS" /TERMINATE
   $ DEFINE/KEY KP7 "SPAWN" /TERMINATE
   $ DEFINE/KEY KP8 "ATTACH"
   $ DEFINE KP4 "SET HOST"
 
 
                              23 
 
                        000152-01 97 04
 
 
        Администратор системы назначает спецификацию файла для
 
   командной процедуры регистрации пользователя в поле  LGICMD
 
   записи пользователя. В большинстве случаев  командный  файл
 
   регистрации называется LOGIN.COM. Однако, если есть необхо-
 
   димость в выполнении другого  файла,  отличного  от  файла,
 
   указанного в записи пользователя,  необходимо  использовать
 
   квалификатор /COMMAND при регистрации.  Описание  процедуры
 
   регистрации и квалификатора /COMMAND приведено в  документе
 
   [1].
 
        Администратор системы может установить для пользовате-
 
   ля ограничение  возможности  и  поместить  имя  специальной
 
   командной процедуры в поле LGICMD  записи  пользователя.  В
 
   этом случае пользователь может  выполнить  только  функции,
 
   заданные в командной процедуре, имя которой указано в  поле
 
   LGICMD. Такой пользователь  не  может  использовать  полный
 
   набор команд DCL. Более подробное описание записей  пользо-
 
   вателя с ограниченными возможностями приведено в  документе
 
   [2].
 
 
 
        1.4. Использование  командных  процедур  для
 
             определения       параметров        или
 
             квалификаторов
 
 
        Можно  создать  командную  процедуру,  которая  задает
 
   только параметры и/или квалификаторы, и затем  использовать
 
   командную процедуру  в  командной  строке  DCL.  Такой  тип
 
   командной процедуры используется, когда имеется набор пара-
 
   метров или квалификаторов, которые используются с одной или
 
   несколькими определенными командами. Для выполнения команд-
 
   ной процедуры используется символ '@' в командной строке, в
 
 
 
                              24 
 
                        000152-01 97 04
 
 
   которой будут использоваться квалификаторы или параметры.
 
        Например, часто используется один и тот же набор  ква-
 
   лификаторов при вводе команды LINK. Можно создать командную
 
   процедуру, которая содержит  эти  квалификаторы,  например:
 
   DEBUG/SYMBOL_TABLE/MAP/FULL/CROSS_REFERENCE
 
        Чтобы использовать эту командную процедуру, необходимо
 
   поместить ее в командной строке в месте указания квалифика-
 
   торов. Например, если командной процедуре присваивается имя
 
   DEFLINK.COM, необходимо  использовать  следующую  командную
 
   строку  для   компоновки   об'ектного   модуля   с   именем
 
   SYNAPSE.OBJ с квалификаторами, которые заданы  в  командной
 
   процедуре: $ LINK SYNAPSE@DEFLINK
 
        Нельзя  включать  пробел  перед  символом  '@',  когда
 
   командная процедура содержит только имена квалификаторов.
 
 
 
        1.5. Проверка и отладка командных процедур
 
 
        Обычно командные процедуры нуждаются в проверке и пос-
 
   ледующей отладке. Для выполнения отладки командной процеду-
 
   ры используются  команды  SET  VERIFY  и  SET  NOVERIFY.  С
                                                  
   помощью команды SET VERIFY устанавливается режим распечатки
 
   командных строк процедуры, называемый проверкой.
 
        В примере показано выполнение процедуры SYMBOLS.COM  с
 
   проверкой.
 
 
        П р и м е р.
 
 
   $ SET VERIFY
   $ @SYMBOLS
   $ DISPLAY == "MONITOR PROCESS/TOPCPU"
   $ GO == "SET DEFAULT"
   $ LP == "SHOW QUEUE/ALL SYS$PRINT"
   $ SS == "SHOW SYMBOL"
   $ REM == "@DISK3:[MARCIA,TOOLS]REMINDER"
   $ MAIN == "SET DEFAULT DISK3:[MARCIA]"
 
 
                              25 
 
                        000152-01 97 04
 
 
   $
 
        Проверка продолжает действовать до тех пор,  пока  она
 
   не будет отменена явно с помощью команды SET NOVERIFY. Мож-
 
   но также использовать лексическую  функцию  F$NOVERIFY  для
 
   изменения установок проверки. В разделе 4 приведено подроб-
 
   ное описание изменения установок проверки.
 
 
 
        1.6. Обслуживание командных процедур
 
 
        Если разработанная процедура правильно  форматирована,
 
   документирована и проверена, то  ее  обслуживание  является
 
   относительно легким. Однако, новые версии операционной сис-
                                            
   темы МОС ВП могут включать расширения  возможностей  DCL  и
 
   изменения для текущих команд.
 
 
 
 
                      2. Понятия языка DCL
 
 
 
        Для составления командных процедур, сходных с програм-
 
   мами на языке программирования высокого уровня,  необходимо
 
   использовать переменные. Переменные используются для предс-
 
   тавления величин,  которые  могут  изменяться  при  прогоне
 
   командной процедуры. Для представления переменных в команд-
 
   ной процедуре используются логические  имена,  символы  или
 
   лексические  функции.  Для  манипулирования  с  переменными
 
   используются выражения DCL.
 
        В этом  разделе  представлен  обзор  по  использованию
 
   логических имен, символов, выражений и лексических функций.
 
   Если пользователь уже знаком с этими понятиями, можно  про-
 
   пустить этот раздел и перейти к разделу 3. Базовая  вводная
 
   информация по этим понятиям представлена в  документе  [3];
 
 
                              26 
 
                        000152-01 97 04
 
 
   Полная справочная информация представлена в документе [1].
 
 
 
        2.1. Логические имена
 
 
        Логическое имя является именем, которое можно  исполь-
 
   зовать на месте другой строки. Логическое имя приравнивает-
 
   ся строке (называемой строкой эквивалентности)  или  списку
                             
   строк. Когда используется логическое  имя,  строка  эквива-
 
   лентности заменяется на логическое имя. В основном логичес-
 
   кие имена используются для представления файлов,  каталогов
 
   и устройств.
 
        Например, если логическое имя TEST_FILE приравнивается
 
   строке эквивалентности STATISTICS, можно сформировать  сле-
 
   дующую команду: $RUN TEST_FILE.
 
        Система заменяет строку эквивалентности STATISTICS для
 
   логического   имени   TEST_FILE   и   прогоняет   программу
 
   STATISTICS.EXE. (команда RUN принимает тип файла по умолча-
 
   нию .ехе).
 
        Команда, получившая в командной строке имя  файла  или
 
   устройства, проверяет, является ли введенное  имя  логичес-
 
   ким. Если имя  является  логическим,  то  система  заменяет
 
   логическое имя на действительную величину и выполняет соот-
 
   ветствующую команду.
 
        После трансляции логического имени  в  строку  эквива-
 
   лентности, система проверяет, является  ли  строка  эквива-
 
   лентности также логическим именем. Если это так, то система
 
   выполняет вторую трансляцию. Этот процесс, называемый  ите-
 
   рационной трансляцией, может повторяться максимум 10 раз.
 
 
 
 
 
 
 
                              27 
 
                        000152-01 97 04
 
 
        2.1.1. Создание и удаление логических имен
 
 
        Можно использовать команды ASSIGN или DEFINE для  соз-
 
   дания логического имени. Следующая команда создает логичес-
 
   кое имя WORKFILE и определяет для него  строку  эквивалент-
                                                  
   ности:
 
   $ DEFINE WORKFILE DISK2:[WALSN.REPORTS]WORK_SUMMARY.DAT
 
 
        Для удаления логического  имени  используется  команда
 
   DEASSIGN. Например, логическое имя WORKFILE может быть уда-
 
   лено с помощью команды:
 
   $ DEASSIGN WORKFILE
 
 
 
        2.1.2. Использование логических имен
 
 
        При работе в  диалоговом  режиме,  можно  использовать
 
   логические имена для обращения к  своим  файлам  и  рабочим
 
   каталогам. Например, назначив логическое имя COMS для ката-
                                            
   лога: DISK7:[WALSH.COMMAND_PROC],  можно  использовать  имя
 
   сомS вместо ввода с клавиатуры длинных  имен  устройства  и
 
   каталога. В примере 1 показано, как  определить  логическое
 
   имя сомS и использовать его в качестве  части  спецификации
 
   файла.
 
 
        П р и м е р 1.
 
 
   $ DEFINE COMS DISK7:[WALSH.COMMAND_PROC]
   $ TYPE COMS:PAYROLL.COM
   $ SET DEFAULT COMS
 
        Когда логическое имя используется как часть специфика-
                    
   ции файла, логическое имя  должно  помещаться  в  начальной
 
   (самой левой) части спецификации файла,  и  за  ним  должно
 
   следовать двоеточие. Однако, имеются специальные правила по
 
 
 
                              28 
 
                        000152-01 97 04
 
 
   использованнию логических имен в спецификациях сетевых фай-
 
   лов. Для получения более  подробной  информации  необходимо
 
   ознакомиться с документом [1].
 
        Логические имена также могут использоваться для  обра-
 
   щения к устройствам в системе. Не рекомендуется  обращаться
 
   к устройству, используя  его  физическое  имя  (такое,  как
 
   DBA1); вместо этого лучше использовать логическое имя, наз-
 
   наченное администратором  системы.  Кроме  того,  некоторые
 
   команды, такие как ALLOCATE и MOUNT, предоставляют  возмож-
 
   ность создавать собственные логические имена, когда пользо-
 
   ватель работает с дисками или магнитными лентами.
 
        В командных процедурах часто  используются  логические
 
   имена при выполнении ввода и вывода из файлов. При открытии
 
   файла с помощью команды ореN создается логическое  имя  для
 
   файла. В примере 2 показано,  что  команды  READ,  WRITE  и
 
   CLOSE для обращения к файлу используют логическое имя, а не
 
   действительную спецификацию файла.
 
 
        П р и м е р 2.
 
 
   $ OPEN INFILE DISK3:[WALSH]DATA.DAT
   $ READ INFILE RECORD
   $ CLOSE INFILE
 
        При закрытии файла команда CLOSE  отменяет  назначение
 
   логического имени INFILE.
 
 
 
        2.1.3. Таблицы логических имен
 
 
        Система обслуживает логические имена в таблицах  логи-
 
   ческих имен. Некоторые  таблицы  логических  имен  доступны
 
   только для процесса  одного  пользователя;  другие  таблицы
                                      
   доступны и для  других  пользователей  системы.  Логические
 
 
 
                              29 
 
                        000152-01 97 04
 
 
   имена, с которыми работает пользователь, хранятся в следую-
 
   щих четырех таблицах:
 
 
     таблица     - имена в этой таблице доступны только для
 
     процесса      отдельного пользователя. Действительное
 
                   имя таблицы процесса LNM$PROCESS_TABLE.
 
                   Однако, для обращения к таблице процесса
 
                   следует использовать логическое имя
 
                   LNM$PROCESS;
 
 
 
     таблица     - имена в этой таблице доступны для процесса
 
     заданий       пользователя и любого из его подпроцессов.
 
                   Действительное имя таблицы заданий
 
                   пользователя LNM$JOB_ххх (ххх соответствует
 
                   номеру задания). Однако , рекомендуется
 
                   использовать логическое имя LNM$JOB для
 
                   обращения к таблице заданий;
 
 
 
     таблица     - имена в этой таблице доступны для всех
 
     группы        пользователей в данной  группе.
 
                   Действительное имя такой группы
 
                   LNM$GROUP_ххх (ххх соответствуют номеру
 
                   группы). Однако, рекомендуется использовать
 
                   логическое имя LNM$GROUP для обращения к
 
                   таблице группы;
 
 
 
     таблица     - имена в этой таблице доступны для всех
 
     системы       пользователей системы. Действительное имя
 
                   для таблицы системы LNM$SYSTEM_TABLE.
 
                   Однако, рекомендуется использовать
 
 
 
                              30 
 
                        000152-01 97 04
 
 
                   логическое имя LNM$SYSTEM для обращения к
 
                   таблице системы.
 
 
        Когда используется логическое имя, система  просматри-
 
   вает таблицы процесса, задания, группы и системы (в указан-
 
   ном порядке) для определения трансляции имен. Можно,  одна-
 
   ко, изменить путь трансляции логических имен; для получения
 
   более подробной информации обратитесь к документу [1].
 
        По умолчанию, команды DEFINE  и  DEASSIGN  помещают  и
 
   удаляют имена из таблицы процесса. Однако, можно  запросить
 
   другую таблицу с помощью квалификатора /TABLE. Например:
 
   $DEFINE/TABLE=LNM$SYSTEM REVIEWERS -
 
    DISK3:[PUBLIC]REVIEWERS.DIS
 
 
        Более подробная информация содержится в документе [1].
 
        В основном, логические имена создаются в таблице  про-
 
   цесса. Однако, администратор системы или  привилегированный
 
   пользователь может добавлять имена к совместно используемым
 
   таблицам группы и системы.
 
        Можно создавать новые таблицы в дополнение к тем  таб-
 
   лицам, которые обеспечиваются операционной системой МОС ВП.
 
   Для создания  дополнительных  таблиц  используется  команда
 
   CREATE/NAME_TABLE.
 
        Система обслуживает таблицы логических имен в  катало-
 
   гах    двух     типов:     личном     каталоге     процесса
 
   LNM$PROCESS_DIRECTORY      и      разделяемом      каталоге
 
   LNM$SYSTEM_DIRECTORY. В системе имеется только один  разде-
 
   ляемый каталог таблиц и несколько личных каталогов для каж-
 
   дого процесса. Все логические имена  таблиц  сохраняются  в
 
   этих  каталогах.  Например,   имена   таблиц   пользователя
 
   LNM$PROCESS, LNM$JOB и LNM$GROUP хранятся в личном каталоге
 
 
                              31 
 
                        000152-01 97 04
 
 
   процесса, LNM$SYSTEM хранится в разделяемом каталоге.
 
 
 
        2.1.4. Отображение логических имен
 
 
        Логические имена и строки их  эквивалентности  отобра-
 
   жаются с помощью команды SHOW LOGICAL. Команда SHOW LOGICAL
 
   выполняет поиск таблиц логических имен для заданного  имени
                                          
   (имен). Если не  задана  таблица  для  поиска,  то  команда
 
   выполняет  поиск  таблиц  процесса  пользователя,  заданий,
 
   группы и системы. Однако, можно изменить порядок поиска  по
 
   умолчанию, либо назначить другие таблицы  логических  имен,
 
   для которых необходимо выполнить поиск.
 
        В  примере  отображается  строка  эквивалентности  для
 
   логического имени INTRO.
 
 
        П р и м е р.
 
 
   $ SHOW LOGICAL INTRO
   0 "INTRO"[SUPER]="DISK6:[DCONNEL.INTRO]"(LNM$PROCESS_TABLE)
 
        Эта команда использует порядок поиска по умолчанию  и,
 
   следовательно, выполняет поиск  таблиц  процесса,  заданий,
 
   группы и системы для логического имени INTRO. Номер 0  ука-
 
   зывает на то, что логическое имя INTRO соответсвует  первой
 
   итерации трансляции.
 
        Если логическое имя имеет дополнительные итерации, они
 
   также будут отображаться. Нумерация итераций  начинается  с
 
   нуля.
 
        Команда SHOW LOGICAL отображает, в квадратных скобках,
 
   любые режимы и атрибуты, связанные с логическим  именем.  В
 
   примере слово "[SUPER]" указывает на то, что логическое имя
 
   было создано в режиме супервизора. Имя  в  круглых  скобках
 
   (LNM$PROCESS_TABLE) указывает таблицу, в которой было  най-
 
 
                              32 
 
                        000152-01 97 04
 
 
   дено логическое имя. Если логическое имя  не  задавалось  в
 
   команде SHOW LOGICAL, то отображаются все имена в  таблицах
 
   процесса, задания, группы и системы, если  не  был  изменен
 
   порядок поиска по умолчанию.
 
        Можно использовать  квалификатор  /TABLE,  чтобы  явно
 
   указать таблицу для поиска.  Например,  с  помощью  команды
 
   SHOW LOGICAL/TABLE=LNM$PROCESS отображаются имена в таблице
 
   процесса.
 
 
 
        2.1.5. Режимы доступа и атрибуты
 
 
        Логические имена имеют соответствующие режимы  доступа
 
   и атрибуты. Команда SHOW/LOGICAL отображает  эти  режимы  и
 
   атрибуты. Когда пользователь создает  логическое  имя,  оно
                                        
   создается в режиме супервизора, если не используется квали-
 
   фикатор для задания другого режима.  Атрибуты  не  присваи-
 
   ваются, если отсутствует явный запрос.
 
        В командных  процедурах  пользователь  обычно  создает
 
   имена в режиме супервизора. Однако, можно назначить времен-
 
   ное логическое имя,  которое  существует  только  на  время
 
   выполнения одной программы. Для создания временного  назна-
 
   чения  используется   команда   DEFINE   с   квалификатором
 
   /USER_MODE. Более подробная информация содержится в разделе
 
   3.
 
 
 
        2.1.6. Списки поиска
 
 
        Список  поиска  является  логическим  именем,  имеющим
 
   больше одной строки эквивалентности. Например:
 
   $ DEFINE MY_FILES DISK1:[COOPER], DISK2:[COOPER]
                            
 
 
 
                              33 
 
                        000152-01 97 04
 
 
        Список поиска можно использовать в  любом  месте,  где
 
   можно использовать логическое имя. Когда используется  спи-
 
   сок поиска, система транслирует каждую  строку  эквивалент-
 
   ности в определении списка поиска.
 
 
        П р и м е р.
 
   $ TYPE MY_FILES:CHAP1.RNO
 
        В примере  команда  делает  попытку  распечатать  файл
 
   DISK1:[COOPER]CHAP1.RNO. Если этот файл не  существует,  то
 
   система будет искать файл DISK2:[COOPER]CHAP1.RNO.
 
        Более подробная информация о командах обработки  спис-
 
   ков поиска содержится в документе [1].
 
 
 
        2.1.7. Логические имена, определенные системой
 
 
        После загрузки системы создается и помещается в табли-
 
   цу логических имен системы LNM$SYSTEM  набор  общесистемных
 
   логических имен. Эти логические имена предоставляют возмож-
                                
   ность пользователю обращаться к обычно используемым  файлам
 
   и устройствам, без использования  их  действительных  имен.
 
   Например, если необходимо распечатать программы  операцион-
 
   ной системы, пользователю не нужно знать имя диска и  ката-
 
   лога,  где  эти  программы  хранятся.  Вместо  этого  можно
 
   использовать логическое имя SYS$SYSTEM:
 
   $ DIRECTORY SYS$SYSTEM
 
        В документе [1] представлен полный список  общесистем-
 
   ных логических имен. В дополнение к  общесистемным  именам,
 
   система всякий раз  при  регистрации  пользователя  создает
 
   группу логических имен для процесса пользователя и помещает
 
   эти имена в его таблицу процесса. Например, логическое  имя
 
   SYS$LOGIN назначается на устройство и каталог  пользователя
 
 
                              34 
 
                        000152-01 97 04
 
 
   по умолчанию по  регистрации.  Если  выполняется  изменение
 
   текущих умолчаний с помощью команды SET DEFAULT,  то  можно
 
   использовать следующую  команду  для  распечатки  файла  из
 
   начального каталога пользователя по умолчанию:
 
   $ TYPE SYS$LOGIN:DAILY_NOTES.DAT
 
        Четыре логических имени процесса по умолчанию относят-
 
   ся к постоянным файлам процесса, их описание  приводится  в
 
   п.2.2.1.
 
 
 
        2.2. Постоянные файлы процесса
 
 
        Постоянные файлы процесса - это файлы, которые остают-
 
   ся открытыми на все время осуществления процесса. По  умол-
 
   чанию DCL создает  четыре  постоянных  файла  процесса  при
                                      
   регистрации пользователя. В дополнение, всякий раз при вво-
 
   де команды открытия файла, DCL открывает файл как  постоян-
 
   ный файл процесса. Например,  если  пользователь  открывает
 
   файл с помощью команды ореN, то этот файл  открывается  как
 
   постоянный файл процесса. Файл  остается  открытым  до  тех
 
   пор, пока файл не будет явно закрыт, либо  пользователь  не
 
   выполнит выход из системы.
 
        Постоянные  файлы  процесса  хранятся  в   специальной
 
   области в основной памяти. При одновременном хранении боль-
 
   шего числа открытых файлов эта область может быть  исчерпа-
 
   на. В этом случае необходимо закрыть несколько файлов  (или
 
   выполнить выход из системы).
 
 
 
        2.2.1. Постоянные файлы процесса по умолчанию
 
 
        По умолчанию DCL создает и назначает логические  имена
 
   для четырех постоянных файлов процесса:
 
 
                              35                     
 
                        000152-01 97 04
 
 
   SYS$COMMAND   - исходный файл, из которого DCL
 
                   осуществляет чтение входных данных. Файл,
 
                   из которого DCL читает входные данные,
 
                   называется входным потоком. Интерпретатор
 
                   команд использует файл SYS$COMMAND для
 
                   "запоминания" исходного входного потока;
 
 
 
   SYS$ERROR     - файл по умолчанию, в который DCL
 
                   записывает сообщения, создаваемые
 
                   предупреждениями, ошибками и неисправимыми
 
                   ошибками;
 
                              
 
   SYS$INPUT     - файл по умолчанию, из которого DCL читает
 
                   ввод;
 
 
 
   SYS$OUTPUT    - файл по умолчанию, в который DCL
 
                   записывает вывод. Файл, в который DCL
 
                   записывает вывод, называется выходным
 
                   потоком.
 
 
        Если используется команда SноW LOGIсаL для определения
 
   строки  эквивалентности  для  постоянного  файла  процесса,
 
   отображается только часть строки, относящаяся к устройству,
 
   как показано в примере.
 
 
        П р и м е р.
 
   $ SHOW LOGICAL SYS$INPUT
   0 "SYS$INPUT"[EXEC] = "_TTB4:[TERMINAL] (LNM$PROCESS_TABLE)
 
        Однако, строки эквивалентности для  постоянных  файлов
 
   процесса также содержат специальные символы, которые систе-
 
   ма использует для размещения файлов. Эти специальные симво-
 
   
 
                              36 
 
                        000152-01 97 04
 
 
   лы никогда не отображаются для пользователей;  они  исполь-
 
   зуются только для собственных нужд системы.
 
        Когда система  используется  в  интерактивном  режиме,
 
   SYS$INPUT, SYS$OUTPUT, SYS$COMMAND назначаются на  терминал
 
   пользователя. Однако, когда выполняются командные процедуры
 
   и запускаются пакетные задания, DCL создает  новые  эквива-
 
   ленты для этих логических имен.
 
        При выполнении командной процедуры  интерактивно  соз-
 
   даются следующие эквиваленты:
 
        1) SYS$INPUT назначается на командную процедуру,  сле-
 
   довательно, язык DCL получает команды из командной процеду-
 
   ры. Такое назначение является временным и после  завершения
 
   командной процедуры SYS$INPUT переназначается  на  исходный
 
   эквивалент;
 
        2) SYS$OUTPUT, SYS$COMMAND и SYS$ERROR остаются назна-
 
   ченными на терминал.
 
        При выполнении пакетного задания  создаются  следующие
 
   эквиваленты:
 
        1) SYS$INPUT и SYS$COMMAND  назначаются  на  командную
 
   процедуру пакетного задания;
 
        2) SYS$OUTPUT и SYS$ERROR - на файл регистрации пакет-
 
   ного задания.
 
        При использовании вложенных командных процедур,  экви-
 
   валент для SYS$INPUT изменяется, чтобы указывать на текущую
 
   выполняемую командную процедуру.
 
        Однако,  эквиваленты  для  SYS$OUTPUT,   SYS$ERROR   и
 
   SYS$COMMAND остаются теми же, если они  не  изменены  самим
 
   пользователем.
 
 
 
 
 
 
                              37 
 
                        000152-01 97 04
 
 
        2.2.2. Переопределение  системных   логических
 
               имен по умолчанию
 
 
        DCL   обеспечивает   по   умолчанию   назначения   для
 
   SYS$INPUT, SYS$OUTPUT,  SYS$ERROR  и  SYS$COMMAND,  которые
 
   обычно не нуждаются в изменении.  Однако,  если  необходимо
 
   выполнить определенные операции ввода и вывода, как описано
 
   в разделе 3, необходимо изменить эти эквиваленты.
 
 
 
        2.3. Символы
 
 
        Символ является именем, на  которое  назначается  сим-
 
   вольная строка или целая величина. При работе в интерактив-
 
   ном режиме символам можно присваивать  командные  строки  и
 
   затем использовать символы  в  качестве  синонимов  команд.
 
   Например, если символ  LP  приравнивается  к  команде  SHOW
 
   QUEUE/ALL SYS$PRINT, то можно ввести: $LP .
 
        В  командных  процедурах  символы  помогают  выполнять
 
   программирование задач. Например, можно использовать симво-
 
   лы в качестве переменных в выражениях. Можно также  исполь-
 
   зовать символы для передачи параметров в командные процеду-
 
   ры. В дополнение, такие команды, как READ, WRITE и  INQUIRE
 
   используют символы для обращения к записям данных. В разде-
 
   ле 5  приводится  полное  описание  применения  символов  в
 
   командных процедурах.
 
        Для создания символа используется знак  "="  (оператор
 
   присваивания).
 
 
        П р и м е р 1.
 
                    
   $ SUM = 5 + 7
   $ NAME = "MоRTIMER" + "SNERD"
 
 
 
                              38 
 
                        000152-01 97 04
 
 
        В примере 1  левая  от  оператора  присваивания  часть
 
   строки определяет имя символа; правая часть содержит  выра-
 
   жение. При создании символа DCL вычисляет выражение и прис-
 
   ваивает  результат  символу.  Если  вычисленное   выражение
 
   является целым, то символ имеет целую величину. Если  выра-
 
   жение содержит символьную строку, то символ имеет  величину
 
   строки.
 
        Символ SUM имеет целую  величину,  так  как  выражение
 
   (5+7) вычисляется в целую величину (12).
 
        Символ NAME имеет величину строки, так  как  выражение
 
   вычисляется в символьную строку ("MORTIMER SNERD").
 
        Символьные строки необходимо заключать в кавычки, если
 
   они используются в выражениях.
 
        Для отображения величины символа используется  команда
 
   SHOW SYMBOL.
 
 
        П р и м е р 2.
 
 
   $ SHOW SYMBOL SUM
     SUM = 12 HEX = 000000C OCTAL = 0000000014
   $ SHOW SYMBOL NAME
     NAME = "MORTIMER SNERD"
 
        Если символ имеет  целую  величину,  то  команда  SноW
 
   SYмвоL отображает величины в десятичном,  шестнадцатеричном
 
   и восьмеричном представлениях, как показано в примере 2.
 
        Можно создавать символы двух типов: локальные  символы
 
   и глобальные символы. Локальные символы доступны из текуще-
 
   го командного уровня и из командных  процедур,  выполняемых
 
   из текущего командного уровня. Глобальные символы  доступны
 
   на всех командных уровнях. Для создания локального  символа
 
   используется один знак равенства; для создания  глобального
 
   символа следует использовать два знака равенства, как пока-
 
 
 
                              39 
 
                        000152-01 97 04
 
 
   зано в примере 3.
 
 
        П р и м е р 3.
 
 
   $ SS = "SHOW SYMBOL"
   $ GO == "SET DEFAULT"
 
        DCL помещает локальные  символы  в  таблицу  локальных
 
   символов для текущего командного уровня. Таблица  локальных
 
   символов используется на каждом  командном  уровне  до  тех
 
   пор,  пока  командный  уровень  является  активным.   Когда
 
   командный  уровень  становится  неактивным,   его   таблица
 
   локальных символов (и всех символов, которые она  содержит)
 
   удаляется.
 
        DCL использует одну  таблицу  глобальных  символов  во
 
   время выполнения процесса и помещает все глобальные символы
 
   в эту таблицу. Следовательно, глобальный символ  существует
 
   в течении времени выполнения процесса, если символ не  уда-
 
   ляется специально.
 
        Для определения значения символа просматривается  таб-
 
   лица локальных символов на текущем командном  уровне.  Если
 
   символ не найден, то выполняется поиск в таблице  локальных
 
   символов на предыдущих командных уровнях.  Если  символ  не
 
   найден, то просматривается таблица глобальных символов.
 
        Можно удалять глобальный и локальный символы с помощью
 
   команды DELETE/SYMBOL. По умолчанию  команда  DELETE/SYMBOL
 
   удаляет символы из текущей таблицы локальных символов.  Для
 
   удаления глобального символа необходимо использовать квали-
 
   фикатор /GLOBAL. Например: $ DELETE/SYMBOL/GLOBAL GO
 
 
                              
 
 
 
 
 
 
                              40 
                              
                        000152-01 97 04
 
 
        2.4. Выражения
 
 
        Выражения являются величинами  или  группами  величин,
 
   которые вычисляет DCL. Имеется два типа выражений:
 
        1) целое выражение - это выражение, которое вычисляет-
 
   ся в целое значение;
 
        2) выражение типа символьной строки - выражение, кото-
 
   рое вычисляется в символьную строку.
 
        Выражения используются в  операторах  присваивания  (с
 
   правой стороны от знака  равенства),  в  операторах  IF,  в
 
   командах WRITE и  в  качестве  аргументов  для  лексических
 
   функций.
 
        Выражения могут  содержать  символьные  строки,  целые
 
   величины, лексические функции, символы или комбинации  этих
 
   величин. При использовании в выражениях эти величины  назы-
 
   ваются операндами. Если выражение  содержит  больше  одного
 
   операнда, то они соединяются с помощью  операторов,  назна-
 
   чающих нужные операции.
 
        В примере иллюстрируются эти выражения.
 
 
        П р и м е р.
 
 
   Y = 25                  это целое выражение содержит только
                           один  операнд - число  25.
                           следовательно, величина 25
                           присваивается символу Y.
 
   Х = Y - 8               это целое выражение содержит два
                           операнда: Y и 8. Y является
                           символом, а 8 является целой
                           величиной. Знак "-" является
                           оператором, задающим вычитание.
                           когда DCL вычисляет это выражение,
                           он заменяет символ Y на его
                           действительную величину и выполняет
                           вычитание.
 
   ТITLE "TWELFTH"+"NIGHT" это строчное выражение содержит
                           два операнда: "TWELFTH" и "HIGHT.
                           так как оба операнда являются
 
 
                              41 
 
                        000152-01 97 04
 
 
                           символьными строками, то знак "+"
                           указывает на то, что строки должны
                           быть соединены. Вычисленнное
                           выражение будет следующим:
                           "TWELFTH NIGHT".
 
   IF COUNT.EQ.4 THEN EXIT в этом операторе IF определяется
                           истинность целого выражения
                           COUNT.EQ.4. DCL заменяет символ
                           COUNT на его целую действительную
                           величину и проверяет равна ли она
                           4. Если это условие
                           удовлетворяется, то выполняется
                           выход из командной процедуры.
 
 
        2.4.1. Величины в выражениях
 
 
        В данном пункте приводится описание  величин,  которые
 
   могут использоваться в выражениях. Эти величины включают:
 
        1) символьные строки;
 
        2) целые;
 
        3) символы;
 
        4) лексические функции.
 
 
 
        2.4.1.1. Символьные строки
 
 
        Если  в  выражениях  используются  символьные  строки,
 
   необходимо заключать их в  кавычки.  Если  не  использовать
 
   знаки кавычек, то DCL будет рассматривать строку  как  сим-
 
   вольное имя.
 
        Для включения знаков кавычек в строку необходимо ввес-
 
   ти два последовательных знака кавычек, как показано в  при-
 
   мере 1.
 
 
        П р и м е р 1.
 
 
   $ PROMPT = "TYPE ""YES"" OR ""NO"""
   $ SHOW SYMBOL PROMPT
     PROMPT = "TYPE "YES" OR "NO""
 
 
 
 
                              42 
 
                        000152-01 97 04
 
 
        Для продолжения символьной строки на следующей строке,
 
   используется знак "плюс" (для  соединения  строк)  и  дефис
 
   (для продолжения), как показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $ ADVICE = "A STITCH IN TYPE" + -
   $ "SAVES NINE"
   $ SHOW SYMBOL ADVICE
     ADVICE = "A STITCH IN TIPE SAVES NINE"
 
        Нельзя использовать символ продолжения "дефис"  внутри
 
   символьной строки, заключенной в кавычки.
 
 
 
        2.4.1.2. Целые
 
 
        Целые определяются как десятичные числа (числа с осно-
 
   ванием 1O), если не используются оператор основания %х (для
 
   шестнадцатеричных величин) или %о (для  восьмеричных  вели-
 
   чин). Целые указываются без кавычек, как приведено в приме-
 
   ре.
 
 
        П р и м е р.
 
 
   $ NUM = 17
   $ HEXNUM = %X1AB
 
 
        2.4.1.3. Символы
 
 
        Когда в выражениях используются символы, они автомати-
 
   чески заменяются на  соответствующую  величину.  Символьное
 
   имя нельзя указывать в кавычках. В примере  1  используется
 
   символ COUNT в выражении.
 
 
 
 
 
 
 
 
 
                              43 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $ COUNT = 3
   $ TOTAL = COUNT + 1
   $ SHOW SYMBOL TOTAL
     TOTAL = 4 HEX = 00000004 OCTAL = 00000000004
 
        При вычислении выражения, величина автоматически заме-
 
   няет символьное имя COUNT и результат присваивается символу
 
   TOTAL.
 
        Если символы используются  внутри  символьной  строки,
 
   следует использовать знаки  апострофа  для  запроса  замены
 
   символа. Более подробное описание представлено в п.2.5.1.
 
 
 
        2.4.1.4. Лексические функции
 
 
        Лексические функции возвращают значение  элемента  или
 
   списка элементов. (эти  элементы  называются  аргументами).
 
   Вызов  лексической  функции  выполняется  вводом  ее  имени
 
   (которое всегда начинается с F$) и  списка  ее  аргументов.
 
   Необходимо всегда заключать  список  аргументов  в  круглые
 
   скобки.
 
        Можно использовать лексические  функции  в  выражениях
 
   таким же способом, как обычно используются символьные стро-
 
   ки, целые и символы. Когда лексическая функция используется
 
   в выражении, DCL автоматически вычисляет функцию и заменяет
 
   ее на возвращаемую величину, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $ SUM = F$LENGTH("BUMBLEBEE")+1
   $ SHOW SYMBOL SUM
     SUM = 10 HEX = 0000000A OCTAL = 00000000012
 
        В примере 1 функция F$LENGTH возвращает длину  величи-
 
   ны, заданную в качестве  ее  аргумента.  DCL  автоматически
 
 
 
                              44 
 
                        000152-01 97 04
 
 
   определяет возвращаемую величину (9) и использует эту вели-
 
   чину для  вычисления  выражения.  Следовательно,  результат
 
   выражения (9+1) равен 10 и эта величина присваивается  сим-
 
   волу SUM.
 
        Каждая лексическая функция возвращает информацию  либо
 
   как целое, либо как символьную  строку,  в  зависимости  от
 
   функции. Также следует отметить,  что  необходимо  задавать
 
   аргументы для лексических функций либо как целые, либо  как
 
   выражения типа символьной строки, в зависимости от функции.
 
        Например, функция F$LENGTH требует  аргумент,  который
 
   является выражением типа символьной строки, и  она  возвра-
 
   щает величину, которая является целым. В примере 1 аргумент
 
   "BUMBLEBEE" является выражением типа символьной  строки,  а
 
   возвращаемая величина (9) является целым.
 
        Когда назначаются аргументы для  лексических  функций,
 
   необходимо следовать обычным правилам для написания выраже-
 
   ния: символьные строки заключаются в знаки кавычек;  целые,
 
   символы и лексические функции не заключаются в кавычки.
 
        В примерах 2, 3 и  4  показаны  различные  способы,  с
 
   помощью  которых  можно  задавать  аргумент   для   функции
 
   F$LENGTH; в каждом  примере  аргумент  является  выражением
 
   типа символьной строки.
 
        В примере 2 показан  символ,  который  используется  в
 
   качестве аргумента.
 
 
        П р и м е р 2.
 
 
   $ BUG = "BUMBLEBEE"
   $ LEN = F$LENGTH(BUG)
   $ SHOW SYMBOL LEN
     LEN = 9 HEX = 00000009 OCTAL = 00000000011
 
        Когда символ BUG используется в качестве аргумента, он
 
 
 
                             45 
 
                        000152-01 97 04
 
 
   не заключается в кавычки. Лексическая функция автоматически
 
   заменяет величину "BUMBLEBEE" на BUG,  определяет  длину  и
 
   возвращает величину 9.
 
        В примере 3 показан  аргумент,  который  содержит  как
 
   символ, так и символьную строку.
 
 
        П р и м е р 3.
 
 
   $ LEN = F$LENGTH(BUG + "S")
   $ SHOW SYMBOL LEN
     LEN = 10 HEX = 0000000A OCTAL = 00000000012
 
        Символ BUG не заключается в знаки кавычек,  но  строка
 
   "S" заключается в знаки кавычек.  Перед  тем,  как  функция
 
   F$LENGTH может определить длину, необходимо вычеслить аргу-
 
   мент. Величина, представленная  символом  BUG("BUMBLEBEE"),
 
   соединяется   со   строкой   "S";   результатом    является
 
   "BUMBLEBEES".  Функция  F$LENGTH  определяет  длину  строки
 
   "BUMBLEBEES" и возвращает величину 10.
 
        В примере 4 используется другая лексическая функция  в
 
   качестве аргумента для функции F$LENGTH.
 
        Функция F$DIRECTORY возвращает имя  текущего  каталога
 
   пользователя по умолчанию,  включая  квадратные  скобки.  В
 
   примере 4 текущий каталог по умолчанию [SALMON].
 
 
        П р и м е р 4.
 
 
   $ LEN = F$LENGTH( F$DIRECTORY())
   $ SHOW SYMBOL LEN
     LEN = 8 HEX = 00000008 OCTAL = 00000000010
 
        Функция  F$DIRECTORY  не  заключается  в  кавычки  при
 
   использовании в  качестве  аргумента;  функция  вычисляется
 
   автоматически. Перед тем, как функция F$LENGTH может  опре-
 
   делить  длину,  необходимо  возвратить  результат   функции
 
   F$DIRECTORY. Затем функция F$LENGTH определяет длину  ката-
 
 
                              46 
 
                        000152-01 97 04
 
 
   лога пользователя по умолчанию, включая квадратные скобки.
 
        В приложении 3 представлено  краткое  описание  каждой
 
   лексической функции.
 
 
 
        2.4.2. Операторы  используемые в выражениях
 
 
        Когда выражение  имеет  больше  одного  операнда,  они
 
   перечисляются с помощью операторов. В таблице 1 перечислены
 
   операторы в таком порядке, в котором они вычисляются,  если
 
   выражение содержит два или большее число операндов.  Опера-
 
   торы перечислены по  старшинству,  от  самого  старшего  до
 
   самого младшего; то есть, операторы вверху  таблицы  выпол-
 
   няются перед выполнением  операторов  внизу  таблицы.  Если
 
   выражение содержит операторы,  имеющие  одинаковый  порядок
 
   старшинства, то операции выполняются слева направо.
 
        Пользователь может отвергнуть нормальный порядок стар-
 
   шинства путем использования круглых скобок.
 
 
        П р и м е р.
 
 
   $ RESULT = 4 (6 + 2)
   $ SHOW SYMBOL RESULT
     RESULT = 32 HEX = 00000020 OCTAL = 00000000040
 
        В примере, путем  указания  круглых  скобок,  сложение
 
   будет выполнено перед умножением. Если  круглые  скобки  не
 
   используются,  то  вначале  будет  выполнено  умножение   и
 
   результат будет равен 26.
 
                                                    Таблица 1
 
                     Oператоры в выражениях
 
   ----------------------------------------------------------
   Oператор ! Cтаршинство !             Oписание
   ----------------------------------------------------------
            !             !
      +     !     7       !   Yказывает на положительное чис-
            !             ! ло
 
 
                              47 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 1
   ----------------------------------------------------------
   Оператор ! Старшинство !             Описание
   ----------------------------------------------------------
            !             !
      -     !     7       !   Указывает на отрицательное чис-
            !             ! ло
            !             !
      ж     !     6       !   Выполняет умножение  двух   чи-
            !             ! сел
            !             !
      /     !     6       !   Выполняет деление для двух  чи-
            !             ! сел
            !             !
      +     !     5       !   Выполняет  сложение  двух   чи-
            !             ! сел или соединяет две  символьныE
            !             ! строки
            !             !
      -     !     5       !   Выполняет  вычитание  для  двух
            !             ! чисел или уменьшает строку
            !             !
    .ЕQS.   !     4       !   Выполняет  проверку  на  равен-
            !             ! ство двух символьных строк
            !             !
    .GES.   !     4       !   Выполняет проверку на  то,  что
            !             ! первая строка  больше, или  равна
            !             ! второй строке
            !             !
    .GTS.   !     4       !   Выполняет проверку на  то,  что
            !             ! первая  строка  больше  второй
            !             ! строки
            !             !
    .LES.   !     4       !   Выполняет проверку на  то,  что
            !             ! первая строка меньше,  или  равна
            !             ! второй строке
            !             !
    .LTS.   !     4       !   Выполняет проверку  на  то, что
            !             ! первая   строка  меньше  второй
            !             ! строки
            !             !
    .NES.   !     4       !   Выполняет проверку  на  то, что
            !             ! две строки не равны
            !             !
    .EQ.    !     4       !   Выполняет проверку  на  то, что
            !             ! два числа равны
            !             !
    .GE.    !     4       !   Выполняет проверку  на  то, что
            !             ! первое  число  больше  или  равно
            !             ! второму числу
            !             !
    .GT.    !     4       !   Выполняет  проверку  на то, что
            !             ! первое число больше второго числа
            !             !
    .LE.    !     4       !   Выполняет  проверку на то,  что
            !             ! первое  число  меньше  или  равно
            !             ! второму числу
            !             !
    .LT.    !     4       !   Выполняет  проверку на то,  что
            !             ! первое число меньше второго числа
 
 
                              48 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 1
   ----------------------------------------------------------
   Оператор ! Старшинство !             Описание
   ----------------------------------------------------------
            !             !
    .NE.    !     4       !   Выполняет проверку  на  то, что
            !             ! два числа равны
            !             !
    .NOT.   !     3       !   Логически инвертирует число
            !             !
    .AND.   !     2       !   Комбинирует два числа с помощью
            !             ! логической операции и
            !             !
    .OR.    !     1       !   Комбинирует два числа с помощью
            !             ! логической операции или
            !             !
 
        Когда  пользователь  составляет   выражения,   которые
 
   содержат две или большее число величин, соединенных  опера-
 
   торами, величины должны иметь одинаковый тип данных.  Вели-
 
   чины могут быть либо данными типа строки, либо данными типа
 
   целого. Данные типа строки включают символьные строки, сим-
 
   волы с величинами типа строки и лексические функции,  кото-
 
   рые возвращают величины типа  строки.  Данные  типа  целого
 
   включают целые, символы с целыми величинами  и  лексические
 
   функции, которые возвращают целые величины.
 
        Если используются различные типы данных, то DCL преоб-
 
   разует величины в один тип данных перед вычислением выраже-
 
   ния. В общем случае, если используются  как  величины  типа
 
   строки, так и  целые  величины,  то  величины  типа  строки
 
   преобразуются в целые величины. Исключением является только
 
   тот случай, когда DCL выполняет сравнения строк; при  таких
 
   сравнениях целые преобразуются в строки.
 
 
 
        2.5. Замена символов
 
 
        В определенных контекстах DCL подразумевает, что стро-
 
   ка символов, начинающаяся с буквы, является символьным име-
 
   нем или лексической функцией. В этих контекстах DCL автома-
 
 
                              49 
 
                        000152-01 97 04
 
 
   тически выполняет замену символа или лексической функции на
 
   их величину. Если символ или  лексическая  функция  исполь-
 
   зуется в любом другом  контексте,  необходимо  использовать
 
   оператор замены для запроса замены символа.
 
        DCL  автоматически  вычисляет  символы  и  лексические
 
   функции, когда они используются в выражениях.  Следователь-
 
   но, символы и лексические функции вычисляются  автоматичес-
 
   ки, когда они размещены:
 
        1) в правой стороне оператора присваивания (=или==);
 
        2) в аргументе лексической функции;
 
        3) в командах DEPOSIT, EXAMINE, IF или WRITE.
 
        Кроме  указанных  контекстов,  символы   автоматически
 
   вычисляются в начале строки, если за  символом  не  следует
 
   знак равенства или двоеточие. (в примерах в предыдущих раз-
 
   делах использовались символы и лексические функции на  мес-
 
   тах автоматического вычисления).
 
        Однако, можно использовать символы и лексические функ-
 
   ции в других местах  командной  строки,  если  используются
 
   специальные операторы запроса замены символа. В общем  слу-
 
   чае, используются знаки апострофа для запроса замены симво-
 
   ла. Однако, имеются специальные  случаи,  когда  необходимо
 
   использовать знак амперсенда вместо знака апострофа.
 
 
 
        2.5.1. Использование   знаков   апострофа    в 
 
               качестве операторов замены
 
 
        Если символы и лексические функции используются на тех
 
   местах, где они автоматически не заменяются, то  необходимы
 
   знаки апострофа для запроса замены символов, как показано в
 
   примере 1.
 
 
 
                              50 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $ FILENAME = "CALENDAR.DAT"
   $ TYPE 'FILENAME'
 
        В примере 1  знаки  апострофа  указывают  на  то,  что
 
   FILENAME является символом, который должен транслироваться.
 
   Так как в предыдущей команде FILENAME  приравнен  к  строке
                                   
   "CALENDAR.DAT", то будет распечатываться файл CALENDAR.DAT.
 
   Если не указать знаки апострофа, то DCL не выполнит  замену
 
   символа.
 
        Можно  использовать  знаки  апострофа  для  выполнения
 
   замены символов, когда требуется соединить  два  символьных
 
   имени, как показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $ NAME = "EXAMPLES"
   $ TYPE = ".TST"
   $ PRINT 'NAME''TYPE'
 
        Когда последняя команда в примере 2 выполняется, имена
 
   NAME и TYPE заменяются на символьные строки.
 
        Две строки "EXAMPLES" и  ".TST"  соединяются,  образуя
 
   имя файла "EXAMPLES.TST".
 
        Для запроса замены символа,  указанного  в  символьной
 
   строке, необходимо поместить два знака апострофа перед сим-
 
   вольным именем и один знак после него.
 
 
        П р и м е р 3.
 
 
   $ PROMPT_STRING = "CREATING FILE''FILENAME'.TST"
 
 
        Если текущая величина символа  FILENAME  в  примере  3
 
   соответствует строке "BUGS", то результатом замены  символа
 
   будет строка "CREATING FILE BUGS.TST".
 
 
 
                              51 
 
                        000152-01 97 04
 
 
        2.5.2. Использование   знаков   амперсенда   в
 
               качестве операторов замены
 
 
        Амперсенд также может использоваться для запроса заме-
 
   ны символа. Различие действия апострофа и  амперсенда  сос-
 
   тоит в  определении  времени  выполнения  замены.  Символы,
 
   которым предшествует знак апострофа,  заменяются  во  время
 
   первой фазы обработки команды; символы,  которым  предшест-
 
   вует знак амперсенда,  заменяются  во  время  второй  фазы.
 
   Иногда, при использовании этих операторов получается одина-
 
   ковый результат, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $ TYPE 'FILENAME'
   $ TYPE &FILENAME
 
        Если символ FILENAME соответствует строке  "BUGS",  то
 
   обе команды будут  распечатывать  файл  BUGS.LIS.  (команда
 
   тYре по умолчанию использует тип файла LIS).
 
        Однако,  в  некоторых  случаях   пользователь   должен
 
   использовать знак амперсенда для получения нужного  резуль-
 
   тата. Например, когда параметры передаются в командную про-
 
   цедуру, их  значения  присваиваются  символам  P1-P8.  Если
 
   необходимо обратиться к параметрам, которые были переданы в
 
   процедуру, необходимо использовать синтаксис, показанный  в
 
   примере 2.
 
 
        П р и м е р 2.
 
 
   $ PRINT &P'COUNT'
 
  
        В примере 2 распечатывается файл, указанный с  помощью
 
   первого параметра P1. Сначала DCL заменяет символ COUNT  на
 
 
 
                              52 
 
                        000152-01 97 04
 
 
   его величину. Предполагается, что его величина  была  равна
 
   1. Промежуточная строка будет иметь вид,  представленный  в
 
   примере 3.
 
 
        П р и м е р 3.
 
 
   $ PRINT &P1
 
 
        Затем DCL выполняет замену, которая  была  затребована
 
   знаком амперсенда и подставляет надлежащую величину для P1.
 
   Если P1 соответствует COMMENTS.DAT, то результирующая стро-
 
   ка будет иметь вид, представленный в примере 4.
 
 
        П р и м е р 4.
 
 
   $ PRINT COMMENTS.DAT
 
 
        В общем случае амперсенд для замены символа не исполь-
 
   зуется, если это не  требуется  для  корректной  трансляции
 
   символов. В документе [1]  представлена  полная  информация
 
   относительно замены символов.
 
 
 
        2.5.3. Различие между символами и логическими 
 
               именами
 
 
        Легко перепутать символы и логические имена,  особенно
 
   если символы используются на месте спецификаций файла  (как
                                                      
   показано в некоторых предыдущих примерах). Основное  разли-
 
   чие между логическими именами и символами состоит в способе
 
   их трансляции: замену символов выполняет DCL, а  трансляцию
 
   логических имен выполняют обслуживающие программы.
 
        Когда вводится командная строка, DCL проверяет  строку
 
   на корректность. При проверке строки DCL проверяет  символы
 
 
 
                              53 
 
                        000152-01 97 04
 
 
   в местах, где ожидается их присутствие, и в местах,  задан-
 
   ных с помощью операторов замены. После того, как DCL выпол-
 
   нит вычисление элементов командной строки, команда начинает
 
   выполняться. Затем проверяется спецификация файла или  уст-
 
   ройства для определения того, что файл находится в  процес-
 
   се. После этого проверяется, содержит ли спецификация логи-
 
   ческое имя.
 
 
 
 
                3. Ввод-вывод командных процедур
 
 
 
        В этом  разделе  описана  передача  входных  данных  в
 
   командные процедуры и прием выходных  данных  из  командных
 
   процедур. Описываются следующие темы:
 
        1) передача  входных  данных  в  командные  процедуры,
 
   команды и образы, которые выполняются в командной  процеду-
 
   ре;
 
        2) управление выводом из командных процедур;
 
        3) отображение информации на терминале.
 
 
 
        3.1. Передача данных в командные процедуры
 
 
        При создании командной процедуры,  необходимо  предус-
 
   мотреть возможность передачи данных в  командную  процедуру
 
   во время ее выполнения. В языке DCL предусмотрены три  спо-
 
   соба для обеспечения такого ввода:
 
        1) передавать данные в командную процедуру,  используя
 
   параметры;
 
        2) формировать подсказку для пользователя на терминале
 
   и осуществлять ввод данных интерактивно;
 
 
 
 
                              54 
 
                        000152-01 97 04
 
 
        3) читать данные из входного файла.
 
        В следующих пунктах приводится описание передачи пара-
 
   метров и получения данных от пользователя с терминала.
 
        В разделе 6 приведено описание  по  чтению  данных  из
 
   файла.
 
 
 
        3.1.1. Передача параметров
 
 
        При интерактивном выполнении командной процедуры можно
 
   передавать до  восьми  параметров  путем  указания  величин
 
   параметров после спецификации  файла  командной  процедуры.
 
   Для передачи параметров в  пакетное  задание,  используется
 
   квалификатор /PARAMETER более подробное  описание  передачи
 
   параметров в пакетное задание приводится в документе [1].
 
        Величины  параметров  назначаются  локальным  символам
 
   P1-P8.
 
 
        П р и м е р 1.
 
 
   $ @COPYSORT INSORT.DAT OUTSORT.DAT
 
        Когда выполняется процедура из примера  1,  передаются
 
   два параметра:
 
        1) INSORT.DAT
        2) OUTSORT.DAT
 
        Первый параметр (P1) имеет величину INSORT.DAT; второй
 
   параметр (P2) имеет величину OUTSORT.DAT.
 
        Командная процедура COPYSORT.COM может затем использо-
 
   вать символы P1 и P2 для обращения к файлам при их обработ-
 
   ке.
 
 
 
 
 
 
 
 
                              55 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
 
 
   $! копирование и сортировка файла
   $  COPY 'P1' USER_DISK:[MARY]*.*
   $  SORT 'р1' 'р2'
 
        Командная  процедура  в  примере   2   копирует   файл
 
   INSORT.DAT в USER_DISK:[MARY] *.* . Затем сортируется  файл
 
   INSORT.DAT и отсортированный файл помещается в OUTSORT.DAT.
 
        Используя параметры, можно обрабатывать различные фай-
 
   лы без изменения  процедуры.  Различные  файлы  задаются  в
 
   качестве параметров при вызове процедуры.
 
        Перечисление параметров в командной строке  необходимо
 
   разделять одним или несколькими пробелами и/или  табуляция-
 
   ми. Для передачи пустого параметра используется пара знаков
 
   кавычек в качестве указателя места в командной строке.
 
 
        П р и м е р 3.
 
 
   $ @COPYFILES " " USER_DISK:[MARY]*.*
 
 
        В примере 3, при выполнении  файла  COPYFILES.COM,  P1
 
   будет пустой строкой, а параметр P2  будет  иметь  величину
 
   "USER_DISK:[MARY]*.*".
 
        Можно задать параметр в качестве  целого,  строки  или
 
   символа. Если параметр задается как целое, то при  назначе-
 
   нии параметров символам P1+P8, целое преобразуется в  стро-
 
   ку. Например:
 
   $ @OADDER 24 25
 
        В этом случае символ P1 получает значение типа  строки
 
   "24", а параметр P2 получает  значение  типа  строки  "25".
 
   (можно, однако, использовать символ  P1  в  выражениях  как
 
   целое, так и как символьную строку; DCL будет автоматически
 
   выполнять необходимые преобразования).
 
 
                              56 
 
                        000152-01 97 04
 
 
        Если значение задается в качестве строки, DCL  автома-
 
   тически преобразует буквы в строке в прописные  буквы.  Для
 
   сокращения пробелов, табуляций и строчных  букв  необходимо
 
   заключать строки в знаки кавычек. Если необходимо  передать
 
   меньше восьми параметров, то оставшимся символам  назначают
 
   пустые строки. При попытке передать больше восьми  парамет-
 
   ров пользователь получит сообщение об  ошибке  и  командная
 
   процедура не будет выполняться.
 
        Командная процедура PARAMS.COM в примере 4  отображает
 
   параметры, переданные в процедуру.
 
 
        П р и м е р 4.
 
 
   $! отображение параметров
   $  SHOW SYMBOL/LOCAL ALL
 
        Можно выполнить процедуру с параметрами, как  показано
 
   в примере 5.
 
 
        П р и м е р 5.
 
 
   $ @PARAM PAUL CRAMER
   р8 = ""
   р7 = ""
   р6 = ""
   р5 = ""
   р4 = ""
   р3 = ""
   р2 = "CRAMER"
   р1 = "PAUL"
 
        Параметру P1 назначается величина "PAUL", а  параметру
 
   P2 назначается величина "CRAMER";  строки  преобразуются  в
 
   прописные буквы, так как они не заключены в знаки кавычек.
 
        В примере 6  передается  только  один  параметр  "PAUL
 
   CRAMER", знаки кавычек сохраняют строчные буквы и пробелы.
 
 
 
 
 
 
 
                              57 
 
                        000152-01 97 04
 
 
        П р и м е р 6.
 
 
   $ @PARAMS "PAUL CRAMER"
   P8 = ""
   P7 = ""
   P6 = ""
   P5 = ""
   P4 = ""
   P3 = ""
   P2 = ""
   P1 = "PAUL CRAMER"
 
        При запуске вложенной процедуры, создаются новые  сим-
 
   волы P1-P8 в таблице локальных символов для вложенной  про-
 
   цедуры. Эти символы получают новые значения указанные,  при
 
   запуске вложенной процедуры.
 
 
 
        3.1.2. Подсказки для ввода                    
 
 
        Можно использовать команду INQUIRE для подсказки  вво-
 
   да,  который  будет  использоваться  командной  процедурой.
 
   Команда INQUIRE формирует подсказку, читает ответ пользова-
 
   теля с терминала и назначает его для символа:
 
   $ INQUIRE FILE "FILENAME"
 
        Эта команда формирует подсказку "FILENAME" на термина-
 
   ле пользователя и назначает ответ символу FILE.
 
        По умолчанию, команда INQUIRE  добавляет  двоеточие  и
 
   пробел в конце строки подсказки. Они могут быть подавлены с
 
   помощью квалификатора /NOPUNCTUATION как описано в докумен-
 
   те [1].
 
        Команда INQUIRE преобразует ответ пользователя в  про-
 
   писные буквы, заменяет  многократные  пробелы  и  табуляции
 
   одним пробелом и удаляет ведущие и конечные пробелы. Коман-
 
   да INQUIRE также выполняет замену апострофа для символов  и
 
   лексических функций.
 
 
 
 
                              58 
 
                        000152-01 97 04
 
 
        Для сохранения строчных букв, многократных пробелов  и
 
   табуляций, необходимо заключать ответ в знаки кавычек.  Для
 
   включения знаков кавычек в ответ, необходимы две пары  зна-
 
   ков кавычек, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $ INQUIRE FILE "FILENAME"
     FILENAME: "OZ""WITCH CLENDA""::[CLENDA]SPELLS.DAT"
   $ SHOW SYMBOL FILE
     FILE = "OZ"WITCH CLENDA"::[CLENDA]SPELLS.DAT"
 
        Обычно, при указании строки  управления  доступом,  ее
 
   необходимо заключать в знаки кавычек. Однако, при ее указа-
 
   нии в ответе для команды INQUIRE,  необходимо  использовать
 
   двойные знаки кавычек.
 
        Можно также использовать команду  READ  для  получения
 
   данных и сохранения исходных  пробелов  и  знаков  кавычек.
 
   Используя команду READ, пользователь  не  должен  заключать
 
   свой ответ в знаки кавычек или использовать две пары знаков
 
   кавычек.
 
 
        П р и м е р 2.
 
 
   $ READ/PROMPT="FILENAME:"SYS$COMMAND FILE
     FILENAME:OZ"WITCH GLENDA"::[GLENDA]SPELLS.DAT
   $ SHOW SYMBOL FILE
     FILE = "OZ"WITCH GLENDA"::[GLENDA]SPELLS.DAT
 
        Рекомендуется составлять процедуру таким образом, что-
 
   бы можно было либо принимать  параметры,  либо  формировать
 
   подсказку для ввода пользователя.
 
 
        П р и м е р 3.
 
 
   $! подсказка для имени файла, если имя не передается
   $! в качестве параметра
   $  IF P1 EQS. "" THEN INQUIRE P1 "FILENAME"
   $  COPY 'P1' DISK5:[RESERVED]*.*
 
 
 
                              59 
 
                        000152-01 97 04
 
 
        П р и м е ч а н и е. Когда командная процедура  запус-
 
   кается как пакетное задание, величина символа,  заданная  в
 
   команде INQUIRE, читается из строки  данных,  следующей  за
 
   командой INQUIRE. Если строка  данных  не  задана,  символу
 
   назначается нулевая величина.
 
 
 
        3.2. Передача данных в команды и образы                        
 
 
        При выполнении системных образов и образов пользовате-
 
   ля  они  в  основном  получают  ввод  из  входного   потока
 
   SYS$INPUT (входного потока по умолчанию), который в команд-
 
   ной процедуре назначается на файл командных процедур.  Сле-
 
   довательно, если для образов требуются входные  данные,  то
 
   они будут  просматриваться  в  файле  командной  процедуры.
 
   Однако, если необходимо  ввести  данные  из  другого  файла
 
   (такого, как терминал), то можно переопределить  SYS$INPUT.
 
   В следующих пунктах описаны различные  методы  по  передаче
 
   данных в команды и образы.
 
 
 
        3.2.1. Включение данных в командную процедуру                  
 
 
        Следующая командная процедура выполняет прогон  образа
 
   CENSUS.EXE, для которого требуемые входные данные передают-
 
   ся в строках данных.  Образ  CENSUS.EXE  получает  ввод  из
 
   входного потока  по  умолчанию  SYS$INрUT,  то  есть  файла
 
   командных процедур.
 
 
        Пример 1.
 
 
   $! выполнение CENSUS
   $  RUN CENSUS
   1981
   1982
   1983
 
 
                              60 
 
                        000152-01 97 04
 
 
        Текст в строках данных  примера  1  передается  непос-
 
   редственно в образ сеNSUS.ехе без обработки DCL.  Пользова-
 
   тель не может включать символы или выражения  языка  DCL  в
 
   строки данных, так  как  DCL  не  будет  иметь  возможности
 
   выполнить трансляцию символов или вычислить выражение. Так-
 
   же, в строке данных нельзя указывать комментарии с  помощью
 
   восклицательного знака (если образ не интерпретирует  воск-
 
   лицательный знак как ограничитель).
 
        Для включения строк данных, которые начинаются со зна-
 
   ка "$", во входном  потоке  необходимо  определять  входные
 
   данные таким способом,  который  защищал  бы  интерпретатор
 
   команд от попытки выполнения данных в качестве команд.  Для
 
   ограничения такого  входного  потока  используются  команды
 
   DECK и EOD (конец данных).
 
 
        П р и м е р 2.
 
 
   $! все между командами DECK и EOD написано для файла
   $! WEATHER.COM
   $!
   $  CREATE WEATHER.COM
   $  DECK
   $  FORTRAN WEATHER
   $  LINK WEATHER
   $  RUN WEATHER
   $  EOD
   $!
   $! теперь выполнить WEATHER.COM
   $  WEATHER
   $  EXIT
 
        Командная процедура в примере 2  создает  и  выполняет
 
   файл WEATHER.COM. Так как строки данных начинаются со знака
 
   "$", эти строки ограничиваются командами DECK и EOD.
 
        Также можно размещать программы для компилятора в фай-
 
   ле командных процедур с помощью назначения имени файла дан-
 
   ных на SYS$INPUT. В этом случае компилятор читает программу
 
   из командной процедуры, а не из  другого  файла.  Пример  3
 
 
                              61 
 
                        000152-01 97 04
 
 
   иллюстрирует  командную  процедуру,  в  которой  содержится
 
   команда FORTRAN,  за  которой  следуют  операторы  исходной
 
   программы.
 
 
        П р и м е р 3.
 
 
   $ FORTRAN/OBJECT=TESTER/LIST=TESTER SYS$INPUT
     (это программа проверки)
     A = 1
     B = 2
     STOP
     END
   $ PRINT TESTER.LIS
 
        В примере 3 команда FORTRAN использует логическое  имя
 
   SYS$INPUT для идентификации файла, подлежащего  компиляции.
 
   Так как SYS$INPUT назначен на командную процедуру, то  ком-
 
   пилируются операторы, следующие  за  командой  FORTRAN  (до
 
   следующей строки, которая начинается со знака  "$").  Когда
 
   компиляция  завершается,  создаются  два  выходных   файла:
 
   TESTER.OBJ и TESTER.LIS. Затем  выполняется  команда  PRINT
 
   для распечатки выходного файла листинга.
 
        Включение данных  в  командную  процедуру  оказывается
 
   полезным, если всегда передаются одинаковые данные в коман-
 
   ду или образ, прогон которых выполняется. Однако, если есть
 
   необходимость в передаче различных  данных  без  перезаписи
 
   командной процедуры,  можно  переопределить  SYS$INPUT  для
 
   любого терминала или файла данных.
 
 
 
        3.2.2. Передача данных в вызываемый образ                 
 
 
        Если выполняется прогон образа из командной  процедуры
 
   и данные передаются в образ в диалоговом режиме, необходимо
 
   переопределить SYS$INPUT на терминал запуска. Это переопре-
 
   деление необходимо выполнить в пределах командной  процеду-
 
 
 
                              62 
 
                        000152-01 97 04
 
 
   ры, используя команду DEFINE. Когда пользователь определяет
 
   SYS$INPUT как свой терминал, образ, который  вызывается  из
 
   командной процедуры, будет получать ввод с терминала  поль-
 
   зователя, а не из строк данных в командной процедуре.  Этот
 
   метод получения данных необходимо использовать  только  при
 
   интерактивном выполнении командной процедуры.
 
        Для переопределения SYS$INPUT в качестве своего терми-
 
   нала, используется логическое имя SYS$COMMAND для  указания
 
   своего терминала. (SYS$COMMAND является логическим  именем,
 
   которое по умолчанию назначено на терминал пользователя.)
 
        Когда пользователь переопределяет SYS$INPUT (или любое
 
   другое логическое  имя  для  постоянного  файла  процесса),
 
   рекомендуется использовать квалификатор /USER_MODE.  Квали-
 
   фикатор /USER_MODE создает временное назначение логического
 
   имени, которое действует только  до  завершения  следующего
 
   образа.
 
        Например, если выполняется образ CENSUS.EXE и требует-
 
   ся ввести номер года в диалоговом режиме, тогда в процедуру
 
   можно включить команды, приведенные в примере 1.
 
 
        П р и м е р 1.
 
 
   $! выполнить CENSUS получая данные с терминала
   $  DEFINE/USER_MODE SYS$INPUT SYS$COMMAND
   $  RUN CENSUS
   $  EXIT
 
        Команда DEFINE/USER_MODE переопределяет  SYS$INPUT  на
 
   терминал на время выполнения CENSUS.EXE.  После  завершения
 
   образа CENSUS.EXE временное назначение отменяется.
 
        SYS$INPUT необходимо переопределить для  использования
 
   команд или  обслуживающих  программ,  которые  интерактивно
 
   запрашивают ввод. Например, командная процедура в примере 2
 
 
 
                              63 
 
                        000152-01 97 04
 
 
   использует редактор EDT.
 
 
        П р и м е р 2.
 
 
   $! получить список своих файлов
   $  DIRECTORY
   $!
   $! получить имя файла и вызвать редактор EDT
   $  EDIT_LOOP:
   $  INQUIRE FILE "FILE TO EDIT (PRESS RET TO END)"
   $  IF FILE .EGS. "" THEN EXIT
   $  DEFINE/USER_MODE SYS$INPUT SYS$COMMAND
   $  EDIT 'FILE'
   $  GOTO EDIT_LOOP
 
        Эта командная процедура запрашивает  имена  файлов  до
 
   тех пор, пока пользователь не завершит цикл  вводом  RETURN
 
   (возврат каретки). Когда  пользователь  вводит  имя  файла,
 
   процедура автоматиески вызывает редактор EDT для редактиро-
 
   вания файла. Во время работы редактора, SYS$INPUT  назначен
 
   на терминал, так что пользователь  может  вводить  редакции
 
   интерактивно.
 
 
 
        3.2.3. Определение SYS$INPUT в качестве файла          
 
 
        Можно также переопределить SYS$INPUT для файла данных.
 
   Например, командная процедура в следующем примере выполняет
 
   образ CENSUS.EXE и  обеспечивает  входные  данные  в  файле
 
   YEARS.DAT.
 
 
        П р и м е р.
 
 
   $! выполнить сеNSUS, используя данные в файле YEARS.DAT
   $ DEFINE/USER_MODE SYS$INPUT YEARS.DAT
   $ RUN CENSUS
   $ EXIT
 
 
 
 
 
 
 
 
 
                              64 
 
                        000152-01 97 04
 
 
        3.3. Перенаправление  вывода  из   командных               
 
             процедур         
 
 
        Командные процедуры могут перенаправлять вывод следую-
 
   щими путями:
 
        1) записывать данные в выходной файл по умолчанию  или
 
   перенаправить данные в другой файл;
 
        2) отображать сообщение об ошибке, когда  имеют  место
 
   определенные типы ошибок;
 
        3) возвращать величины в качестве глобальных  символов
 
   или логических имен;
 
        4) отображать проверку командных строк и строк данных.
 
 
 
        3.3.1. Перенаправление  вывода  из   командных          
 
               процедур              
 
 
        В общем случае, когда пользователь выполняет командную
 
   процедуру интерактивно, она отображает вывод  на  терминале
 
   пользователя, так как командная процедура передает вывод  в
 
   файл SYS$OUTPUT, который по умолчанию определен как  терми-
 
   нал пользователя. Пакетные задания передают  вывод  в  файл
 
   регистрации пакетного задания. Для получения более  подроб-
 
   ной информации относительно вывода пакетного  задания  сле-
 
   дует обратиться к разделу 8.
 
        Пользователь может перенаправить вывод  в  файл  путем
 
   использования квалификатора /OUTPUT.  В  примере  вывод  из
 
   SETD.сом записывается в файл RESULTS.TXT вместо терминала.
 
 
        П р и м е р.
 
 
   $ @SETD/OUTPUT=RESULTS.TXT
 
 
 
 
                              65 
 
                        000152-01 97 04
 
 
        В примере все выводные данные записываются в  файл  на
 
   диске с именем RESULTS.TXT. В дальнейшем с помощью  команды
 
   тYре можно отобразить  файл  на  терминале  или  с  помощью
 
   команды PRINT распечатать его.
 
 
        П р и м е ч а н и е. Квалификатор  /OUTPUT  помещается
 
   непосредственно после имени файла командной  процедуры  без
 
   внутренних пробелов. В противом случае DCL будет  интерпре-
 
   тировать  квалификатор  как  параметр,  который  необходимо
 
   передать в процедуру.
 
        Когда пользователь перенаправляет вывод командной про-
 
   цедуры в файл,  процедура  будет  передавать  сообщение  об
 
   ошибке и на терминал, и в файл, который принимает вывод.
 
 
 
        3.3.2. Перенаправление  вывода  из  команд   и  
 
               образов                 
 
 
        Для перенаправления вывода из  отдельной  команды  или
 
   образа используется квалификатор /OUTPUT с данной  командой
 
   (если команда имеет квалификатор /OUTPUT)  или  переопреде-
 
   ляется SYS$OUTPUT на время выполнения команды.
 
        Например,  для  перенаправления  вывода   из   команды
 
   DIRECTORY, можно использовать квалификатор /OUTPUT.
 
 
        П р и м е р 1.
 
 
   $! направить вывод из команды DIRECTORY в файл NUMBER.DAT
   $! накапливать эту информацию в GRAND_TOTAL.DAT
   $  DIRECTORY/TOTAL/OUTPUT=NUMBER.DAT
   $  APPEND/LOG NUMBER.DAT GRAND_TOTAL.DAT
   $  EXIT
 
        В примере 1, при запуске этой  процедуры  квалификатор
 
   /OUTPUT не используется.
 
 
 
 
                              66 
 
                        000152-01 97 04
 
 
        Однако,  некоторые  команды  не   имеют   квалификатор
 
   /OUTPUT. Для перенаправления вывода из таких команд времен-
 
   но переопределяется SYS$OUTPUT в файл.
 
        SYS$OUTPUT являтся логическим именем,  которое  обычно
 
   команды и образы используют для определения  вывода.  Можно
 
   также переопределить SYS$OUTPUT для перенаправления  вывода
 
   из программы, составленной пользователем.
 
        В примере 2  показано,  каким  образом  перенаправлять
 
   вывод из команды SHOW USERS в файл. Новое  определение  для
 
   SYS$OUTPUT влияет только на выполнение команды SHOW  USERS.
 
   Затем SYS$OUTPUT возвращается к своему опредению по умолча-
 
   нию (терминал).
 
 
        П р и м е р 2.
 
 
   $ DEFINE/USER_MODE SYS$OUTPUT SHOW_USER.DAT
   $ SHOW USERS
   $!
   $! обработать информацию в SHOW_USER.DAT
   $ OPEN/READ INFILE SHOW_USER.DAT
   $ READ INFILE RECORD
     .
     .
     .
   $ CLOSE INFILE
 
        Для подавления вывода из команды, SYS$OUTPUT  временно
 
   определяется как нулевое устройство, как показано в примере
 
   3.
 
 
        П р и м е р 3.
 
 
   $ DEFINE/USER_MODE SYS$OUTPUT NL:
   $ APPEND NEW_DATA.DAT STATS.DAT
    .
    .
    .
 
        Команду DEFINE/USER_MODE нельзя использовать для пере-
 
   направления вывода из команд DCL, которые выполняютя в пре-
 
 
 
                              67 
 
                        000152-01 97 04
 
 
   делах интерпретатора  команд.  Однако  можно  перенаправить
 
   вывод из этих команд с  помощью  переназначения  SYS$OUTPUT
 
   командой  DEFINE.  Затем  назначение  отменяется   командой
 
   DEASSIGN, как показано в примере 4.
 
 
        П р и м е р 4.
 
 
   $ DEFINE SYS$OUTPUT TIME.DAT
   $ SHOW TIME
   $ DEASSIGN SYS$OUTPUT
 
        После отмены назначения SYS$OUTPUT с  помощью  команды
 
   DEASSIGN, восстанавливается его значение  по  умолчанию.  В
 
   табл. 2 перечислены команды, которые выполняются в пределах
 
   интерпретатора команд.
 
 
 
 
                                                    Таблица 2
 
      Kоманды, выполняемые в пределах интерпретатора команд
 
   ----------------------------------------------------------
                            !                !
   =                        ! DEPOSIT        ! SET PROMPT
                            !                !
   ALLOCATE                 ! DISCONNECT     ! SET PROTEC -
                            !                ! TION/DEFAULT
                            !                !
   ASSIGN                   ! EOD            ! SET UIC
                            !                !
   ATTACH                   ! EXAMINE        ! SET VERIFY
                            !                !
   CANCEL                   ! EXIT           ! SHOW DEFAULT
                            !                !
   CLOSE                    ! GOTO           ! SHOW KEY
                            !                !
   CONNECT                  ! IF             ! SHOW QUOTA
                            !                !
   CONTINUE                 ! INQUIRE        ! SHOW PROTEC-
                            !                ! TION
                            !                !
   CREATE/LOGICAL_NAME_TABLE! ON             ! SHOW STATUS
                            !                !
   DEALLOCATE               ! OPEN           ! SHOW SYMBOL
                            !                !
   DEASSIGN                 ! READ           ! SHOW TIME
                            !                !
   DEBUG                    ! RECALL         ! SHOW TRANS-
                            !                ! LATION
 
 
                              68 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 2
   ----------------------------------------------------------
                            !                !
   DECK                     ! SET CONTROL    ! SPAWN
                            !                !
   DEFINE                   ! SET DEFAULT    ! STOP
                            !                !
   DEFINE/KEY               ! SET KEY        ! WAIT
                            !                !
   DELETE/KEY               ! SET ON         ! WRITE
                            !                !
   DELETE/SYMBOL            ! SET OUTPUT_RATE!
                            !                !
 
 
        3.3.3. Перенаправление сообщений об ошибках 
 
 
        По умолчанию, командные процедуру  передают  сообщения
 
   об ошибках в файл, указанный логическим  именем  SYS$ERROR.
 
   Можно переопределить SYS$ERROR, чтобы  направить  сообщения
 
   об ошибках  в  заданный  файл.  Однако,  если  пользователь
 
   переопределяет SYS$ERROR, а не SYS$OUTPUT (или если пользо-
 
   ватель  переопределяет  SYS$OUTPUT   без   соответствующего
 
   переопределения SYS$ERROR), команды  DCL  будут  передавать
 
   сообщения об ошибках и  неисправимых  ошибках  как  в  файл
 
   SYS$ERROR, так и в файл SYS$OUTPUT. Следовательно,  пользо-
 
   ватель будет принимать эти сообщения дважды: в  файл,  ука-
 
   занный с помощью определения SYS$ERROR и в файл,  указанный
 
   с помощью SYS$OUTPUT.
 
        Сообщения об успешном завершении, информационные сооб-
 
   щения и предупреждающие сообщения будут передаваться только
 
   в файл, указанный с помощью SYS$OUTPUT.
 
        Командная процедура в примере 1 принимает имя каталога
 
   в качестве параметра, устанавливает значение  по  умолчанию
 
   для этого каталога и очищает файлы в  каталоге.  Для  того,
 
   чтобы подавить сообщения  об  ошибках,  процедура  временно
 
   определяет SYS$ERROR и SYS$OUTPUT как нулевое устройство.
 
 
 
 
                              69 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $! очистить файлы в каталоге и подавить сообщения
   $  SET DEFAULT 'P1'
   $! подавить сообщение
   $  DEFINE/USER_MODE SYS$ERROR NL:
   $  DEFINE/USER_MODE SYS$OUTPUT NL:
   $  PURGE
   $  EXIT
 
        Для  подавления  сообщений  можно  также  использовать
 
   команду SET MESSAGE, как показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $! очистить файлы в каталоге и подавить сообщения
   $  SET DEFAULT 'P1'
   $! подавить сообщения
   $  SET MESSAGE/NOFACILITY -
           /NOIDENTIFICATION -
           /NOSEVERITY -
           /NOTEXT
   $  PURGE
   $  SET MESSAGE/FACILITY -
           /IDENTIFICATION -
           /SEVERITY
           /TEXT
   $ EXIT
 
        Если в командной процедуре выполняется  пользовательс-
 
   кая программа и она обращается к SYS$ERROR, то сообщения об
 
   ошибках передаются  только  в  файл,  указанный  с  помощью
 
   SYS$ERROR  -  даже  если  SYS$ERROR  будет  отличаться   от
 
   SYS$OUTPUT. Только команды DCL  и  программы,  использующие
 
   стандартные механизмы отображения ошибок операционной  сис-
 
   темы МОС ВП, передают  сообщения  об  ошибках  как  в  файл
 
   SYS$ERROR, так и в файл SYS$OUTPUT.
 
 
 
        3.3.4. Использование глобальных  символов  для        
 
               возврата данных
 
 
        Для возврата величины из командной процедуры (либо для
 
   вызывающей процедуры, либо для командного уровня DCL) можно
 
 
                              70 
 
                        000152-01 97 04
 
 
   назначить величину глобальному символу, так как  глобальный
 
   символ можно читать на любом командном уровне. Пользователь
 
   должен использовать комментарии для пояснения использования
 
   любых глобальных символов.
 
        Командная процедура AVERAGE.COM в примере 1  вычисляет
 
   среднее значение для восьми чисел, которые  передаются  как
 
   параметры.
 
 
        П р и м е р 1.
 
 
   $! найти сумму чисел (SUM) и определить, для скольких
   $! чисел определялась средняя величина (COUNT)
   $  IF P1 .EQS. "" THEN GOTO ERR
   $  COUNT = 1
   $  SUM = 0
   $  LOOP:
   $  IF P'COUNT' .EQS. "" THEN GOTO DONE
   $  SUM = &P'COUNT' + SUM
   $  SOUNT = COUNT + 1
   $  GOTO LOOP
   $
   $! вычислить среднюю величину и запомнить ее в глобальном
   $! символе AVERAGE
   $  DONE:
   $  AVERAGE == SUM/(COUNT-1)
   $  EXIT
   $
   $  ERR:
   $  WRITE SYS$OUTPUT "чисел нет"
   $  EXIT
 
        Пользователь   может   вызвать   командную   процедуру
 
   AVERAGE.COM из другой процедуры и затем  использовать  гло-
 
   бальный символ AVERAGE для индикации средней величины,  как
 
   показано в примере 2.
 
 
        П р и м е р 2.
 
 
     .
     .
     .
   $ @AVERAGE 34 60 22 86
   $ WRITE SYS$OUTPUT "средняя величина",AVERAGE
 
 
 
 
 
                              71 
 
                        000152-01 97 04
 
 
        3.3.5. Использование   логических   имен   для 
 
               возврата данных
 
 
        Логические имена можно использовать для возврата  дан-
 
   ных из вложенной командной процедуры в вызывающую  процеду-
 
   ру. Логическое имя, определенное командой DEFINE,  доступно
 
   из любого командного уровня. Следующая командная  процедура
 
   REPORT.COM получает имя файла для отчета.  Затем  процедура
 
   определяет логическое имя REPORT_FILE, используя имя,  вве-
 
   денное пользователем. Наконец, процедура выполняет програм-
 
   му, которая записывает отчет в файл REPORT_FILE, как  пока-
 
   зано в примере 1.
 
 
        П р и м е р 1.
 
 
   $! получить имя файла и затем выполнить REPRRT.EXE для
   $! записи отчета в файл
   $!
   $  INQUIRE FILE "NAME OF REPORT FILE"
   $  DEFINE/NOLOG REPORT_FILE 'FILE'
   $  RUN REPORT
   $  EXIT
 
        Если   из   одной   процедуры   вызывается   процедура
 
   REPORT.COM для создания файла отчета, то вызывающая  проце-
 
   дура может  использовать  логическое  имя  REPORT_FILE  для
 
   обращения к файлу отчета, как показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $! командная процедура, которая корректирует файлы
   $! данных и дополнительно подготавливает отчеты
   $  UPDATE:
      .
      .
      .
   $  INQUIRE REPORT "PREPARE A REPORT (Y OR N)"
   $  IF REPORT THEN GOTO REPORT_SEC
   $  EXIT
   $!
   $  REPORT_SEC:
   $  @REPORT
 
 
                              72 
 
                        000152-01 97 04
 
 
   $  WRITE SYS$OUTPUT "REPORT WRITTEN TO",F$TRNLNM -
      ("REPORT_FILE")
   $  EXIT
 
 
        3.3.6. Проверка выполнения командных процедур         
 
 
        По умолчанию, когда процедуры выполняются  интерактив-
 
   но, на экране терминала отображается только вывод команд  и
 
   образов. Если необходим  просмотр  командных  строк,  строк
 
   данных  и  строк  комментариев,  используется  команда  SET
 
   VERIFY. Команду SET VERIFY можно ввести  либо  в  командной
 
   процедуре, либо на интерактивном командном уровне.
 
        Команда SET VERIFY влияет на все  командные  процедуры
 
   до тех пор, пока не будет введена команда SET NOVERIFY.
 
        Для отображения строк в определенной командной  проце-
 
   дуре, можно поместить команду SET VERIFY в начале процедуры
 
   и команду SET NOVERIFY в конце, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $! включите проверку
   $  SET VERIFY
   $  LOOP:
   $      INQUIRE FILE "FILE NAME"
   $      IF FILE .EQS."" THEN EXIT
   $      PRINT 'FILE'
   $      GOTO LOOP
   $! выключите проверку
   $  SET NOVERIFY
 
        Если интерактивно выполняется  процедура,  которая  не
 
   содержит команду SET VERIFY (а также не содержит обработчик
 
   прерываний CTRL/Y), и необходимо, после  начала  выполнения
 
   просмотреть командные строки и строки данных,  можно  прер-
 
   вать процедуру  вводом  управляющего  символа  CTRL/Y,  как
 
   показано в примере 2.
 
 
 
 
 
 
                              73 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
 
 
   $  @MASTER
    ------
   !CTRL/Y!
    ------
   INTERRUPT
   $  SET VERIFY
   $  CONTINUE
   $! следующий шаг выполнения  этой процедуры
      .
      .
      .
 
        Проверка выполнения командных процедур является  инст-
 
   рументом отладки командной процедуры.
 
        Можно использовать команду SET VERIFY со  специальными
 
   ключевыми словами для указания того, что  только  командные
 
   строки или строки данных подлежат проверке. В документе [1]
 
   более подробно описана команда SET VERIFY.
 
        В примере 3 используется лексическая функция F$VERIFY.
 
 
        П р и м е р 3.
 
 
   $! включить проверку
   $  TEMP = F$VERIFY(1)
   $  LOOP:
   $      INQUIRE FILE "FILE NAME"
   $      IF FILE .EQS.""THEN EXIT
   $      PRINT 'FILE'
   $      GOTO LOOP
   $! выключить проверку
   $  темр = F$VERIFY(0)
 
        В разделе 4  описаны  процедуры  сохранения  установок
 
   проверки перед их изменением.
 
 
 
        3.4. Запись данных на терминал                          
 
 
        Имеются несколько способов записи данных на  терминал.
 
   Наиболее часто используются  методы  с  применением  команд
 
   WRITE и TYPE, как описано в этом подразделе.
 
 
 
 
                              74 
 
                        000152-01 97 04
 
 
        3.4.1. Использование команды WRITE                             
 
 
        В командных процедурах, которые  выполняются  интерак-
 
   тивно, можно использовать  команду  WRITE  для  отображения
 
   строк  на  терминале.  Для  этого  задается  выходной  файл
 
   SYS$OUTPUT. Пользователь должен переслать  данные,  которые
 
   необходимо записать как выражение типа строки; данные могут
 
   быть символьной строкой, символом, лексической функцией или
 
   комбинацией этих категорий.
 
        В примере 1  показаны  способы  использования  команды
 
   WRITE.
 
 
        П р и м е р 1.
 
 
   $! запись символьной строки
   $  WRITE SYS$OUTPUT "TWO FILES WERE WRITTEN."
   $!
   $! запись символа
   $  FILE = "STAT1.DAT"
   $  WRITE SYS$OUTPUT FILE
   $!
   $! запись символьной строки, которая содержит символ
   $  AFILE = "STAT1.DAT"
   $  вFILE = "STAT2.DAT"
   $  WRITE SYS$OUTPUT "''AFILE' AND ''BFILE' WERE WRITTEN."
   $!
   $! запись списка элементов
   $  WRITE SYS$OUTPUT AFILE, "AND",BFILE,"WERE WRITTEN."
   $  EXIT
 
        Для отображения длинной строки ее  необходимо  продол-
 
   жить на вторую строку, KAк показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $! запись длинной строки
   $  WRITE SYS$OUTPUT "REPORT BY MARY JONES"+ -
   "  PREPARED APRIL 15, 1984"
   $  EXIT
 
        В примере 3  показано  использование  двойного  набора
 
   знаков кавычек в местах, где должны появиться кавычки.
 
 
 
 
                              75 
 
                        000152-01 97 04
 
 
        П р и м е р 3.
 
 
   $! включение кавычек
   $  WRITE SYS$OUTPUT "SUMMARY OF""Q AND A""SESSION"
   $  EXIT
 
 
        3.4.2. Использование команды TYPE                           
 
 
        Команда TYPE используется для отображения текста  дли-
 
   ной в несколько строк и если не требуется  замена  символа.
 
   Команда тYре записывает данные из файла, заданного  пользо-
 
   вателем, в файл  SYS$OUTPUT.  Для  интерактивной  командной
 
   процедуры, если SYS$INPUT задан в качестве файла, из  кото-
 
   рого предполагается выполнять запись,  команда  TYPE  будет
 
   читать данные из последующих строк данных и  отображать  их
 
   на терминале. Использование команды TYPE показано в следую-
 
   щем примере.
 
 
        П р и м е р.
 
 
   $! использование TYPE для отображения строк
   $  TYPE SYS$INPUT
   $  EXIT
      информационное сообщение
      подготовлено 15 апреля 1984
      предмет: исследование надежности
 
        Строки данных, которые читает TYPE, не  обрабатываются
 
   DCL и, следовательно, символы и выражения в этих строках не
 
   вычисляются. Если необходимо вычислить символы и выражения,
 
   нужно использовать команду WRITE для отображения данных.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              76 
 
                        000152-01 97 04
 
 
        4. Использование символов и лексических функций
 
 
 
        В этом разделе описаны типы информации, которую  можно
 
   получить и  обработать,  используя  символы  и  лексические
 
   функции.  В  этом  разделе  описываются  способы  получения
 
   информации о следующих компонентах системы:
 
        1) процесс пользователя;
 
        2) система;
 
        3) файлы и устройства;
 
        4) логические имена;
 
        5) строки;
 
        6) типы данных.
 
        В приложении 2 перечислены все лексические  функции  и
 
   их аргументы.
 
        Многие  лексические  функции  возвращают   информацию,
 
   которую можно получить, используя команды  DCL.  Однако,  в
 
   командной  процедуре  легче  манипулировать  с  информацией
 
   полученной из лексической функции, а не из команды.  Напри-
 
   мер, для получения имени текущего  каталога  по  умолчанию,
 
   можно использовать либо функцию F$ENVIRONMENT, либо команду
 
   SHOW  DEFAULT.  Если  используется  функция  F$ENVIRONMENT,
 
   результат можно присвоить символу и затем использовать этот
 
   символ в процедуре, как показано в примере.
 
 
        П р и м е р.
 
 
   $ DIR_NAME = F$ENVIRONMENT("DEFAULT")
   $ SET DEFAULT DISK4:[TEST]
     .
     .
     .
   $ SET DEFAULT 'DIR_NAME'
 
        Функция F$ENVIRONMENT возвращает имена текущего  диска
 
 
 
                              77 
 
                        000152-01 97 04
 
 
   и каталога по умолчанию  и  присваивает  результат  символу
 
   DIR_NAME. В дальнейшем  символ  DIR_NAME  используется  для
 
   установки значения  по  умолчанию  с  помощью  команды  SET
 
   DEFAULT.
 
        Если используется команда SHOW DEFAULT, то  получаемое
 
   значение нельзя назначить для символа, и поэтому его  необ-
 
   ходимо перенаправить в файл. Для восстановления каталога по
 
   умолчанию необходимо открыть файл, содержащий вывод команды
 
   SHOW DEFAULT, прочитать его и сделать грамматический разбор
 
   записи, содержащей имя  каталога,  восстановить  каталог  и
 
   закрыть файл. Затем  необходимо  удалить  файл,  содержащий
 
   вывод SHOW DEFAULT.
 
 
 
        4.1. Получение   информации    о    процессе                  
 
             пользователя
 
 
        Следующие лексические функции используются для опреде-
 
   ления информации, относящейся к процессу пользователя:
 
 
   F$DIRECTORY   - возвращает строку текущего каталога по
 
                   умолчанию;
 
 
 
   F$ENVIRONMENT - возвращает информацию командного окружения
 
                   для процесса пользователя;
 
 
 
   F$GETJPI      - возвращает информацию об учете, состоянии
 
                   и идентификации, относящейся к процессу
 
                   пользователя или другим процессам в
 
                   системе;
 
 
 
   F$MODE        - возвращает режим, в котором выполняется
 
 
                              78 
 
                        000152-01 97 04
 
 
                   процесс пользователя;
 
 
 
   F$PRIVILEGE   - указывает на то, имеет ли процесс
 
                   пользователя заданные привилегии;
 
 
 
   F$PROCESS     - возвращает имя процесса пользователя;
 
 
 
   F$SETPRV      - устанавливает заданные привилегии. Эта
 
                   функция также указывает на то, были ли
 
                   разрешены заданные привилегии до того, как
 
                   пользователь применил функцию F$SETPRV;
 
   F$USER        - возвращает код идентификации пользователя;
 
 
 
   F$VERIFY      - указывает на то, включена ли проверка.
 
 
        В табл. 3 представлены характеристики процесса,  кото-
 
   рые обычно изменяются в командной процедуре;  в  ней  также
 
   представлены лексические  функции,  которые  сохраняют  эти
 
   характеристики, и команды языка  DCL,  которые  изменяют  и
 
   восстанавливают исходные установки.
 
                                                    Таблица 3
 
            Oбычно изменяемые характеристики процесса
 
   ----------------------------------------------------------
   Xарактеристики ! Oперации ! Kоманды/лексические функции
   ----------------------------------------------------------
   Yправляющие    !Cокращение!   F$ENVIRONMENT("CONTROL")
   символы        !восстанов-! SET CONTROL
                  !ление     !
                  !          !
   Подсказка DCL  !Сокращение!   F$ENVIRONMENT("PROMPT")
                  !восстанов-! SET PROMPT
                  !ление     !
                  !          !
   Защита по умол-!Сокращение!   F$ENVIRONMENT("PROTECTION")
   чанию          !восстанов-! SET PROTECTION/DEFAULT
                  !ление     !
                  !          !
   Состояние ката-!Сокращение!   F$ENVIRONMENT("KEY_STATE")
 
 
                              79 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 3
   ----------------------------------------------------------
   Характеристики ! Операции ! Команды/лексические функции
   ----------------------------------------------------------
   лога           !Восстанов-! SET KEY
                  !ление     !
                  !          !
   Формат сообще- !Сокращение!   F$ENVIRONMENT("MESSAGE")
   ния            !восстанов-! SET MESSAGE
                  !ление     !
                  !          !
   Привилегии     !Сокращение!   F$рRIVILEGE, F$SEтрRV,
                  !восстанов-! F$SETрRV
                  !ление     ! SET рROсеSS/рRIVILEGES
                  !          !
   Проверка       !Сокращение!   F$VERIFY, F$ENVIRONMENT,
                  !восстанов-! F$VERIFY
                  !ление     ! SET VERIFY
                  !          !
 
        Обычно необходимо восстановление исходных  характерис-
 
   тик процесса в завершении процедуры,  в  том  числе  и  при
 
   завершении процедуры по ошибке или вводу CTRL/Y.
 
        В разделе 7 подробно описана обработка ошибок и преры-
 
   ваний по CTRL/Y.
 
 
 
        4.1.1. Изменения установок проверки                            
 
    
        Один из обычных приемов в командной  процедуре  заклю-
 
   чается в отключении проверки на время выполнения процедуры.
 
   Это защищает пользователей от отображения содержимого  про-
 
   цедуры во время ее выполнения. В командной процедуре  поль-
 
   зователь может установить или блокировать два типа  провер-
 
   ки:
 
        1) проверка процедуры -  отображает  каждую  командную
 
   строку во время ее выполнения;
 
        2) проверка образа - отображает каждую  строку  данных
 
   во время ее обработки.
 
        Команда SET [NO]VERIFY и функция  F$VERIFY  устанавли-
 
   вают или отменяют оба типа проверки, если пользователь спе-
 
 
 
                              80 
 
                        000152-01 97 04
 
 
   циально не затребовал, чтобы изменялся только один тип про-
 
   верки. Перед тем, как пользователь изменит эти установки  в
 
   командной процедуре, он должен сохранить  каждую  установку
 
   отдельно, как показано в примере.
 
 
        П р и м е р.
 
 
   $! сохранить каждое состояние проверки
   $! отключить оба состояния проверки
   $  SAVE_VERIFY_IMAGE=F$ENVIRONMENT("VERIFY_IMAGE")
   $  SAVE_VERIFY_PROCEDURE=F$VERIFY(0)
      .
      .
      .
   $! восстановить исходные состояния проверки
   $  SAVE_VERIFY_IMAGE=F$VERIFY(SAVE_VERIFY_PROCEDURE,-
      SAVE_VERIFY_IMAGE)
 
        В примере функция F$ENVIRONMENT  возвращает  установку
 
   проверки текущего образа и назначает эту  величину  символу
 
   SAVE_VERIFY_IMAGE. Затем,функция F$VERIFY возвращает  уста-
 
   новку проверки текущей процедуры и назначает  эту  величину
 
   символу SAVE_VERIFY_PROCEDURE. Функция F$VERIFY также отме-
 
   няет проверку образа и проверку процедуры.
 
        Для получения установки процедуры  можно  использовать
 
   функцию F$ENVIRONMENT, а затем можно  использовать  функцию
 
   F$VERIFY для  отключения  проверки.  Однако,  использование
 
   функции F$VERIFY для выполнения обеих задач в одной команд-
 
   ной строке короче.
 
        В конце процедуры примера функция F$VERIFY использует-
 
   ся  для  восстановления  исходных  установок  (заданных   с
 
   помощью       символов       SAVE_VERIFY_PROCEDURE        и
 
   SAVE_VERIFY_IMAGE).
 
        Величина, возвращаемая в SAVE_VERIFY_IMAGE, не исполь-
 
   зуется процедурой.
 
 
 
 
 
                              81 
 
                        000152-01 97 04
 
 
        4.1.2. Изменение защиты по умолчанию            
 
 
        Другой  характеристикой,  которая  часто   изменяется,
 
   является код защиты файла по умолчанию. В примере командная
 
   процедура изменяет защиту по умолчанию файлов, созданных во
 
   время выполнения процедуры. Исходная величина  восстанавли-
 
   вается перед завершением процедуры.
 
 
        П р и м е р.
 
 
   $ SAVE_PROT = F$ENVIRONMENT("PROTECTION")
   $ SET PROTECTION=(SYSTEM:RWED,OWNER:RWED,GROUP,WORLD)
    .
    .
    .
   $ SET PROTECTION = 'SAVE_PROT'/DEFAULT
   $ EXIT
 
        Функция F$ENVIRONMENT возвращает код защиты по умолча-
 
   нию, синтаксис которого  соответствует  синтаксису  команды
 
   SET PROTECTION. Это дает  возможность  использовать  символ
 
   SAVE_PROT с командой SET PROTECTION.
 
 
 
        4.2. Получение информации о системе                    
 
 
        Следующие лексические функции используются для получе-
 
   ния информации о системе:
 
 
   F$GETSYI      - возвращает информацию о системе
 
                   пользователя;
 
 
 
   F$IDENTIFIER  - преобразует идентификаторы из приведенного
 
                   в числовой формат и наоборот;
 
 
 
   F$MESSAGE     - возвращает текст сообщения, связанный с
 
                   кодом состояния;
 
 
 
                              82 
 
                        000152-01 97 04
 
 
 
 
   F$PID         - возвращает номер идентификатора процессов,
 
                   для которых предоставлена возможность
 
                   проверки;
 
 
 
   F$TIME        - возвращает текущие дату и время.
 
 
        В пп.4.2.1 и 4.2.2 приводится описание обычно  исполь-
 
   зуемой системной информации.
 
 
 
        4.2.1. Определение имени узла пользователя 
 
 
        Если система является узлом, из которого  пользователь
 
   может регистрироваться во многих  узлах,  можно  установить
 
   подсказку DCL для индикации  текущего  узла.  Для  этого  в
 
   командную процедуру регистрации включается функция F$GETSYI
 
   для определения имени узла. Затем используется команда  SET
 
   PROMPT для установки уникальной подсказки узла, как показа-
 
   но в примере.
 
 
        П р и м е р.
 
 
   $ NODE = F$GETSYI("NODENAME")
   $ SET PROMPT = "''NODE'$"
     .
     .
     .
 
        Если требуется использовать только часть имени узла  в
 
   строке подсказки, используется функция F$EXTRACT для  выде-
 
   ления определенных символов. (в п.4.5.2 приводится дополни-
 
   тельная информация о выделении символов).
 
 
 
 
 
 
 
 
                              83 
 
                        000152-01 97 04
 
 
        4.2.2. Получение информации о процессах              
 
 
        Функция F$PID используется для получения номера  иден-
 
   тификатора процесса (PID) всех процессов, для которых  есть
 
   возможность проверки. Пользователь может получать PID  про-
 
   цессов в системе, если он имеет привилегию WORLD; всех про-
 
   цессов в своей группе, если он имеет привилегию GROUP. Если
 
   пользователь не имеет привилегии WORLD или GROUP, он  может
 
   получить идентификатор только своего процесса.
 
        В примере 1 показано, каким образом получать и отобра-
 
   жать PID для процессов, для которых  предоставлена  возмож-
 
   ность проверки. В начале процедуры отображается время.
 
 
        П р и м е р 1.
 
 
   $ WRITE SYS$OUTPUT F$TIME()
   $!
   $ CONTEXT = ""
   $ START:
   $! получить и отобразить PID, пока функция F$PID не
   $! возвратит пустую строку
   $!
   $  PID = F$PID(CONTEXT)
   $  IF PID .EQS. "" THEN EXIT
   $  WRITE SYS$OUTPUT "PID --- ' 'PID'"
   $  GOTO START
 
        В примере 1 используется символ соNтехт для  указателя
 
   в системном списке PID. Каждый цикл система изменяет указа-
 
   тель для размещения  следующего  PID  в  списке.  Процедура
 
   завершается после того, как будут отображены все PID.
 
        После того,  как  пользователь  получил  идентификатор
 
   PID, он может использовать функцию F$GETJPI  для  получения
 
   специфической информации о процессе. Например, можно  уточ-
 
   нить процедуру так, чтобы она отображала PID и код  иденти-
 
   фикации пользователя (UIC) для каждого процесса.
 
 
 
 
 
                              84 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
 
 
   $  CONTEXT = ""
   $  START:
   $! получить и отобразить PID и коды UIC
   $!
   $  PID = F$PID(CONTEXT)
   $  IF PID .EQS. "" THEN EXIT
   $  UIC = F$GETJPI(PID,"UIC")
   $  WRITE SYS$OUTPUT "PID ---' 'PID' UIC--- ''UIC'"
   $  GOTO START
 
        Можно сократить командную процедуру примера 2, включив
 
   функции F$GETJPI в команду WRITE, как показано в примере 3.
 
 
        П р и м е р 3.
 
 
   $ CONTEXT = ""
   $ START:
   $ PID = F$PID(CONTEXT)
   $ IF PID .EQS. "" THEN EXIT
   $ WRITE SYS$OUTPUT "PID ---''PID'UIC---''F$GETJPI -
     (PID,"UIC")'"
   $ GOTO START
 
 
        4.3. Получение   информации   о   файлах  
 
             устройствах
 
 
        Следующие лексические функции используются для получе-
 
   ния информации о файлах и устройствах:
 
 
   F$FILE_ATTRIBUTES     - возвращает информацию об атрибутах
 
                           файла;
 
 
 
   F$GETDVI              - возвращает информацию об указанном
 
                           устройстве;
 
 
 
   F$PARSE               - выполняет синтаксический разбор
 
                           спецификации файла и возвращает
 
                           требуемое поле (поля);
 
 
 
 
                              85 
 
                        000152-01 97 04
 
 
   F$SEARCH              - выполняет поиск каталога файла.
 
 
        В пп.4.3.1 и 4.3.2 приводится описание обычно  исполь-
 
   зуемой информации о файле.
 
 
 
        4.3.1. Поиск файла в каталоге                                
 
 
 
        Перед обработкой файла  в  командной  процедуре  может
 
   потребоваться проверка того, что файл в это  время  сущест-
 
   вует.
 
        Для этого  используется  функция  F$SEARCH.  Командная
 
   процедура примера 1 использует функцию F$SEARCH для опреде-
 
   ления   того,   что   файл   STATS.DAT    присутствует    в
 
   DISK3:[JONES.WORK].  Если  это  условие   выполняется,   TO
 
   командная процедура обрабатывает файл.
 
        В противном случае командная процедура  выводит  подс-
 
   казку для другого входного файла.
 
 
        П р и м е р 1.
 
 
   $ FILE = F$PARSE("STATS.DAT","DISK3:[JONES.WORK]" -
     ,,,"SYNTAX_ONLY")
   $ IF F$SEARCH(FILE) .EQS. "" THEN GOTO GET_FILE
   $ PROCESS_FILE:
     .
     .
     .
   $ GET_FILE:
   $  INQUIRE FILE "FILE NAME"
   $  GOTO PROCESS_FILE
 
        После определения того,  что  файл  существует,  можно
 
   использовать  функции  F$PARSE  или  F$FILE_ATTRIBUTES  для
 
   получения дополнительной информации о файле, как показано в
 
   примере 2.
 
 
 
 
 
 
                              86 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
 
 
   $ IF F$SEARCH("STATS.DAT") .EQS. ""THEN GOTO GET_FILE
   $ PROCESS_FILE:
   $     NAME = F$PARSE("STATS.DAT", "NAME")
     .
     .
     .
   $ GET_FILE:
   $     INQUIRE FILE "FILE NAME"
   $     GOTO рROсеSS_FILE
 
 
        4.3.2. Удаление старых версий файлов                           
          
 
 
        Если командная процедура  создает  файлы,  которые  не
 
   нужны после завершения процедуры, их следует удалить  перед
 
   завершением процедуры. Команда рURGE используется для  уда-
 
   ления всех копий, кроме самых новых. Команда DELETE исполь-
 
   зуется для удаления всех копий.
 
        Перед удалением файла рекомендуется использовать функ-
 
   цию F$SEARCH для проверки того, что файл  существует.  Сле-
 
   дующая строка формирует команду DELETE только в том случае,
 
   если существует файл TEMP.DAT:
 
   $ IF F$SEARCH("TEMP.DAT") .NES. "" THEN DELETE TEMP.DAT;*
 
 
 
        4.4. Трансляция логических имен                           
 
 
        Для трансляции логических имен используются  следующие
 
   лексические функции:
 
 
   F$LOGICAL     - возвращает строку эквивалентного имени для
 
                   логического имени;
 
 
 
   F$TRNLNM      - возвращает либо строку эквивалентного
 
                   имени, либо запрошенные атрибуты для
 
                   логического имени.
 
 
 
                              87 
 
                        000152-01 97 04
 
 
        В некоторых ситуациях необходимо использовать логичес-
 
   кие имена вместо символов в качестве переменных в командной
 
   строке. Например, может  оказаться,  что  программам  легче
 
   организовать доступ к логическим  именам,  чем  к  символам
 
   языка DCL.
 
 
        П р и м е р 1.
 
 
   $! убедиться, что NAME определено
   $  IF F$TRNLNM("NAMES") .NES. "" THEN GOTO ALL_SET
   $  INQUIRE FILE "файл с именами служащих"
   $  DEFINE NAMES 'FILE'
   $!
   $! запустить PAYROLL, используя файл, указанный с
   $! помощью NAMES
   $  ALL_SET:
   $  RUN PAYROLL
      .
      .
      .
 
        В примере 1 проверяется логическое имя NAMES. Если это
 
   имя определено, то  запускается  PAYROLL.EXE.  В  противном
 
   случае, процедура запрашивает значение для символа  FILE  и
 
   использует его для создания логического имени NAMES.
 
        В примере 1 ввод значения организован с помощью коман-
 
   ды INQUIRE.
 
        Можно также использовать функцию F$TRNLNM для назначе-
 
   ния величины логического имени для символа, как показано  в
 
   примере 2.
 
 
        П р и м е р 2.
 
 
   $ DEFINE NAMES DISK4:[JONES]EMPLOYEE_NAMES.DAT
   $ RUN PAYROLL
     .
     .
     .
   $ FILE =F$TRNLNM(NAMES)
   $ WRITE SYS$OUTPUT "обработка завершена",FILE
 
        В  примере  2  определяется  логическое  имя,  которое
 
 
 
                              88 
 
                        000152-01 97 04
 
 
   используется в программе PAYROLL. В конце процедуры команда
 
   WRITE отображает сообщение о  завершении  обработки  файла.
 
   Так как команда  WRITE  не  транслирует  логические  имена,
 
   необходимо назначить логическое имя (NAMES) символу (FILE).
 
   Затем можно использовать символ FILE для отображения файла.
 
 
 
        4.5. Операции над строками                      
 
 
 
        Для  выполнения  операций  над  символьными   строками
 
   используются следующие лексические функции:
 
 
   F$CVTIME      - возвращает информацию относительно строки
 
                   времени;
 
 
 
   F$EDIT        - редактирует символьную строку;
 
 
 
   F$ELEMENT     - выделяет элемент из строки, в которой
 
                   элементы разделены ограничителями;
 
 
 
   F$EXTRACT     - выделяет подстроку из символьной строки;
 
 
 
   F$FAO         - форматирует выходную строку;
 
 
 
   F$LENGTH      - определяет длину строки;
 
 
 
   F$LOCATE      - размещает символ или подстроку внутри
 
                   строки и возвращает смещение.
 
 
 
 
 
 
 
 
 
                              89 
 
                        000152-01 97 04
 
 
        4.5.1. Определение наличия строки или символа   
 
 
        Одной из обычных причин проверки строк является  необ-
 
   ходимость определения наличия  символа  (или  подстроки)  в
 
   символьной строке. Для этого используются функции  F$LENGTH
 
   и F$LOCATE. Если величина, возвращаемая с  помощью  функции
 
   F$LOCATE, равна величине, возвращаемой  функцией  F$LENGTH,
 
   то исходный символ отсутствует.
 
        Для процедуры в примере требуется имя файла, с  указа-
 
   нием номера версии. Для определения того, что номер  версии
 
   присутствует, выполняется поиск знака точки с запятой (ука-
 
   зывающий на номер версии) в имени файла.
 
 
        П р и м е р.
 
 
   $ INQUIRE FILE "введите имя файла"
   $ IF F$LOCATE (";",FILE) .EQ. F$LENGTH (FILE) THEN -
     GOTO NO_VERSION
     .
     .
     .
 
        Функция F$LOCATE возвращает величину смещения для точ-
 
   ки с запятой. Смещения начинаются с 0; то есть, если  точка
 
   с  запятой  является  первым  символом  в  строке,  функция
 
   F$LOCATE будет возвращать 0. Если точка с запятой  отсутст-
 
   вует в строке, то  функция  F$LOCATE  возвращает  смещение,
 
   которое на единицу больше  смещения  последнего  символа  в
 
   строке.  Эта  величина  соответствует  длине,  возвращаемой
 
   функцией F$LENGTH.
 
 
 
        4.5.2. Выделение части строки                      
 
 
        Для  выделения  строки   используется   либо   функция
 
   F$EXTRACT,  либо  функция  F$ELEMENT.   Функция   F$EXTRACT
 
 
 
                              90 
 
                        000152-01 97 04
 
 
   используется для выделения подстроки, которая начинается  с
 
   определенного смещения; функция F$ELEMENT используется  для
 
   выделения части  строки  между  двумя  ограничителями.  Для
 
   того, чтобы использовать эти функции,  пользователь  должен
 
   знать общий формат обрабатываемой строки.
 
        Для выполнения синтаксического разбора строки специфи-
 
   кации файла или времени, рекомендуется использовать функции
 
   F$PARSE или F$CVTIME.
 
        В примере 1 используется функция F$EXTRACT для выделе-
 
   ния подстроки кода идентификации пользователя.  Это  позво-
 
   ляет выполнять различные наборы  команд  в  зависимости  от
 
   группы пользователей.
 
 
        П р и м е р 1.
 
 
   $ UIC = F$USER()
   $ GROUP_LEN = F$LOCATE(",",UIC) -1
   $ GROUP = F$EXTRACT(1,GROUP_LEN,UIC)
   $ GOTO 'GROUP'_SECTION
     .
     .
     .
   $ WRITERS_SECTION
     .
     .
     .
   $ MANAGERS_SECTION
     .
     .
     .
 
        В примере 1 сначала определяется UIC с помощью функции
 
   F$USER. Затем процедурой определяется длина имени группы  с
 
   использованием функции F$LOCATE  при  определении  смещения
 
   запятой. Между левой квадратной скобкой  и  запятой  всегда
 
   находится  имя  группы.  Например,  имя   группы   из   UIC
 
   [WRITERS,SMITH] соответствует WRITERS.
 
        После  определения  длины  выделяется  имя  группы   с
 
   помощью функции F$EXTRACT. Имя начинается со смещения  1  и
 
 
                              91 
 
                        000152-01 97 04
 
 
   заканчивается символом перед запятой.  Наконец,  управление
 
   передается на требуемую метку.
 
        Длину имени группы можно определить одновременно с его
 
   выделением, как показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $ UIC = F$USER()
   $ GROUP = F$EXTRACT(!,F$LOCATE(",",UIC)-1,UIC)
   $ GOTO 'GROUP'_SECTION
 
        Если строка содержит разделители, используется функция
 
   F$ELEMENT для выделения требуемой части. В примере 3 в коде
 
   защиты каждый тип доступа отделяется запятой.
 
 
        П р и м е р 3.
 
 
   $ PROT = F$ENVIRONMENT("PROTECTION")
   $ SHOW SYMBOL PROT
     PROT = "SYSTEM=RWED, OWNER=RWED, GROUP=RE, WORLD"
 
        Таким образом, можно  использовать  функцию  F$ELEMENT
 
   для получения различных типов доступа путем выделения  час-
 
   тей строки запятыми. Для получения доступа  SYSTEM  опреде-
 
   ляется первый элемент; для получения доступа OWNER  опреде-
 
   ляется второй элемент, и так далее.
 
        В примере 4 выделяется тип  доступа  WORLD  (четвертый
 
   элемент) из кода защиты пользователя по  умолчанию.  Номера
 
   элементов начинаются с  нуля,  следовательно,  используется
 
   целое 3 для задания четвертого элемента.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              92 
 
                        000152-01 97 04
 
 
        П р и м е р 4.
 
 
   $ PROT = F$ENVIRONMENT("PROTECTION")
   $ WORLD_PROT = F$ELEMENT(3,",",PROT)
     .
     .
     .
 
        В примере 4  функция  F$ELEMENT  возвращает  все,  что
 
   находится между третьей  запятой  и  концом  строки.  Таким
 
   образом, если защита по умолчанию разрешает доступ по  чте-
 
   нию для пользователей WORLD, то будет  возвращаться  строка
 
   "WORLD=R".
 
        После получения строки доступа WORLD ее  можно  прове-
 
   рить, как показано в примере 5.
 
 
        П р и м е р 5.
 
 
   $ PROT = F$ENVIRONMENT("PROTECTION")
   $ WORLD_PROT = F$ELEMENT(3,",",PROT)
   $ IF F$LOCATE("=",WORLD_PROT) .EQ. -
     F$LENGTH(WORLD_PROT) -
     THEN GOTO NO_WORLD_ACESS
     .
     .
     .
 
 
        4.5.3. Форматирование выходных строк                           
 
 
        Вывод  строк  можно  осуществлять  с  помощью  команды
 
   WRITE. В примере 1 используется команда WRITE для отображе-
 
   ния имени процесса и кода идентификации процесса.
 
 
        П р и м е р 1.
 
 
   $! создать символ контекста для получения PID
   $  CONTEXT = ""
   $! вывод заголовка
   $  WRITE SYS$OUTPUT "PROCESS NAME PID"
   $!
   $  GET_PID:
   $  PID = F$PID(CONTEXT)
   $  IF PID .EQS. "" THEN EXIT
   $  WRITE SYS$OUTPUT F$GETJPI(PID,"PRCNAM"),"   ", -
 
 
                              93 
 
                        000152-01 97 04
 
 
      F$GETJPI(PID."PID")
   $  GOTO GET_PID
 
   PROCESS NAME    PID
   MARCHESAND    2CA0049C
   TRACTMEN    2CA0043A
   FALLON    2CA0043C
   ODONELL     2CA00453
   PERRIN    2CA004DE
   CHAMPIONS   2CA004E3
 
        Для выравнивания колонок  можно  использовать  функцию
 
   F$FAO, которая определяет поля записи, и поместить имя про-
 
   цесса и имя пользователя в эти поля. В  примере  2  исполь-
 
   зуется функция F$FAO, с помощью которой  определяются  поля
 
   из 16 и 12 символов. Функция F$FAO размещает имя процесса в
 
   первом поле, пропускает нужное число пробелов и затем  раз-
 
   мещает идентификатор процесса (PID) во втором поле.
 
 
        П р и м е р 2.
 
 
   $! создать символ контекста для получения PID
   $  CONTEXT = ""
   $! вывести заголовок
   $  WRITE SYS$OUTPUT "PROCESS NAME PID"
   $!
   $  GET_PID:
   $  PID = F$PID(CONTEXT)
   $  IF PID .EQS. "" THEN EXIT
   $  LINE = F$FAO("!16AS !12AS", F$GETJPI(PID,"PRCNAM"), -
      F$GETJPI(PID,"PID"))
   $  WRITE SYS$OUTPUT LINE
   $  GOTO GET_PID
 
        Теперь при выполнении процедуры колонки будут формати-
 
   роваться правильно.
 
 
   РROCESS NAME    PID
   MARCHESAND      2CA0049C
   TRACTMEN        2CA0043A
   FALLON          2CA0043C
   ODONNELL        2CA00453
   PERRIN          2CA004DE
   CHAMPIONS       2CA004E3
 
        Другой способ форматирования полей в записи состоит  в
 
   использовании  наложения  символьных  строк.  В  примере  3
 
 
 
                              94 
 
                        000152-01 97 04
 
 
   используются наложения для размещения имени процесса в пер-
 
   вых 16 символах (начиная со  смещения  0)  символа  RECORD.
 
   Затем идентификаторы процесса (PID) размещаются в следующих
 
   12 символах (начиная со смещения 17).
 
 
        П р и м е р 3.
 
 
   $! создать символ контекста для получения PID
   $  CONTEXT =""
   $! вывод заголовка
   $  WRITE SYS$OUTPUT "PROCESS NAME PID"
   $!
   $  GET_PID:
   $  PID = F$PID(CONTEXT)
   $  IF PID .EQS. "" THEN EXIT
   $  RECORD[0,16]:= 'F$GETJPI(PID,"PRCNAM")'
   $  RECORD[17,12]:= 'F$GETJPI(PID,"PID")'
   $  WRITE SYS$OUTPUT RECORD
   $  GOTO GET_PID
 
   PROCESS NAME    PID
   MARCHESAND      2CA0049C
   TRACTMEN        2CA0043A
   FALLON          2CA0043C
   ODONNELL        2CA00453
   PERRIN          2CA004DE
   CHAMPIONS       2CA004E3
 
 
        4.6. Операции с типами данных                        
 
 
        Можно использовать следующие лексические  функции  для
 
   преобразования данных из строк в целые и наоборот:
 
 
   F$CVSI        - выделяет битовые поля из символьной строки
 
                   и преобразует результат в целое число со
 
                   знаком;
 
 
 
   F$CVUI        - выделяет битовые поля из символьной строки
 
                   и преобразует результат в целое число без
 
                   знака;
 
 
 
   F$INTEGER     - преобразует выражение типа строки в целое;
 
 
                              95 
 
                        000152-01 97 04
 
 
 
 
   F$STRING      - преобразует целое выражение в строку;
 
 
 
   F$TYPE        - определяет тип данных символов.
 
 
 
        4.6.1. Преобразование типов данных                           
 
 
        Функции F$INTEGER и F$STRING используются для преобра-
 
   зования целых и строк. Командная процедура в примере преоб-
 
   разует типы данных. Если выводится строка, командная проце-
 
   дура  указывает  целый  эквивалент.  Если  вводится  целое,
 
   командная процедура указывает строчный эквивалент.
 
        Функция F$TYPE  используется  для  формирования  имени
 
   метки в операторе GOTO, возвращая "STRING" или "INTEGER"  в
 
   зависимости от типа данных символа.
 
 
        П р и м е р.
 
 
   $ IF P1 .EQS. "" THEN INQUIRE P1 "исходная величина"
   $ GOTO CONVERT_'F$TYPE(P1)'
   $
   $ CONVERT_STRING:
   $ WRITE SYS$OUTPUT "строка ''R1' преобразована -
     ''F$INTEGER(R1)'"
   $ EXIT
   $
   $ CONVERT_INTEGER:
   $ WRITE SYS$OUTPUT "десятичное ''P1' преобразовано -
     ''F$STRING(P1)'"
   $ EXIT
 
 
        4.6.2. Вычисление выражений                    
 
 
        Некоторые команды, такие как INQUIRE и READ, восприни-
 
   мают только  данные  типа  строки.  Если  используются  эти
 
   команды для получения данных, которые необходимо  вычислять
 
   как целые выражения, то  для  преобразования  и  вычисления
 
   таких данных используется функция F$INTEGER.
 
 
                              96 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $ INQUIRE EXP "введите десятичное выражение"
   $ RES = F$INTEGER('EXP')
   $ WRITE "результат", RES
 
        В примере 2 показан вывод из командной процедуры  при-
 
   мера 1.
 
 
        П р и м е р 2.
 
 
   Введите десятичное выражение: 9 + 7
   результат 16
 
 
        4.6.3. Определение существования символа        
 
 
        Для  определения  существования  символа  используется
 
   функция F$TYPE. Если символ не определен,  функция  возвра-
 
   щает пустую строку.
 
 
        П р и м е р.
 
 
   $ IF F$TYPE(TEMP) .EQS. "" THEN TEMP = "YES"
   $ IF TEMP .EQS. "YES" THEN GOTO TEMP_SEC
 
        Процедура в примере проверяет, был ли ранее  определен
 
   символ темр. Если символ темр был определен , то сохраняет-
 
   ся его текущая величина темр. Если символ темр не был опре-
 
   делен, то оператор IF присваивает ему величину "YES".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              97 
 
                        000152-01 97 04
 
 
           5. Разработка и логика командных процедур
 
 
 
        Обычно команды в процедуре  выполняются  в  последова-
 
   тельном порядке, пока не будет достигнут конец файла. Одна-
 
   ко, часто возникает необходимость управления ходом выполне-
 
   ния в зависимости от того, что: (1)  выполнен  определенный
 
   оператор, (2) произошло изменение состояний в соответсвии с
 
   которыми процедура должна продолжить выполнение.
 
        В этом разделе обсуждаются  команды,  которые  исполь-
 
   зуются для управления потоком выполнения командной процеду-
 
   ры:
 
        1) команда IF проверяет величину выражения и выполняет
 
   командную строку в зависимости от результата проверки;
 
        2) команда  GOTO  передает  управление  на  помеченную
 
   строку в процедуре;
 
        3) команда выполнения процедуры '@'  запускает  (вызы-
 
   вает) другую командную процедуру и создает другой командный
 
   уровень;
 
        4) команды EXIT и STOP завершают текущую  процедуру  и
 
   возвращают управление либо в вызывающую командную  процеду-
 
   ру, либо на командный уровень 0, соответственно.
 
 
 
        5.1. Разработка командной процедуры                     
 
 
        Перед  составлением  командной  процедуры   необходимо
 
   проанализировать задачи, которые предполагается  выполнять.
 
   В частности, необходимо определить следующие параметры:
 
        1) переменные - данные, которые изменяются всякий  раз
 
   при выполнении задачи;
 
        2) условия - условия, которые должны проверяться  вся-
 
 
 
                              98 
 
                        000152-01 97 04
 
 
   кий раз при выполнении задачи;
 
        3) итерации - группы команд, которые выполняются  пов-
 
   торно, пока не установится нужное условие.
 
        Например, необходимо составить командную процедуру для
 
   очистки каталога.  Для  очистки  каталога  в  интерактивном
 
   режиме обычно используются следующие команды:
 
        1) команда DIRECTORY используется для того, чтобы убе-
 
   диться в наличие файлов в каталоге;
 
        2) команда PURGE используется для удаления старых вер-
 
   сий файлов;
 
        3) команда DELETE используется  для  удаления  файлов,
 
   которые больше не нужно сохранять;
 
        4) команда TYPE используется для проверки  содержимого
 
   файлов перед принятием решения об их удалении;
 
        5) команда PRINT используется для получения распечатки
 
   твердой копии файла перед его удалением.
 
        После определения команд, которые будут использоваться
 
   для очистки каталога, необходимо определить следующие пере-
 
   менные: команды, подлежащие выполнению и файлы,  подлежащие
 
   обработке. Эти переменные изменяются всякий раз при  выпол-
 
   нении процедуры.
 
        Затем необходимо определить условия. Во-первых,  необ-
 
   ходимо определить, какие команды  будут  выполняться.  Если
 
   запрашиваемая команда не является одной из известных проце-
 
   дуре команд, необходимо сформировать сообщение об ошибке  и
 
   получить другую команду. Также необходимо определить момент
 
   завершения процедуры.
 
        Наконец, пользователь определяет, что командная проце-
 
   дура должна повторять следующую последовательность  команд,
 
   пока каталог не будет очищен: получение  команды,  контроль
 
 
                              99 
 
                        000152-01 97 04
 
 
   за тем, что  она  присутствует,  выполнение  команды,  если
 
   команда является корректной, и получение другой команды.
 
 
 
        5.2. Программирование
 
 
        Для разработки более легкой для понимания и обслужива-
 
   ния командной процедуры, ее следует составлять  так,  чтобы
 
   команды выполнялись по возможности последовательно от  пер-
 
   вой до последней. В данном подразделе показаны этапы  прог-
 
   раммирования командной процедуры, выполняющей очистку ката-
 
   лога.
 
 
 
        5.2.1. Получение  переменных
 
 
        Для получения значений переменных  можно  использовать
 
   любой из методов, описанных в разделе 3. Однако,  одним  из
 
   наиболее  общих  методов  получения   значений   переменных
 
   является использование команды INQUIRE. В командной  проце-
 
   дуре очистки каталога имя нужной команды вводится как пока-
 
   зано в примере.
 
 
        П р и м е р.
 
 
   $ INQUIRE COMMAND "введите команду -
     (DELETE,DIRECTORY,PRINT,PURGE,TYPE)"
 
 
        5.2.2. Программирование общей схемы  командной           
 
               процедуры
 
 
        В соответствии с рассмотренным проектом командной про-
 
   цедуры (см. подраздел 5.1), первое, что необходимо  сделать
 
   после получения команды,  это  определить  ход  дальнейшего
 
   выполнения командной процедуры. Для этого необходимо прове-
 
 
 
                              100 
 
                        000152-01 97 04
 
 
   рить, не введена ли команда EXIT. Эта проверка  показана  в
 
   примере 1.
 
 
        П р и м е р 1.
 
 
   $ IF COMMAND .EQS. "EXIT" THEN EXIT
 
        Затем необходимо  определить  введенную  команду.  Для
 
   этого проверяются все возможные ответы пользователя и, если
 
   введенная команда не соответствует заданным, выдается сооб-
 
   щение об ошибке.
 
        Для проверки истинности условия  используется  команда
 
   IF ... ТHEN. Для изменения потока  выполнения  используется
 
   команда перехода на метку GOTO. Рекомендуется  использовать
 
   "заготовки" секций программы. "заготовка" является  времен-
 
   ной секцией программы, которая  используется  для  проверки
 
   проекта. После получения  готового,  правильно  работающего
 
   проекта, можно возвратиться и заменить  каждую  "заготовку"
 
   окончательной секцией программы. Проект программы приводит-
 
   ся в примере 2.
 
 
        П р и м е р 2.
 
 
   $  INQUIRE COMMAND "введите команду -
      (DELETE, DIRECTORY, EXIT, PRINT,PURGE, TYPE)"
   $  IF COMMAND .EQS. "EXIT" THEN EXIT
   $!
   $! выполнить, если пользователь ввел DELETE
   $  DELETE:
   $    IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
   $    WRITE SYS$OUTPUT "это секция DELETE."
   $!
   $! выполнить, если пользователь ввел DIRECTORY
   $  DIRECTORY:
   $    IF COMMAND .NES. "DIRECTORY" THEN GOTO PRINT
   $    WRITE SYS$OUTPUT "это секция DIRECTORY."
   $!
   $! выполнить, если пользователь ввел PRINT
   $  PRINT:
   $    IF COMMAND .NES. "PRINT" THEN GOTO PURGE
   $    WRITE SYS$OUTPUT "это секция PRINT."
   $!
 
 
                              101 
 
                        000152-01 97 04
 
 
   $! выполнить, если пользователь ввел PURGE
   $  PURGE:
   $    IF COMMAND .NES. "PURGE" THEN GOTO TYPE
   $    WRITE SYS$OUTPUT "это секция PURGE."
   $!
   $! выполнить, если пользователь ввел TYPE
   $  TYPE:
   $    IF COMMAND .NES. "TYPE" THEN GOTO ERROR
   $    WRITE SYS$OUTPUT "это секция TYPE."
   $!
   $  ERROR:
   $    WRITE SYS$OUTPUT "введена неверная команда".
   $
   $  EXIT
 
        Проектирование завершается добавлением цикла, в  кото-
 
   ром команды принимаются от пользователя  до  ввода  команды
 
   EXIT, как показано в примере 3.
 
 
        П р и м е р 3.
 
 
   $  GET_COMMAND_LOOP:
   $  INQUIRE COMMAND "введите команду -
      (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)"
   $  IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
   $
   $! выполнить, если пользователь ввел DELETE
   $  DELETE:
   $    IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
   $    WRITE SYS$OUTPUT "это секция DELETE."
   $    GOTO GET_COMMAND_LOOP
   $
   $! выполнить, если пользователь ввел DIRECTORY
   $  DIRECTORY:
   $    IF COMMAND .NES. "DIRECTORY" THEN GOTO PRINT
   $    WRITE SYS$OUTPUT "это секция DIRECTORY."
   $    GOTO GET_COMMAND_LOOP
   $!
   $! выполнить, если пользователь ввел PRINT
   $  PRINT:
   $    IF COMMAND .NES. "PRINT" THEN GOTO PURGE
   $    WRITE SYS$OUTPUT "это секция PRINT."
   $    GOTO GET_COMMAND_LOOP
   $!
   $! выполнить, если пользователь ввел PURGE
   $  PURGE:
   $    IF COMMAND .NES. "PURGE" THEN GOTO TYPE
   $    WRITE SYS$OUTPUT "это секция PURGE."
   $    GOTO GET_COMMAND_LOOP
   $!
   $  TYPE:
   $    IF COMMAND .NES. "TYPE" THEN GOTO ERROR
   $    WRITE SYS$OUTPUT "это секция TYPE."
   $    GOTO GET_COMMAND_LOOP
   $!
 
 
                              102 
 
                        000152-01 97 04
 
 
   $  ERROR:
   $    WRITE SYS$OUTPUT "введена неверная команда."
   $    GOTO GET_COMMAND_LOOP
   $!
   $  END_LOOP:
   $    WRITE SYS$OUTPUT "'каталог()' очищен."
   $  EXIT
 
 
        5.2.3. Проверка и отладка
 
 
        После разработки процедуры с  использованием  "загото-
 
   вок" программы, можно  проверить  полную  логику  командной
 
   процедуры. Например, для проверки процедуры CLEAN.COM (опи-
 
   санной в п. 5.2.2),  необходимо  ввести  каждую  допустимую
 
   команду, недопустимую команду и  затем  команду  EXIT,  как
 
   показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $ @CLEAN
     введите команду (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)-
     :DELETE
     это секция DELETE.
     .
     .
     .
     введите команду (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)-
     :EXIT
   $
 
        Для отладки командной процедуры  используются  команды
 
   SET VERIFY и SHOW SYMBOL. В примере 2  показано  выполнение
 
   командной процедуры с использованием команды SET VERIFY.
 
 
        П р и м е р 2.
 
 
   $ SET VERIFY
   $ @CLEAN
   $ GET_COMMAND_LOOP:
   $ INQUIRE COMMAND "введите команду -
     (DELETE,DIRECTORY,EXIT, PRINT, PURGE, TYPE)"
     введите команду (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)
     :EXIT
   $ IF COMMAND .EQS. "EXIT" THEN GOTO END_LOP
     %DCL-W-USGOTO, TARGER OF GOTO NOT FOUND - CHECK
     SPELLING AND PRESENCE OF LABEL
 
 
                              103 
 
                        000152-01 97 04
 
 
     (метка в команде GOTO не найдена - проверьте орфографию
      и точность метки)
 
        В примере 2 метка в операторе GOTO написана некоррект-
 
   но. Для исправления ошибки необходимо изменить эту метку на
 
   END_LOOP.
 
        В примере 3 используется команда SHOW SYMBOL для опре-
 
   деления значения символа COMMAND.
 
 
        П р и м е р 3.
 
 
   $ SET VERIFY
   $ @CLEAN
   $ GET_COMMAND_LOOP:
   $   INQUIRE COMMAND "введите команду -
       (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)"
     введите команду (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)-
     :EXIT
   $ SHOW SYMBOL COMMAND
     COOMMAND = "EXIT"
   $ IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
 
        В примере 3 команда SHOW SYMBOL указывает, что  символ
 
   сомMAND имеет значение "EXIT".  Следует  учитывать,  что  в
 
   отличие от команды INQUIRE, оператор IF не преобразует про-
 
   писные буквы в заглавные.
 
 
 
        5.2.4. Заполнение "заготовок" программы       
 
 
        После отладки общего проекта необходимо создать полные
 
   программы  "заготовок"  и  еще  раз  отладить  и  проверить
 
   командную процедуру.
 
        В примере показана программа "заготовки" TYPE процеду-
 
   ры CLEAN.COM.
 
 
 
 
 
 
 
 
 
 
 
                              104 
 
                        000152-01 97 04
 
 
        П р и м е р.
 
 
   $! выполнить, если пользователь ввел TYPE
   $  TYPE:
   $    IF COMMAND .NES. "TYPE" THEN GOTO ERROR
   $    INQUIRE FILE "файл для распечатки"
   $    TYPE 'FILE'
   $    GOTO GET_COMMAND_LOOP
 
 
        5.3. Методы управления потоком выполнения        
 
 
        В подразделе 5.2  описаны  некоторые  методы,  которые
 
   можно использовать при проектировании процедур и управлении
 
   потоком выполнения.
 
        В данном подразделе эти методы описаны более подробно.
 
 
 
        5.3.1. Команда IF
 
 
        Команда IF проверяет величину  выражения  и  выполняет
 
   соответствующую команду, если выражение истинно.
 
        Команда IF имеет следующий формат:
                         
 
   \F\выражение \HEN\[$] команда
 
 
        Выражение соответствует значению "истинно" в следующих
 
   случаях:
 
        1) выражение имеет целую величину;
 
        2) выражение имеет величину  типа  символьной  строки,
 
   которая начинается с любой из букв Y, у, тт или т;
 
        3) выражение имеет величину  типа  символьной  строки,
 
   которая содержит числа, образующие нечетное  целое  (напри-
 
   мер, строка "27").    
 
        Выражение соответствует значению "ложно"  в  следующих
 
   случаях:
 
        1) выражение имеет четную целую величину;
 
 
 
                              105 
 
                        000152-01 97 04
 
 
        2) выражение имеет величину  типа  символьной  строки,
 
   которая начинается с любой буквы, за исключением Y,  Y,  TT
 
   или T.
 
        3) выражение имеет величину  типа  символьной  строки,
 
   которая содержит числа, образующие четное целое  (например,
 
   строка "28").
 
        В примерах 1, 2, 3 приводятся выражения, которые могут
 
   использоваться с командой IF.
 
        В примере 1 используется логический оператор.
 
 
        П р и м е р 1.
 
 
   $ INQUIRE CONT "хотите продолжить [Y/N]"
   $ IF .NOT. СONT THEN EXIT
     .
     .
     .
 
        В примере 1, если символ CONT не соответствует  истине
 
   (то есть величина CONT четная или не начинается с  букв  Y,
 
   Y, T или T), то выполняется выход  из  процедуры.  Следова-
 
   тельно, если величина CONT соответствует N, то  выполняется
 
   выход из процедуры; если величина CONT соответствует Y,  то
 
   продолжается выполнение процедуры.
 
        В примере 2 используется полное выражение IF.
 
 
        П р и м е р 2.
 
 
   $ IQUIRE CHANGE "хотите изменить запись [Y/N]"
   $ IF CHANGE THEN GOTO GET_CHANGE
     .
     .
     .
   $ GET_CHANGE:
     .
     .
     .
 
        В примере 2, если символ CHANGE  соответствует  истине
 
   (то есть величина является нечетной или начинается  с  букв
 
 
                              106 
 
                        000152-01 97 04
 
 
   Y, Y, T или T), то выполняется переход на метку GET_CHANGE.
 
   В противном  случае  выполнение  процедуры  продолжается  в
 
   обычной последовательности.
 
        В примере 3 приводятся две команды IF. Первая  команда
 
   IF выполняет сравнение двух целых; вторая команда IF выпол-
 
   няет сравнение двух строк.
 
 
        П р и м е р 3.
 
 
   $ COUNT = 0
   $ LOOP:
   $   COUNT = COUNT + 1
   $   IF COUNT .EQ. 9 THEN EXIT
   $   IF P'COUNT' .EQS. "" THEN EXIT
     .
     .
     .
 
        В первой команде IF COUNT сравнивается с целым  числом
 
   9; если величины равны, то процедура завершается. Это обес-
 
   печивает обработку восьми параметров  (максимальное  разре-
 
   шенное число параметров).
 
        Во второй команде IF величина  символа  P'COUNT'  типа
 
   строки сравнивается с пустой строкой для  обнаружения  слу-
 
   чая, когда символ не определен. Знаки апострофа  необходимо
 
   использовать для ускорения  итеративной  замены.  Например,
 
   если COUNT равен 2, результат первой замены равен P2. Затем
 
   величина P2 используется в сравнении строк.
 
        При составлении выражения для команды  IF,  необходимо
 
   следовать правилам для составления выражений, приведенных в
 
   разделе 2 данного документа. В частности, необходимо  иметь
 
   в виду следующие правила:
 
        1) символы в операторах IF  заменяются  автоматически.
 
   Апострофы в качестве  операторов  замены  не  используются,
 
   если для этого нет специальных причин;
 
 
 
                              107 
 
                        000152-01 97 04
 
 
        2) операторы сравнения строк заканчиваются буквой "S".
 
   Например, для сравнения строк, используются такие  операто-
 
   ры, как .EQS., .LTS. И .GTS. . В отличие от них,  операторы
 
   .EQ., .LT. И .GT. Используются для сравнения целых;
 
        3) при сравнении двух строк, составляющие  их  символы
 
   должны быть в одном  регистре,  чтобы  DCL  мог  определить
 
   соответствие.
 
        Об'ектами команды IF может быть одиночная команда язы-
 
   ка DCL, метка, идентифицирующая  блок  команд,  или  другая
 
   командная  процедура.  В  примере  4  об'ектом  команды  IF
 
   является команда EXIT.
 
 
        П р и м е р 4.
 
 
   $ GET_COMMAND_LOOP:
   $   INQUIRE COMMAND "введите соманду -
       (COPY,DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)"
   $   IF COMMAND .EQS. "EXIT" THEN EXIT
 
        В примере 5 используется команда GOTO, чтобы направить
 
   поток выполнения  на  метку,  которая  идентифицирует  блок
 
   команд.
 
 
        П р и м е р 5.
 
 
   $ GET_COMMAND_LOOP:
   $  INQUIRE COMMAND "введите команду -
      (COPY,DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)"
   $  IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
     .
     .
     .
   $ END_LOOP:
     .
     .
     .
 
        Можно поместить группу команд  в  отдельную  командную
 
   процедуру и  выполнить  ее,  если  результат  выражения  IF
 
   является истиной, как показано в примере 6.
 
 
 
                              108 
 
                        000152-01 97 04
 
 
        П р и м е р 6.
 
 
   $ GET_COMMAND_LOOP:
   $  INQUIRE COMMAND "введите команду -
      (COPY,DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)"
   $  IF COMMAND .EQS. "EXIT" THEN @EXIT_ROUTINE
 
 
        5.3.2. Команда GOTO             
 
 
        Команда GOTO передает управление на метку в  командной
 
   процедуре. Правила указания меток следующие:
 
        1) метка должна указываться первым элементом в строке;
 
        2) метка может иметь до 255 символов;
 
        3) не разрешается вставлять пробелы внутри метки;
 
        4) метка должна заканчиваться двоеточием.
 
        В примере 1 показано использование команды GOTO.
 
 
        П р и м е р 1.
 
 
   $ GOTO BYPASS
     .
     .
     .
   $ BYPASS:
 
        Когда интерпретатор команд встречает метки, он  вводит
 
   их в  специальный  раздел  таблицы  локальных  меток.  Если
 
   встречается метка, которая уже существует в  этой  таблице,
 
   новое определение замещает существующее определение. Размер
 
   таблицы меток ограничен. Если командная  процедура  исполь-
 
   зует много символов и меток, то интерпретатор команд  может
 
   выйти за пространство таблицы и сформировать  сообщение  об
 
   ошибке. В этом случае необходимо удалить ненужные  в  даль-
 
   нейшем символы с помощью команды DELETE/SYMBOL.
 
        Команда GOTO оказывается особенно полезной в предложе-
 
   нии THEN для выполнения перехода  в  процедуре  вперед  или
 
   назад. Например, если используются  параметры  в  командной
 
 
                              109 
 
                        000152-01 97 04
 
 
   процедуре, то можно проверить параметры в начале  процедуры
 
   и выполнить переход на соответствующую метку.
 
 
        П р и м е р 2.
 
 
   $ IF P1 .NES. "" THEN GOTO OKAY
   $ INQUIRE P1 "введите имя файла"
   $ OKAY:
   $   PRINT/COPIES=10 'P1'
     .
     .
     .
 
        В примере 2 команда IF проверяет, является ли P1  пус-
 
   той строкой. Если проверенное  условие  "истинно",  команда
 
   GOTO не выполняется, а команда  INQUIRE  выводит  подсказку
 
   для ввода параметра. В противном случае команда GOTO выпол-
 
   няет переход с обходом команды INQUIRE. В любом случае про-
 
   цедура выполняет команду  PRINT,  следующую  за  помеченной
 
   строкой OKAY.
 
 
 
        5.3.3. Циклы
 
 
 
        Циклы используются для повторения группы операторов до
 
   тех пор, пока не встретится условие. Общие правила  состав-
 
   ления циклов следующие:
 
        1) цикл начинается с метки;
 
        2) проверяется  значение  переменной  для  определения
 
   того, что выполнение команд в цикле требуется;
 
        3) если выполнять команды цикла не  требуется,  выпол-
 
   няется переход на конец цикла;
 
        4) если цикл необходимо выполнять, тогда после  выпол-
 
   нения команд необходим переход на начало цикла.
 
        Можно также проверять переменную в конце цикла.
 
 
 
 
                              110 
 
                        000152-01 97 04
 
 
        В примерах  1,  2,  3  показаны  различные  методы,  с
 
   помощью которых можно составить циклы. Пример  1  проверяет
 
   переменную в начале цикла; цикл завершается, когда перемен-
 
   ная символа FILE является пустой строкой.
 
 
        П р и м е р 1.
 
 
   $ LOOP:
   $   INQUIRE FILE "имя файла"
   $   IF FILE .EQS. "" THEN GOTO DONE
   $!  обработка файла
     .
     .
     .
   $ GOTO LOOP
   $!
   $ DONE:
     .
     .
     .
 
        В примере 1 команда  INQUIRE  запрашивает  имя  файла.
 
   Если имя файла не вводится (CTRL/Z  или  RETURN),  цикл  не
 
   выполняется. В противном случае  цикл  выполняется  до  тех
 
   пор, пока не будет введен пустой ответ.
 
        В примере 2 используется счетчик для управления числом
 
   повторений выполнения цикла. Цикл выполняется 10 раз; пере-
 
   менная проверяется в конце цикла.
 
 
        П р и м е р 2.
 
 
   $! получить имена 10 файлов и запомнить их в символах -
   $! FILE_1-FILE_10
   $ COUNT = 0
   $ LOOP:
   $   COUNT = COUNT + 1
   $   INQUIRE FILE_'COUNT' "файл"
   $   IF COUNT .LT. 10 THEN GOTO LOOP
   $!
   $ PROCESS_FILES:
     .
     .
     .
 
        В примере 2 символ  COUNT  используется  для  хранения
 
 
 
                              111 
 
                        000152-01 97 04
 
 
   счетчика повторений цикла. Символ COUNT используется  также
 
   для создания символьных имен FILE_1, FILE_2, и  так  далее,
 
   до FILE_10. Величина COUNT  получает  приращение  в  начале
 
   цикла и проверяется в  конце  цикла.  Следовательно,  когда
 
   величина COUNT получает приращение от 9 до 10, цикл  выпол-
 
   няется в последний раз (получая величину для FILE_10) перед
 
   тем, как оператор  IF  обнаружит  результат,  соответвующий
 
   значению "ложь".
 
        Чтобы выполнить цикл для известной  последовательности
 
   величин, используют лексическую функцию F$ELEMENT.  Функция
 
   F$ELEMENT обрабатывает список элементов, разделенных  огра-
 
   ничителями.
 
 
        П р и м е р 3.
 
 
   $  FILE_LIST = "снар1/снар2/снар3/снар4/снар5"
   $  NUM = 0
   $!
   $! обработать каждый файл, перечисленный в FILE_LIST
   $  PROCESS_LOOP:
   $     FILE = F$ELEMENT(NUM,"/",FILE_LIST)
   $     IF FILE .EQS. "/" THEN GOTO DONE
   $     COPY 'FILE'.MEM MORRIS::DISK3:[DOCSET]*.*
   $     GOTO PROCESS_LOOP
   $!
   $  DONE:
   $     WRITE SYS$OUTPUT "копирование завершено"
   $  EXIT
 
        В командной процедуре примера 3 используется цикл  для
 
   копирования файлов, перечисленных в  FILE_LIST,  в  каталог
 
   другого узла. Первым файлом, возвращаемым с помощью функции
 
   F$ELEMENT, является файл снар1,  следующим  файлом  -  файл
 
   снар2, и так далее. Всякий  раз  через  цикл  величина  NUM
 
   получает приращение, так что  функция  F$ELEMENT  извлекает
 
   имя следующего файла. Когда  функция  F$ELEMENT  возвращает
 
   символ косой черты, это указывает на то, что  все  элементы
 
   из списка FILE_LIST обработаны и цикл завершен.
 
 
                              112 
 
                        000152-01 97 04
 
 
        5.3.4. Переход по условию
 
 
        Выполнение одного из блоков команд  в  зависимости  от
 
   величины переменной или выражения можно  организовать  сле-
 
   дующим образом:
 
        1) приравнять символ строке, которая  содержит  список
 
   возможных значений переменной;
 
        2) получить конкретное значение переменной от  пользо-
 
   вателя;
 
        3) с помощью лексических функций F$LOCATE  и  F$LENGTH
 
   проверить корректность ввода пользователя;
 
        4) с помощью команды GOTO направить поток выполнения в
 
   соответствующий блок команд. Метки, идентифицирующие каждый
 
   блок команд, должны совпадать со значениями,  указанными  в
 
   списке значений переменной.
 
        Например,  можно  перезаписать   процедуру   CLEAN.COM
 
   (показанную в п.5.2.2) так, чтобы она проверяла команды  на
 
   корректность в начале процедуры. Если команда является кор-
 
   ректной, процедура выполняет команду, как показано в приме-
 
   ре.
 
 
        П р и м е р.
 
 
   $ COMMAND_LIST="DELETE/DIRECTORY/EXIT/"+
     "PRINT/PURGE/PURGE/TYPE/"
   $!
   $ GET_COMMAND_LOOP:
   $   INQUIRE COMMAND "введите команду" -
   $   (DELETE,DIRECTORY,EXIT,PRINT,PURGE,TYPE)"
   $   IF F$LOCATE(COMMAND+"/",COMMAND_LIST) .EQ. -
       F$LENGTH(COMMAND_LIST) THEN GOTO ERROR
   $   GOTO 'COMMAND'
   $!
   $! выполнить, если пользователь ввел DELETE
   $  DELETE:
   $    WRITE SYS$OUTPUT "это секция DELETE"
   $    GOTO GET_COMMAND_LOOP
   $!
   $! выполнить, если пользователь ввел DIREсTORY
 
 
                              113 
 
                        000152-01 97 04
 
 
   $  DIRECTORY:
   $    WRITE SYS$OUTPUT "это секция DIRECTORY"
   $    GOTO GET_COMMAND_LOOP
     .
     .
     .
   $!
   $  EXIT:
   $   WRITE SYS$OUTPUT "каталог ''F$DIRECTORY()' -
       очищен
   $  EXIT
   $!
   $! секция ошибок
   $  ERROR:
   $   WRITE SYS$OUTPUT "неверный ввод"
   $!
   $   GOTO GET_COMMAND_LOOP
 
 
        5.4. Завершение командной процедуры                            
 
 
        Для окончания командной процедуры  можно  использовать
 
   либо команду EXIT, либо команду STOP для завершения  выпол-
 
   нения процедуры. Команда EXIT завершает выполнение  текущей
 
   командной процедуры и возвращает управление  на  вызывающий
 
   командный уровень. Команда STOP  возвращает  управление  на
 
   командный уровень 0 независимо от уровня текущей процедуры.
 
   Если команда STOP выполняется в пакетном задании,  пакетное
 
   задание завершается.
 
        Можно прервать командную процедуру вводом символа YC/Y
 
   и затем ввести либо команду EXIT,  либо  команду  STOP  для
 
   завершения процедуры. В этом случае обе команды  возвращают
 
   управление на командный уровень 0.
 
 
        П р и м е р.
 
 
   $ @TESTALL <CR>
   CTRL/Y
   $ EXIT     <CR>
   $
 
        В примере  процедура  TESTALL  прерывается  при  вводе
 
   CTRL/Y. Команда EXIT завершает обработку процедуры и  восс-
 
 
 
                             114 
 
                        000152-01 97 04
 
 
   танавливает командный уровень 0.
 
        Если команда (или образ),  которую  прервал  пользова-
 
   тель, об'являла обслуживающую подпрограмму обработки  выхо-
 
   да, команда EXIT передает управление на  эту  подпрограмму.
 
   Однако, по команде STOP эти обслуживающие  подпрограммы  не
 
   выполняются. В разделе 7 дается  более  подробное  описание
 
   прерываний CTRL/Y.
 
 
 
        5.4.1. Использование команды EXIT                           
 
 
        Если требуется обрабатывать ошибки в конце  процедуры,
 
   команду EXIT необходимо поставить перед подпрограммой обра-
 
   ботки ошибок, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
     .
     .
     .
   $ EXIT ! (конец нормального выполнения)
   $ ERROR_ROUTINE:
     .
     .
     .
 
        Эта команда также полезна  для  составления  процедур,
 
   имеющих несколько путей выполнения.
 
 
        П р и м е р 2.
 
 
   $ START:
   $   IF P1. ЕQS. "TAPE" .OR. Р1 .EQS. "DISK" THEN GOTO 'P1'
   $   INQUIRE P1 "введите устройство (TAPE OR DISK)"
   $   GOTO START
   $ TAPE: ! обработка файлов на ленте
     .
     .
     .
   $ EXIT
   $ DISK: ! обработка файлов на диске
     .
     .
     .
 
 
                              115 
 
                        000152-01 97 04
 
 
   $ EXIT
 
        Для выполнения командной процедуры примера 2 необходи-
 
   мо ввести либо таре, либо DISK в качестве параметра. Коман-
 
   да IF использует логический  оператор  "или"  для  проверки
 
   того, была ли введена одна из этих строк. Если одна из этих
 
   строк была введена, то команда GOTO выполняет соответствую-
 
   щий переход, используя параметр P1 в качестве метки перехо-
 
   да. Если P1 не соответствует  ни  TAPE,  ни  DISK,  команда
 
   INQUIRE выводит подсказку для  ввода  параметра  и  команда
 
   GOTO START организует цикл.
 
        Команды, следующие за каждой из меток таре  или  DISK,
 
   обеспечивают различные пути выполнения  процедуры.  Команда
 
   EXIT перед меткой DISK обеспечивает завершение процедуры.
 
        Команда EXIT в конце процедуры не требуется,  так  как
 
   конец файла процедуры неявно вызывает команду EXIT. Однако,
 
   и в этом случае рекомендуется использовать команду EXIT.
 
 
 
        5.4.2. Передача значений состояния  с  помощью          
 
               команды  EXIT
 
 
        При завершении процедуры интерпретатор команд  возвра-
 
   щает код условия для предшествующей команды  в  специальный
 
   символ, называемый $STATUS. Код условия указывает на успеш-
 
   ное или с ошибкой завершение выполнения последней  команды.
 
   В разделе 7 дается более подробное описание кодов условия.
 
        В командной процедуре с  помощью  команды  EXIT  можно
 
   задать значение символа $STATUS и отменить значение, назна-
 
   ченное  интерпретатором  команд.  Значение  кода  состояния
 
   задается как целое выражение.
 
        Например,  пусть  процедура  а.сом  содержит   команду
 
 
 
                              116 
 
                        000152-01 97 04
 
 
   запуска вложенной командной процедуры  в.сом,  а  процедура
 
   в.сом содержит следующие строки:
 
   $ ON WARNING THEN GOTO ERROR
     .
     .
     .
   $ ERROR:
   $ EXIT 1
 
        По команде ON, если появляются предупреждения,  ошибки
 
   или неисправимые ошибки при  выполнении  в.сом,  управление
 
   передается на метку ERROR.  Здесь  код  условия  специально
 
   устанавливается в 1, который указывает на успешное заверше-
 
   ние. Следовательно, когда процедура в.сом завершается,  она
 
   передает код успешного завершения в процедуру а.сом незави-
 
   симо от того, была обнаружена ошибка или нет.
 
 
 
        5.4.3. Использование команды STOP                            
 
 
        Команду STOP в командной процедуре или пакетном  зада-
 
   нии можно использовать, например, для завершения всех  про-
 
   цедур при возникновении неисправимой ошибки.
 
 
        П р и м е р.
 
 
   $ ON SEVERE_ERROR THEN STOP
     .
     .
     .
 
        В примере, по командной строке, если возникает  неисп-
 
   равимая ошибка, процедура завершается. В командной процеду-
 
   ре, которая выполняется  интерактивно,  управление  возвра-
 
   щается на командный уровень 0. В пакетном  режиме  пакетное
 
   задание завершается.
 
 
 
 
 
 
 
                              117 
 
                        000152-01 97 04
 
 
                      6. Ввод-вывод файлов
 
 
 
        Основные шаги чтения и записи файлов из командной про-
 
   цедуры следующие:
 
        1) с помощью команды OPEN  файл  открывается.  Команда
 
   OPEN назначает логическое имя для файла и задает  доступ  к
 
   файлу для чтения и/или записи;
 
        2) с помощью команды READ и WRITE записи файла читают-
 
   ся и пишутся. Когда пользователь выполняет ввод  или  вывод
 
   для файлов, он обычно создает цикл для чтения записи, обра-
 
   ботки записи и вывода записи либо в тот же, либо  в  другой
 
   файл. Обычно в цикле выполняются команды чтения,  обработки
 
   и вывода записей, пока он не будет обработан от  начала  до
 
   конца;
 
        3) с помощью команды CLOSE файл закрывается. Если файл
 
   не закрыт, он остается открытым до выхода  пользователя  из
 
   системы.
 
        В этом разделе приводится описание команд OPEN,  READ,
 
   WRITE и CLOSE. Изложена также методика по модификации  фай-
 
   лов и обработке ошибок при выполнении операций с файлами.
 
 
 
        6.1. Команды ввода-вывода для файлов                
 
 
        В следующих пунктах приводится описание  команд  языка
 
   DCL для выполнения ввода и вывода для файлов.
 
 
 
        6.1.1. Команда OPEN
 
 
        Команда OPEN может открывать последовательные, относи-
 
   тельные файлы, а также  файлы  с  индексно-последовательным
 
   методом доступа (ISAM). При  открытии  файла  команда  OPEN
 
 
                              118 
 
                        000152-01 97 04
 
 
   назначает файлу логическое имя и  помещает  его  в  таблицу
 
   логических имен процесса. Команды READ и  WRITE  используют
 
   это логическое имя для обращения к файлу.
 
        Команда OPEN открывает  файлы  в  качестве  постоянных
 
   файлов процесса. Следовательно, эти файлы остаются открыты-
 
   ми на время существования данного  процесса,  если  они  не
 
   будут закрыты специально (с помощью команды CLOSE). На  эти
 
   файлы распространяются ограничения системы управления  дан-
 
   ными (СУД-32) на использование постоянных файлов процесса.
 
        Пользователь  не  должен  специально  открывать  файлы
 
   SYS$INPUT, SYS$OUTPUT, SYS$COMMAND и  SYS$ERROR  для  того,
 
   чтобы выполнять операции чтения или записи, так как система
 
   открывает эти файлы для пользователя при его регистрации  в
 
   системе. Более подробная информация  относительно  операций
 
   чтения и записи для этих файлов содержится в разделе 3.
 
        В следующих подпунктах представлена методика по откры-
 
   тию файлов для чтения, записи или чтения и записи.
 
 
 
        6.1.1.1. Открытие файла для чтения                         
 
 
        Чтобы открыть файл для чтения, используется квалифика-
 
   тор /READ; он является квалификатором по умолчанию  команды
 
   OPEN. В примере показано открытие файла для чтения.
 
 
        П р и м е р.
 
 
   $ OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT
 
 
        Открытый для  чтения  файл  не  доступен  для  записи.
 
   Команда OPEN/READ помещает указатель записи в начало файла.
 
   Всякий раз при чтении записи указатель  переустанавливается
 
   на следующую запись.
 
 
                              119 
 
                        000152-01 97 04
 
 
        6.1.1.2. Открытие файла для записи                         
 
 
        Чтобы открыть файл для записи используется либо квали-
 
   фикатор /WRITE, либо квалификатор /APPEND. Эти квалификато-
 
   ры взаимно исключают друг друга, так что в командной строке
 
   можно использовать только один из этих квалификаторов.
 
        Квалификатор /WRITE всегда помещает указатель записи в
 
   начале файла. Команда OPEN/WRITE всегда создает  последова-
 
   тельный файл в формате файла печати.  Записи  файла  печати
 
   имеют формат с фиксированным управлением (VFC) с двухбайто-
 
   вым заголовком записи. Если задается  файл  с  существующим
 
   именем, то команда OPEN/WRITE открывает новый файл с  номе-
 
   ром версии, на единицу большим по сравнению с  существующим
 
   файлом.
 
        В примере 1 выполняется открытие файла  для  записи  и
 
   вывод записей в файл.
 
 
        П р и м е р 1.
 
 
   $ OPEN/WRITE OUTFILE DISK4:[MURPHY]NAMES.DAT
   $ INQUIRE NEW_RECORD "ENTER NAME"
   $ WRITE OUTFILE OUTFILE NEW_RECORD
     .
     .
     .
   $ CLOSE OUTFILE
 
        Квалификатор  /APPEND,  в  отличие  от   квалификатора
 
   /WRITE, не создает новую версию файла. Квалификатор /APPEND
 
   открывает существующий файл и позиционирует указатель запи-
 
   си в конец файла. Это позволяет добавлять  записи  в  конец
 
   файла.
 
        Командная процедура в  примере  2  помещает  записи  в
 
   конец файла NAMES.DAT.
 
 
 
 
 
                              120 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
 
 
   $ OPEN/APPEND OUTFILE DISK4:[MURPHY]NAMES.DAT
   $ INQUIRE REW_RECORD "ENTER NAME"
   $ WRITE OUTFILE NEW_RECORD
     .
     .
     .
   $ CLOSE OUTFILE
 
 
        6.1.1.3. Открытие файла для чтения и записи            
 
 
        Чтобы открыть файл для чтения  и  записи  используется
 
   как квалификатор /READ, так и квалификатор /WRITE.
 
 
        П р и м е р.
 
 
   $ OPEN/READ/WRITE FILE DISK4:[MURPHY]STATS.DAT
 
 
        В примере команда OPEN  помещает  указатель  записи  в
 
   начале файла STATS.DAT так, чтобы можно было прочитать пер-
 
   вую запись. При таком открытии файла возможна только замена
 
   последней прочитанной записи, вывод новых записей  в  конец
 
   файла запрещен. Кроме того,  заменяемая  запись  должна  по
 
   размеру в точности совпадать с заменяющей ее записью.
 
 
 
        6.1.1.4. Открытие разделяемых файлов                 
 
 
        Чтобы открыть разделяемый файл используется квалифика-
 
   тор /SHARE при открытии файла. Квалификатор  /SHARE  позво-
 
   ляет пользователям читать этот файл или  выполнять  в  него
 
   запись. Квалификатор /SHARE=READ разрешает другим пользова-
 
   телям читать файл; квалификатор /SHARE=WRITE разрешает дру-
 
   гим пользователям выполнять доступ к файлу с помощью команд
 
   TYPE или SEARCH.
 
 
 
 
 
                              121 
 
                        000152-01 97 04
 
 
        6.1.2. Команда READ
 
 
        Команда READ используется для чтения записи и назначе-
 
   ния ее содержимого символу.
 
 
        П р и м е р 1.
 
 
   $ OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT
   $ READ INFILE RECORD
     .
     .
     .
 
        В примере 1 команда READ читает запись из файла INFILE
 
   и назначает содержимое записей символу RECORD.
 
        Символьное имя из команды READ  помещается  в  таблицу
 
   локальных символов текущего командного уровня. Если исполь-
 
   зуется одно и то же символьное  имя  для  более  чем  одной
 
   команды READ, каждая команда READ  переопределяет  величину
 
   символьного имени.
 
 
        П р и м е р 2.
 
 
   $ BEGIN:
   $   READ INFILE RECORD
     .
     .
     .
   $ GOTO BEGIN
 
        В примере 2 в каждом проходе этого цикла, команда READ
 
   читает следующую запись из входного файла и использует  эту
 
   запись для переопределения величины символа RECORD.
 
        Для того, чтобы выполнить чтение из файла, файл должен
 
   быть открыт с доступом по чтению. Пользователь может читать
 
   записи, имеющие длину до 1024 символов.
 
 
 
 
 
 
 
 
                              122 
 
                        000152-01 97 04
 
 
        6.1.2.1. Создание циклов чтения                      
 
 
        Обычно читается и обрабатывается каждая  запись  файла
 
   до тех пор, пока не будет достигнут конец файла. Для  опре-
 
   деления конца файла используется квалификатор  /END_OF_FILE
 
   в команде READ. Используя этот квалификатор  можно  создать
 
   цикл для чтения записей из файла, обработки записей и выхо-
 
   да из цикла, когда закончится чтение всех записей.
 
 
        П р и м е р.
 
 
   $ OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT
   $ READ_LOOP:
   $   READ/END_OF_FILE=END_LOOP INFILE RECORD
     .
     .
     .
   $ GOTO READ_LOOP
   $!
   $ END_LOOP:
   $   CLOSE INFILE
   $ EXIT
 
        В примере команда READ  выполняется  повторно  до  тех
 
   пор, пока не будет возвращен  признак  конца  файла.  Затем
 
   процедура выполняет переход на строку  с  меткой  END_LOOP.
 
   Метки, назначаемые для квалификатора  /END_OF_FILE,  подчи-
 
   няются тем же правилам, что и метки, заданные  для  команды
 
   GOTO.
 
        Если команда READ  используется  в  цикле,  необходимо
 
   указывать квалификатор /END_OF_FILE.  В  противном  случае,
 
   когда условие ошибки, указывающее на конец  файла,  возвра-
 
   щается системой управления данными (СУД-32),  интерпретатор
 
   команд выполняет действия  по  обработке  ошибки,  заданные
 
   текущей командой ON. Например, СУД-32 возвращает  состояние
 
   ошибки  %RMS-E-EOF.  Это  заставляет  командную   процедуру
 
   выполнить выход, если для процедуры не была установлена  ее
 
 
 
                              123 
 
                        000152-01 97 04
 
 
   собственная обработка ошибок.
 
 
 
        6.1.2.2. Произвольное чтение записей из файлов с               
 
                 индексно-последовательным       методом             
 
                 доступа
 
 
        Можно  использовать  команду  READ  с  квалификаторами
 
   /INDEX и /KEY для произвольного чтения записей из файлов  с
 
   индексно-последовательным  методом  доступа.  Квалификаторы
 
   /KEY и /INDEX задают поиск записи в файле по заданному клю-
 
   чу в индексе и чтение записи, связанной с этим ключом. Если
 
   пользователь не  задает  индекс,  то  используется  главный
 
   индекс 0.
 
        После произвольного  чтения  можно  прочитать  остаток
 
   файла последовательно от данной  точки,  используя  команду
 
   READ без квалификаторов /KEY или /INDEX.
 
        Можно  использовать  команду  READ  с   квалификатором
 
   /DELETE    для    удаления    записей    из    файлов     с
 
   индексно-последовательным методом доступа после чтения.
 
        Более подробная информация о  квалификаторах  /DELETE,
 
   /INDEX и /KEY содержится в документе [1].
 
 
 
        6.1.3. Команда WRITE
 
 
        С помощью команды WRITE  в  файл  выводится  отдельная
 
   запись. Данные,  подлежащие  записи,  задаются  в  качестве
 
   выражения типа символьной строки или как список  выражений,
 
   как показано в примере 1.
 
 
 
 
 
 
 
 
                              124 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $ OPEN/WRITE OUTFILE DISK4:[MURPHY]NEW_STATS.DAT
   $ WRITE OUTFILE "FILE CREATED APRIL 15, 1984"
     .
     .
     .
   $ CLOSE OUTFILE
 
        При задании данных для команды WRITE, необходимо  сле-
 
   довать правилам для выражений типа символьной строки,  опи-
 
   санным в разделе 2.
 
        Команда WRITE автоматически заменяет символы и  лекси-
 
   ческие функции.
 
 
        П р и м е р 2.
 
 
   $ OPEN/WRITE OUTFILE DISK4:[MURPHY]NEW_STATS.DAT
   $ INQUIRE RECORD "ENTER NAME"
   $ WRITE OUTFILE NAME
     .
     .
     .
 
        В примере 2 команда WRITE записывает величину  символа
 
   NAME в файл NEW_STATS .DAT.
 
        Можно указать символьные имена и литеральные  символь-
 
   ные строки в команде WRITE, как показано в примере 3.
 
 
        П р и м е р 3.
 
 
   $ WRITE OUTFILE "COUNT IS ".COUNT."."
 
 
        Если величина COUNT равна 4, то данная  команда  WRITE
 
   записывает следующую строку в файл OUTFILE:
 
   COUNT IS 4.
 
        Другой способ для смешивания литеральных строк с  сим-
 
   вольными именами заключается в  помещении  целой  строки  в
 
   знаки кавычек и использовании двойных знаков апострофа  для
 
   запроса замены символа. Например:
 
 
                              125 
 
                        000152-01 97 04
 
 
   $ WRITE OUTFILE "COUNT IS ''COUNT'."
 
        На рис.1 показаны различные способы задания данных для
 
   команды WRITE.
 
 
 
             Замена символа с помощью команды WRITE
 
 
    .
    .
    .
      $ &FIGURE       ---------> DBA1[HIGGINS]FIGURE COM
                                 --------------------------------------
   -> $ TYPE DATA.OUT           ! $ ABC = "THE CHARACTER STRIG"        !
   !  THE CHARACTER STRING      ! $ COUNT = 4                          !
   !  ABC                       ! $ P4 = "FOURTH PARAMETER"            !
   !  COUNT IS 4                ! $ OPEN WRITE OUTFILE DATA.OUT        !
   !  MODE IS INTERACTIVE   (1) ! $ WRITE OUTFILE ABC                  !
   !  FOURTH PARAMETER      (2) ! $ WRITE OUTFILE "ABC"                !
   !  $                     (3) ! $ WRITE OUTFILE "COUNT IS ",COUNT    !
   !                        (4) ! $ WRITE OUTFILE "MODE IS ''F$MOCE()'"!
   !                        (5) ! $ WRITE OUTFILE P'COUNT'             !
    --------------------------  ! $ CLOSE OUTFILE                      !
                                 --------------------------------------
 
 
 
                             Рис. 1
 
 
 
        Команда WRITE может записывать данные только в  файлы,
 
   которые открыты для записи. (можно  использовать  любой  из
 
   квалификаторов /WRITE или /APPEND для открытия  файлов  для
 
   записи). Когда команда WRITE записывает запись,  она  пози-
 
   ционирует указатель записи  после  уже  записанной  записи.
 
   Команда WRITE может выполнять вывод записей, имеющих  длину
 
   до 2048 байт.
 
        Когда требуется вывести запись, длина  которой  превы-
 
   шает 1024 байта, либо если любое выражение в команде  WRITE
 
   превышает по длине 255 байт, необходимо использовать квали-
 
   фикатор /SYMBOL. (см. oписание команды  WRITE  в  документе
 
   [1], где представлена более  подробная  информация  относи-
 
   тельно вывода длинных записей).
 
 
                              126 
 
                        000152-01 97 04
 
 
        Можно  использовать  команду  WRITE  с  квалификатором
 
   /UPDATE для изменения записи в  отличие  от  вставки  новой
 
   записи. Для того, чтобы использовать квалификатор  /UPDATE,
 
   пользователь должен открыть файл как для чтения, так и  для
 
   записи. (см. п.6.2.1).
 
        Пояснения к рис. 1:
 
        (1) команда WRITE автоматически выполняет замену  сим-
 
   вола на символьную строку, которая  не  заключена  в  знаки
 
   кавычек; замена не повторяется;
 
        (2) если символьная строка заключается в  знаки  кавы-
 
   чек, то команда WRITE не выполняет замену символа;
 
        (3) когда задано два или большее число символьных имен
 
   или символьных строк, то  команда  WRITE  соединяет  строки
 
   перед тем, как вывести запись в выходной файл;
 
        (4) в пределах символьных строк  интерпретатор  команд
 
   выполняет замену, задаваемую знаками  апострофа  при  вводе
 
   команды; команда WRITE выводит результат;
 
        (5) если данные, заданные для команды WRITE,  содержат
 
   знак апострофа, интерпретатор команд выполняет замену  сим-
 
   вола при вводе команды (как в 4); команда  WRITE  выполняет
 
   замену символа на результирующую командную строку.
 
 
 
        6.1.4. Команда CLOSE
 
 
        Команда CLOSE закрывает файл и удаляет логическое имя,
 
   созданное командой OPEN, как показано в примере.
 
 
 
 
 
 
 
 
 
 
 
                              127 
 
                        000152-01 97 04
 
 
        П р и м е р.
 
 
   $ OPEN INFILE DISK4:[MURPHY]STATS.DAT
     .
     .
     .
   $ CLOSE INFILE
 
        Если при закрытии  файла  произошла  ошибка,  то  файл
 
   остается открытым и логическое имя, назначенное  файлу,  не
 
   удаляется из таблицы логических имен. Перед выходом из про-
 
   цедуры необходимо закрыть все открытые файлы.
 
 
 
        6.2. Модификация файлов
 
 
        Пользователю предоставляются три способа для модифика-
 
   ции файлов:
 
        1) корректировка записей в текущей версии файла;
 
        2) чтение записей из входного файла и  создание  новой
 
   версии файла, которая включает изменения пользователя;
 
        3) добавление записей к текущей версии файла.
 
 
 
        6.2.1. Корректировка записей в файле                           
 
 
        Во время корректировки файла можно заменять существую-
 
   щие записи, но добавлять новые записи не  разрешено.  Когда
 
   пользователь корректирует файл, он не может  создать  новую
 
   версию входного файла.
 
        В последовательном файле пользователь может  корректи-
 
   ровать отдельные записи только в том случае,  если  исправ-
 
   ляемые записи по размеру в точности совпадают с  существую-
 
   щими записями. В файлах с индексно-последовательным методом
 
   доступа (ISAM) можно корректировать отдельные записи  неза-
 
   висимо от их размеров.
 
 
 
                              128 
 
                        000152-01 97 04
 
 
        Для корректировки записей в файле необходимо выполнить
 
   следующие действия:
 
        1) открыть файл для доступа как для записи, так и  для
 
   чтения;
 
        2) с помощью команды READ, прочесть  запись  (записи),
 
   которую необходимо модифицировать;
 
        3) изменить запись. В  последовательном  файле  размер
 
   этой  записи  должен  в  точности  соответствовать  размеру
 
   исходной записи.
 
        Если размер  измененной  записи  окажется  по  размеру
 
   короче исходной записи, необходимо дополнить запись  пробе-
 
   лами;
 
        4) с помощью команды WRITE  с  квалификатором  /UPDATE
 
   скорректированная запись заносится в файл;
 
        5) продолжить выполнение команд READ и WRITE для  чте-
 
   ния и корректировки записей в файле до  тех  пор,  пока  не
 
   будет закончена корректировка файла;
 
        6) с помощью команды CLOSE закрыть файл.
 
        После закрытия, номер версии файла не изменяется.
 
        В командной процедуре примера показано выполнение кор-
 
   ректировки последовательного файла путем чтения и корректи-
 
   ровки отдельных записей.
 
 
        П р и м е р.
 
 
   $! открыть файл STATS.DAT и назначить логическое имя FILE
   $!
   $  OPEN /READ/WRITE FILE -
      DISK4:[MURPHY] STATS.DAT
   $  BEGIN_LOOP:
   $! читать следующую запись из файла FILE в символ RECORD
      READ/END_OF_FILE = END_LOOP -
      FILE RECORD
   $! отобразить запись и удостовериться в том,
   $! необходимо ли ее изменить
   $! если это так, получить новую запись; если это
 
 
                              129 
 
                        000152-01 97 04
 
 
   $! не так, повторить цикл
   $  PROMPT:
   $   WRITE SYS$OUTPUT RECORD
   $   INQUIRE/NOPUNCTUATION YN "CHANGE? Y OR N [Y]"
   $   IF YN .EQS. "N" THEN GOTO BEGIN_LOOP
   $   INQUIRE NEW_RECORD "NEW RECORD"
   $! сравнить новую и старую записи
   $! если старая запись короче новой записи,
   $! сформировать сообщение об ошибке
   $! если старая и новая записи имеют одинаковую длину
   $! записать запись в файл
   $! в противном случае дополнить новую запись
   $! пробелами, чтобы скорректировать ее длину
   $   OLD_LEN = F$LENGTH(RECORD)
   $   NEW_LEN = F$LENGTN(NEW_RECORD)
   $   IF OLD_LEN .LT. NEW_LEN THEN GOTO ERROR
   $   IF OLD_LEN .EQ. NEW_LEN THEN GOTO WRITE_RECORD
   $   SPACES = "              "
   $   PAD = F$EXTRECT(O,OLD_LEN-NEW_LV,SPACES)
   $   NEW_RECORD = NEW_RECORD + PAD
   $!
   $  WRITE_RECORD:
   $   WRITE/UPDATE FILE NEW_RECORD
   $   GOTO BEGIN_LOOP
   $!
   $  ERROR:
   $   WRITE SYS$OUTPUT "ERROR---NEW RECORD IS TOO LONG"
   $   GOTO PROMPT
   $!
   $  END_LOOP:
   $   CLOSE FILE
   $   EXIT
 
 
        6.2.2. Создание нового выходного файла                    
 
 
        Для изменения файла может оказаться необходимым  пере-
 
   записать весь файл. Так как создается новый выходной  файл,
 
   можно изменять размер записей, добавлять или удалять  запи-
 
   си.
 
        Для создания нового выходного файла  выполняются  сле-
 
   дующие шаги:
 
        1) с помощью команды OPEN открыть файл для доступа  по
 
   чтению. Изменяемый файл является входным файлом;
 
        2) с помощью команды OPEN открыть новый файл для  дос-
 
   тупа по записи. Этот создаваемый пользователем  файл  будет
 
   выходным файлом. Если пользователь задает  выходному  файлу
 
 
 
                              130 
 
                        000152-01 97 04
 
 
   имя, совпадающее с именем  входного  файла,  выходной  файл
 
   будет иметь номер версии на единицу больше версии  входного
 
   файла;
 
        3) с помощью команды READ читать запись из изменяемого
 
   файла;
 
        4) после изменения записи использовать команду  WRITE,
 
   чтобы занести запись в новый файл;
 
        5) продолжить чтение и обработку записей до  обнаруже-
 
   ния конца входного файла;
 
        6) с помощью команды CLOSE закрыть входной и  выходной
 
   файлы.
 
        В примере представлена  командная  процедура,  которая
 
   читает запись из входного файла, затем  ее  обрабатывает  и
 
   копирует в выходной файл.
 
 
        П р и м е р.
 
 
   $! открыть файл STATS.DAT для чтения и назначить
   $! ему имя INFILE
   $! открыть новую версию файла STATS.DAT для
   $! записи и назначить ему логическое имя OUTFILE
   $!
   $  OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT
   $  OPEN/WRITE OUTFILE DISK4:[MURPHY]STATS.DAT
   $!
   $  BEGIN_LOOP:
   $!  читать следующую запись из файла INFILE в
   $!  символ RECORD
   $   READ/END_OF_FILE=END_LOOP INFILE RECORD
   $! отобразить запись и удостовериться в том,
   $! подлежит ли она изменению
   $! если это так, получить новую запись. Если
   $! запись не подлежит изменению, записать ее
   $! непосредственно в файл OUTFILE
   $! PROMPT:
   $    WRITE SYS$OUTPUT RECORD
   $    INQUIRE/NOPUNCTUATION YN "CHANGE? Y OR N[Y]"
   $    IF YN .EQS. "N" THEN GOTO WRITE_RECORD
   $    INQUIRE RECORD "NEW RECORD"
   $!
   $  WRITE_RECORD:
   $  WRITE OUTFILE RECORD
   $    GOTO BEGIN_LOOP
   $!
 
 
                              131 
 
                        000152-01 97 04
 
 
   $! закрыть входной и выходной файлы
   $  END_LOOP:
   $    CLOSE INFILE
   $    CLOSE OUTFILE
   $    EXIT
 
 
        6.2.3. Добавление записей к файлу                          
 
 
        Команда OPEN/APPEND предоставляет  возможность  добав-
 
   лять к концу существующего файла.  Для  добавления  записей
 
   необходимо выполнить следующие шаги:
 
        1) с помощью команды  OPEN  с  квалификатором  /APPEND
 
   позиционировать указатель записи в конец файла.  Квалифика-
 
   тор /APPEND не создает новую версию файла;
 
        2) с помощью команды WRITE занести новые  записи  дан-
 
   ных. Продолжить добавление записей до завершения;
 
        3) с помощью команды CLOSE закрыть файл.
 
        В примере выполняется добавление новых записей к  фай-
 
   лу.
 
 
        П р и м е р.
 
 
   $! открыть файл STATS.DAT для добавления записей
   $! и назначить ему логическое имя FILE
   $!
   $  OPEN/APPEND FILE DISK4:[MURPHY]STATS.DAT
   $!
   $  BEGIN_LOOP:
   $!   получить запись, подлежащую добавлению, и
   $!   поместить эту запись в симл RECORD
   $  PROMPT:
   $    INQUIRE RECORD "ENTER NEW RECORD(PRESS RET TO QUIT)"
   $    IF RECORD .EQS. "" THEN GOTO END_LOOP
   $!   записать запись в файл FILE
   $    WRITE FILE RECORD
   $    GOTO BEGIN_LOOP
   $!
   $! закрыть файл FILE и выполнить выход
   $  END_LOOP:
   $    CLOSE FILE
   $    EXIT
 
 
 
 
 
 
                              132 
 
                        000152-01 97 04
 
 
        6.3. Обработка ошибок ввода-вывода                             
 
 
        Для обработки ошибок используется квалификатор  /ERROR
 
   с командами OPEN, READ, WRITE и CLOSE. Квалификатор  /ERROR
 
   передает управление на метку в командной процедуре  пользо-
 
   вателя, если появляется ошибка  ввода/вывода.  Кроме  того,
 
   квалификатор /ERROR подавляет сообщение об ошибках, которые
 
   обычно должны отображаться. В примере 1 квалификатор /ERROR
 
   используется с командой OPEN.
 
 
        П р и м е р 1.
 
   $ OPEN/READ/ERROR=CHECK FILE CONTINGEN.DOC
      .
      .
      .
   $ CHECK:
   $ WRITE SYS$OUTPUT "ERROR OPENING FILE"
 
        Команда OPEN запрашивает открытие файла  CONTINGEN.DOC
 
   для чтения. Если файл не может быть открыт (например,  если
 
   файл не существует), команда OPEN возвращает условие  ошиб-
 
   ки. Управление затем передается на метку CHECK.
 
        Переход по  ошибке,  заданный  квалификатором  /ERROR,
 
   подавляет условие текущей  команды  ON,  установленное  для
 
   командного уровня. Если происходит ошибка и метка  назначе-
 
   ния полностью соответствует  управлению,  зарезервированный
 
   глобальный символ $STATUS сохраняет код ошибки. В примере 2
 
   показано  использование  лексической  функции  F$MESSAGE  в
 
   пользовательской программе обработки ошибок для отображения
 
   сообщения в символе $STATUS.
 
 
 
 
 
 
 
 
 
 
 
                              133 
 
                        000152-01 97 04
 
 
        П р и м е р 2.
 
 
   $ OPEN/READ/ERROR=CHECK FILE 'P1'
      .
      .
      .
   $ CHECK:
   $ ERROR_MESSAGE = F$MESSAGE($STATUS)
   $ WRITE SYS$OUTPUT "ошибочное открытие файла: ".P1
   $ WRITE SYS$OUTPUT ERROR_MESSAGE
      .
      .
      .
 
        Если ошибка  появляется  во  время  выполнения  команд
 
   OPEN, READ, WRITE и CLOSE и пользователь не задавал  дейст-
 
   вия по обработке ошибки, то выполняются  действия,  опреде-
 
   ленные текущей командой ON (см. раздел 7).
 
        Когда команда READ получает сообщение о  конце  файла,
 
   действие по обработке ошибки определяется  следующим  обра-
 
   зом: если используется квалификатор /END_OF_FILE, то управ-
 
   ление  передается  на  заданную  метку;  если  квалификатор
 
   /END_OF_FILE не  задан,  управление  передается  на  метку,
 
   заданную с помощью  квалификатора  /ERROR;  если  не  задан
 
   никакой квалификатор,  выполняется  действие,  определенное
 
   текущей командой ON.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              134 
 
                        000152-01 97 04
 
 
      7. Управление условиями ошибок и прерываниями CTRL/Y
 
 
 
        В этом разделе приводится описание обработки ошибок  и
 
   CTRL/Y во время выполнения командной процедуры. Также  опи-
 
   сывается возможное использование команд ON, SET [NO]ON, SET
 
   [NO]CONTROL для изменения  обработки  ошибок  и  прерываний
 
   CTRL/Y по умолчанию.
 
 
 
        7.1. Обнаружение    ошибок    в    командных           
 
             процедурах
 
 
        После завершения команды  DCL  в  командной  процедуре
 
   интерпретатор  команд  сохраняет  код  условия   завершение
 
   команды. Этот код может указывать либо на успешное заверше-
 
   ние, либо он может идентифицировать специфическое  информа-
 
   ционное сообщение или сообщение об ошибке.
 
        Интерпретатор  команд  проверяет  код  условия   после
 
   выполнения каждой команды в командной процедуре. Если обна-
 
   ружена ошибка, требующая специальных действий,  то  система
 
   выполняет эти действия. В противном случае выполняется сле-
 
   дующая команда в процедуре.
 
 
 
        7.1.1. Коды  условия   и   глобальный   символ                 
 
               $гдСдег
 
 
        Код условия сохраняется как 32-битное длинное слово  в
 
   зAрезервированном  глобальном   символе   $STATUS.   Символ
 
   $STATUS соответствует формату кода сообщения системы:
 
        1) биты 0-2 содержат уровень серьезности сообщения;
 
        2) биты 3-15 содержат номер сообщения;
 
 
 
 
                              135 
 
                        000152-01 97 04
 
 
        3) биты 16-27 содержат номер компоненты, которая  соз-
 
   дает сообщение;
 
        4) биты 28-31 содержат внутренние управляющие флаги.
 
        Если команда завершается успешно, символ $STATUS имеет
 
   нечетную величину (биты 0-2 содержат 1 или 3).  Если  появ-
 
   ляется любой тип предупреждения или ошибки, символ  $STATUS
 
   имеет четную величину (0, 2 или  4).  Интерпретатор  команд
 
   обслуживает и отображает текущую величину $STATUS  в  шест-
 
   надцатеричном представлении.
 
 
 
        7.1.2. Уровни серьезности ошибки и  глобальный                
 
               символ $SEVERITY
 
 
        Три младших бита символа $STATUS представляют  серьез-
 
   ность условия, вызвавшего  завершение  команды.  Эта  часть
 
   кода условия содержится в зарезервированном глобальном сим-
 
   воле $SEVERITY. Символ $SEVERITY может иметь величины от  0
 
   до 4, каждая из  которых  представляет  один  из  следующих
 
   уровней серьезности условия:
 
         величина             серьезность условия
 
            0                  предупреждение
 
            1                  успешное завершение
 
            2                  ошибка
 
            3                  информация
 
            4                  неисправимая ошибка
 
        Коды успешного завершения и информации имеют  нечетные
 
   числовые величины, а коды  предупреждения  и  ошибки  имеют
 
   четные числовые величины. Можно проверить успешное заверше-
 
   ние команды с помощью команды IF, которая  выполняет  логи-
 
   ческие проверки $SEVERITY или $STATUS, как показано в  при-
 
 
 
                              136 
 
                        000152-01 97 04
 
 
   мере 1.
 
        П р и м е р 1.
 
 
   $ IF $SEVERITY THEN GOTO OKAY
   $ IF $STATUS THEN GOTO OKAY
 
        По командам IF в примере 1 выполняется переход на мет-
 
   ку окаY, если символы $SEVERITY и  $STATUS  имеют  истинные
 
   (нечетные) величины.  Когда  текущая  величина  в  символах
 
   $SEVERITY и $STATUS является нечетной, то это  значит,  что
 
   команда или программа завершилась успешно. Если команда или
 
   программа завершилась неуспешно, то величина в $SEVERITY  и
 
   $STATUS  является  четной;  следовательно,   выражение   IF
 
   является ложным.
 
        Вместо проверки условия на соответствие  истине  можно
 
   выполнить проверку ложности, как показано в примере 2.
 
 
        П р и м е р 2.
 
 
   $ IF .NOT. $STATUS THEN ...
 
 
        Интерпретатор команд  использует  уровень  серьезности
 
   кода условия для определения действия команды ON, как  опи-
 
   сано в п.7.2.1.
 
 
 
        7.1.3. Команды,   которые   не   устанавливают        
 
               символ $STATUS
 
 
        Большинство команд языка DCL вызывают системные обслу-
 
   живающие программы, которые определяют значения состояния и
 
   сообщения об ошибках по их завершению. Однако, имеется нес-
 
   колько команд, которые не изменяют величин
 
 
 
 
 
 
                              137 
 
                        000152-01 97 04
 
 
   символов $STATUS и $SEVERITY, если они завершаются успешно:
 
 
           CONTINUE        IF
           DECK            SHOW STATUS
           DEPOSIT         SHOW SYMBOL
           EOD             STOP
           EXAMINE         WAIT
           GOTO
 
        Однако, если любая из этих команд заканчивается  неус-
 
   пешно, то код условия будет помещен  в  символ  $STATUS,  а
 
   уровень серьезности кода условия  будет  помещен  в  символ
 
   $SEVERITY.
 
 
 
        7.2. Обработка условия ошибок
 
 
        По умолчанию, при получении  ошибки  или  неисправимой
 
   ошибки, интерпретатор команд выполняет  команду  EXIT.  Для
 
   других уровней серьезности (успешное выполнение, предупреж-
 
   дение или информация) командная процедура продолжает выпол-
 
   няться.
 
        Имеется одно  исключение,  при  котором  интерпретатор
 
   команд обрабатывает предупреждение. Если пользователь обра-
 
   щается к метке  в  командной  процедуре,  а  эта  метка  не
 
   существует (например, если  в  процедуру  включена  команда
 
   GOTO ERR1, а ERR1 не используется в качестве метки в проце-
 
   дуре), то создается предупреждение, а  командная  процедура
 
   выполняет выход. Можно, однако, подавить такую обработку  с
 
   помощью команды ON, чтобы  задать  действие  для  командной
 
   процедуры, вызываемое при предупреждениях.
 
        Когда система формирует команду EXIT как  часть  прог-
 
   раммы обработки ошибки, она передает  величину  $STATUS  на
 
   предшествующий  командный  уровень  с   одним   изменением.
 
   Интерпретатор команд устанавливает старшую  цифру  величины
 
 
 
                              138 
 
                        000152-01 97 04
 
 
   $STATUS в 1 так, чтобы интерпретатор  команд  не  отображал
 
   повторно сообщение, связанное с кодом состояния.
 
        В примере  1  командная  процедура  TEST.COM  содержит
 
   ошибку в спецификации выходного файла.
 
 
        П р и м е р 1.
 
 
   $ CREATE DUMMY.DAT\
   $ SHOW TIME
 
        Когда пользователь выполнит процедуру примера  1  (см.
 
   Пример  2),  команда  CREATE  возвращает  ошибку  в  символ
 
   $STATUS  и  отображает  соответствующее  сообщение.   Затем
 
   интерпретатор команд проверяет величину $STATUS, определяет
 
   наличие ошибки, формирует команду EXIT и возвращает величи-
 
   ну $STATUS. Когда процедура выполнят выход, сообщение  пов-
 
   торно не отображается, так как команда CREATE  уже  однажды
 
   отобразила сообщение. Возвратившись  на  командный  уровень
 
   DCL, величина $STATUS содержит сообщение об ошибке,  но  ее
 
   старшая цифра установлена в 1.
 
 
        П р и м е р 2.
 
 
   $ @TEST
     %CREATE-E-OPENOUT, ERROR OPENING DUMMY.DAT
     (ошибка открытия)
   $ SHOW SYMBOL $STATUS
     $STATUS = "%X109110A2"
   $ WRITE SYS$OUTPUT F$MESSAGE(%X109110A2)
     %CREATE-E-OPENOUT, ERROR OPENING  !AS AS OUTPUT
                        (ошибка открытия как выводного)
 
        Можно использовать команды ON или SET [NO]ON для изме-
 
   нения реакции системы на ошибки в командных процедурах.
 
 
 
 
 
 
 
 
 
 
                              139 
 
                        000152-01 97 04
 
 
        7.2.1. Команда ON
 
 
        Команда ON задает действие, которое необходимо  выпол-
 
   нить если имела место ошибка определенного  уровня  серьез-
 
   ности. Если такая ошибка обнаружена  выполняются  следующие
 
   действия:
 
        1) выполняется действие, заданное командой ON;
 
        2) устанавливается $STATUS и $SEVERITY  для  индикации
 
   результата заданного действия ON. (в общем случае они уста-
 
   навливаются для успешного завершения);
 
        3) сбрасывается действие по ошибке по  умолчанию  (для
 
   выполнения выхода, если имела место ошибка или неисправимая
 
   ошибка).
 
        Формат команды ON следующий:
 
   ON условие THEN [$] команда
 
        Пользователь может задать  условия  ошибки  с  помощью
 
   одного из ключевых слов: WARNING, ERROR  или  SEVERE_ERROR.
 
   Если действие команды ON установлено для  заданного  уровня
 
   серьезности, интерпретатор команд будет выполнять  заданное
 
   действие, когда появится ошибка с тем же или  более  худшим
 
   уровнем серьезности.  Когда  появляются  ошибки  с  меньшим
 
   уровнем серьезности, интерпретатор команд будет  продолжать
 
   обработку файла. В табл. 4 приведена  сводка  по  обработке
 
   ошибок по команде ON.
 
                                                    Таблица 4
 
              Kлючевые слова и действия команды ON
 
   ----------------------------------------------------------
     Kлючевое слово    !        Bыполняемое действие
     команды ON        !
   ----------------------------------------------------------
                       !
   WARNING             !   Kомандная процедура выполняет  за-
                       ! данное  действие,  если  имели место
                       ! предупреждения, ошибка или  неиспра-
 
 
                              140 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 4
   ----------------------------------------------------------
     Ключевое слово    !        Выполняемое действие
     команды ON        !
   ----------------------------------------------------------
                       !
                       ! вимая ошибка
                       !
   ERROR               !   Командная процедура выполняет  за-
                       ! данное  действие,  если  имели место
                       ! ошибка или неисправимая ошибка
                       !
   SEVERE_ERROR        !   Командная процедура выполняет  за-
                       ! данное  действие,  если  имела место
                       !  неисправимая  ошибка;     процедура
                       ! продолжает  выполнение,  если  имели
                       ! место предупреждение или ошибка.
                       !
 
        Например,  если  пользователю  необходимо   отвергнуть
 
   обработку ошибки по умолчанию так, чтобы процедура выполня-
 
   ла выход при появлении предупреждений, ошибок или  неиспра-
 
   вимых ошибок, можно использовать команду:
 
   $ ON WARNING THEN EXIT
 
        Действие команды ON выполняется только один раз.  Нап-
 
   ример, процедура пользова
теля содержит следующую команду:
 
   $ ON ERROR THEN GOTO ERR1
 
        В этом случае командная процедура нормально выполняет-
 
   ся до тех пор, пока не  появится  ошибка  или  неисправимая
 
   ошибка. Если обнаружена такая ошибка, процедура  возобновит
 
   выполнение с ERR1, $STATUS и  $SEVERITY  устанавливаются  в
 
   успешное состояние и восстанавливается действие при  ошибке
 
   по умолчанию. Если появляется вторая ошибка перед  выполне-
 
   нием другой команды ON или SET  NOON,  процедура  выполняет
 
   выход на предшествующий командный уровень.
 
        Действие, заданное командой ON, распространяется толь-
 
   ко в пределах командной процедуры,  в  которой  выполняется
 
   эта команда. Команда ON, выполненная в командной  процедуре
 
   любого уровня вложения,  не  влияет  на  обработку  условий
 
 
 
                              141 
 
                        000152-01 97 04
 
 
   ошибки процедур на любом другом уровне.
 
        Рис. 2 иллюстрирует действия команды ON.  Кроме  того,
 
   типовые процедуры FORTUSER.COM и CALC.COM  в  приложении  1
 
   иллюстрируют использование команды ON для  установки  обра-
 
   ботки ошибок.
 
 
 
        7.2.2. Блокировка проверки ошибок                           
 
 
        Пользователь  может  запретить  интерпретатору  команд
 
   проверять состояния,  возвращаемые  из  команд,  с  помощью
 
   команды SET NOON в командной процедуре. Команда SET NOON не
 
   запрещает интерпретатору команд помещать величины в $STATUS
 
   и $SEVERITY, но блокирует проверку любых ошибок.  Пользова-
 
   тель может восстановить проверку ошибок  с  помощью  команд
 
   SET ON или ON.
 
 
        П р и м е р 1.
 
 
   $ SET NOON
   $ RUN TESTA
   $ RUN TESTB
   $ SET ON
 
        В примере 1 команда SET NOON,  предшествующая  команде
 
   RUN, гарантирует, что командная процедура будет продолжена,
 
   если любая из программ TESTA или TESTB  возвращает  условие
 
   ошибки. Команда SET ON восстанавливает обработку ошибок  по
 
   умолчанию интерпретатором команд.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              142 
 
                        000152-01 97 04
 
 
                       Действия команды ON
 
 
       .
       .
       .            DBA1:[HIGGINS]FORT.COM
                    -----------------------------
       $ @FORT ---->! .                         !
   -->              ! .                         !
   !                ! .                         !
   !                ! $ ON ERROR THEN CONTINUE  !  (1)
   !                ! $ FORTRAN A               !  (2)
   !                ! .                         !
   !                ! .                         !
   !                ! .                         !
   !<-------------- ! $ FORTRAN B               !
   !                ! .                         !
   !                ! .                         !
   !                ! .                         !
   !                ! $ ON WARNING THEN EXIT    !  (3)
   !                ! .                         !
   !                ! .                         !
   !                ! .                         !
   !<-------------- ! $ FORTRAN C               !  (4)
   !                ! .                         !
   !                ! .                         !
   !                ! .                         !
   ---------------- ! $ EXIT                    !
                    -----------------------------
 
 
 
                             Рис. 2
 
 
 
        Пояснения к рис. 2:
 
        (1) команда ON подавляет действия команды по умолчанию
 
   (продолжение - при предупреждении; выход  -  при  ошибке  и
 
   неисправимой ошибке); если ошибка или  неисправимая  ошибка
 
   произошли во время компиляции, то командная процедура  про-
 
   должается со следующей команды;
 
        (2) действие по умолчанию сбрасывается после  предыду-
 
   щей команды ON. Таким образом, если  произошла  ошибка  или
 
   неисправимая  ошибка  при  компиляции  A.FOR  и  B.FOR,  то
 
   командная процедура выполняет выход;
 
        (3) команда ON устанавливает выход из командной проце-
 
   дуры по предупреждению и любой ошибке;
 
 
                              143 
 
                        000152-01 97 04
 
 
        (4) если имели место предупреждение, ошибка или неисп-
 
   равимая ошибка произошла в то время, когда  была  завершена
 
   компиляция C.FOR, командная процедура выполняет выход.
 
        Если проверка  ошибок  блокируется,  можно  специально
 
   проверить величину $STATUS вслед за выполнением команды или
 
   программы.
 
 
        П р и м е р 2.
 
 
   $ SET NOON
   $ FORTRAN MYFILE
   $ IF $STATUS THEN LINK MYFILE
   $ IF $STATUS THEN RUN MYFILE
   $ SET ON
 
        В примере 2 первая команда IF проверяет  соответствует
 
   ли величина $STATUS истине (то есть, является ли она нечет-
 
   ной числовой величиной). Если это так, то  команда  FORTRAN
 
   была успешна и будет выполнена команда LINK. После  команды
 
   LINK  вновь  проверяется  величина  $STATUS.  Если  $STATUS
 
   является нечетной величиной, то будет  выполняться  команда
 
   RUN; в противном случае команда RUN не  будет  выполняться.
 
   Команда SET ON  восстанавливает  действие  условий  текущей
 
   команды ON; то  есть  восстанавливается  воздействие  любых
 
   условий, которые имели влияние до  выполнения  команды  SET
 
   NOON.
 
        Команды SET ON или SET  NOON  применяются  только  для
 
   текущего командного уровня, то есть, для командного уровня,
 
   на котором  выполняется  команда.  Если  команда  SET  NOON
 
   используется в командной процедуре, которая вызывает другую
 
   командную процедуру,  то  в  пределах  вложенной  процедуры
 
   будет сказываться влияние  проверки  ошибок  по  умолчанию.
 
   Команда SET NOON не будет оказывать влияния, если она  вво-
 
   дится на командном уровне 0.
 
 
                              144 
 
                        000152-01 97 04
 
 
        7.3. Обработка прерываний YC/Y                           
 
 
        По умолчанию,  при  вводе  YC/Y  во  время  выполнения
 
   командной  процедуры,  интерпретатор  команд   подсказывает
 
   командный ввод на специальном командном уровне,  называемом
 
   командным уровнем YC/Y. Из  командного  уровня  YC/Y  можно
 
   ввести команды DCL, которые выполняются в пределах  интерп-
 
   ретатора команд, и затем возобновить  выполнение  командной
 
   процедуры с помощью команды CONTINUE.
 
        Остановить процедуру можно  путем  выполнения  команды
 
   DCL, которая заставит остановиться командную процедуру.
 
        Можно отвергнуть путь, по которому командная процедура
 
   обрабатывает прерывания YC/Y, путем  использования  команды
 
   ON, как описано в п.7.3.2.
 
 
 
        7.3.1. Прерывание командной процедуры             
 
 
        Пользователь может  прервать  интерактивную  командную
 
   процедуру вводом YC/Y. При вводе YC/Y интерпретатор  команд
 
   устанавливает новый командный уровень,  называемый  уровнем
 
   YC/Y, и выполняет подсказку командного ввода.
 
        Когда в действительности произойдет прерывание,  зави-
 
   сит от выполняемой команды:
 
        1) если текущей выполняемой командой является команда,
 
   выполняемая самим интерпретатором  (например,  команды  IF,
 
   GOTO  или  оператор  присваивания),  то  команда  завершает
 
   выполнение перед тем, как интерпретатор команд введет подс-
 
   казку для команды на уровне YC/Y;
 
        2) если текущей выполняемой  командой  или  программой
 
   является отдельный  образ  (то  есть,  образ,  отличный  от
 
   интерпретатора команд), то команда прерывается и  интерпре-
 
 
                              145 
 
                        000152-01 97 04
 
 
   татор команд выполняет  подсказку  для  команды  на  уровне
 
   YC/Y.
 
        На уровне YC/Y интерпретатор команд запоминает состоя-
 
   ние всех ранее установленных командных уровней  так,  чтобы
 
   можно было восстановить корректное состояние  после  любого
 
   прерывания YC/Y.
 
        После ввода YC/Y пользователь может выполнить  следую-
 
   щие действия:
 
        1) ввести команду DCL, выполняемую в пределах  интерп-
 
   ретатора команд. К таким  командам  относятся  команды  SET
 
   VERIFY,  SHOW  TRANSLATION,  ASSIGN,  SHOW  TIME,  EXAMINE,
 
   DEPOSIT, SPAWN и ATTACH. После того, как введены  одна  или
 
   больше этих команд, можно возобновить выполнение  процедуры
 
   по команде CONTINUE. В  документе  [1]  представлен  полный
 
   список  команд,  выполняемых  в   пределах   интерпретатора
 
   команд;
 
        2) по команде CONTINUE, интерпретатор команд возобнов-
 
   ляет выполнение с прерванной команды или программы, или  со
 
   строки после первой завершенной команды;
 
        3) ввести команду DCL, которая выполняет другой образ.
 
   В этом случае интерпретатор команд возвращается на  команд-
 
   ный уровень 0 и выполняет команду. Это завершает выполнение
 
   командной процедуры. Любые обработчики выхода,  об'явленные
 
   прерванным образом, будут разрешены  для  выполнения  перед
 
   запуском нового образа;
 
        4) ввести команду EXIT или STOP для завершения  выпол-
 
   нения командной процедуры. При использовании  команды  EXIT
 
   будут выполняться программы обработчики выхода, об'явленные
 
   прерванным образом. Команда STOP не выполняет эти  програм-
 
   мы.
 
 
                              146 
 
                        000152-01 97 04
 
 
        Если прерывается выполнение привилегированного образа,
 
   можно ввести только команды  CONTINUE,  SPAWN  или  ATTACH,
 
   если есть необходимость в сохранении контекста образа. Если
 
   будут введены любые другие команды (за  исключением  команд
 
   из подпроцесса, который порожден образом или подсоединен  к
 
   нему),  привилегированный  образ  принудительно   выполняет
 
   выход.
 
 
 
        7.3.2. Установка    подпрограммы     обработки              
 
               прерывания CTRL/Y
 
 
        Команда ON, определяющая действие, которое  необходимо
 
   выполнить в случае ошибки,  также  определяет  подпрограмму
 
   обработки прерывания  CTRL/Y,  которое  вводится  во  время
 
   выполнения командной  процедуры.  Задаваемое  пользователем
 
   действие подавляет  действие  по  умолчанию  интерпретатора
 
   команд (то есть, подсказку для ввода команды  на  командном
 
   уровне CTRL/Y).
 
 
        П р и м е р 1.
 
   $ ON CONTROL_Y THEN EXIT
 
        Если в процедуре выполняется  указанная  в  примере  1
 
   команда ON, то подпоследовательность прерывания  CTRL/Y  во
 
   время выполнения командной процедуры вызывает выход из про-
 
   цедуры. Управление передается на  предшествующий  командный
 
   уровень.
 
        Когда пользователь вводит CTRL/Y для прерывания проце-
 
   дуры, в которой используется команда  ON  CONTROL_Y,  вызы-
 
   ваются следующие действия:
 
        1) если текущей выполняемой командой является команда,
 
   выполняемая в пределах интерпретатора  команд,  то  команда
 
 
                              147 
 
                        000152-01 97 04
 
 
   завершается и  затем  выполняется  действие  по  прерыванию
 
   CTRL/Y;
 
        2) если текущая команда выполняется с помощью  образа,
 
   отличного от  интерпретатора  команд,  образ  принудительно
 
   выполняет выход, и затем выполняется действие по прерыванию
 
   CTRL/Y. Если, однако,  образ  об'явил  программу  обработки
 
   выхода, то она выполняется перед вызовом действия  прерыва-
 
   ния CTRL/Y. Образ не может продолжить выполнение  вслед  за
 
   прерыванием CTRL/Y.
 
        Выполнение действия по CTRL/Y автоматически не сбрасы-
 
   вает действие CTRL/Y по умолчанию. Действие CTRL/Y  продол-
 
   жает оказывать влияние до тех пор, пока не произойдет  одно
 
   из следующих событий:
 
        1)  процедура  завершится  (в  результате   выполнения
 
   команд EXIT или STOP или действия по  обработке  ошибки  по
 
   умолчанию);
 
        2) будет выполнена другая команда ON CONTROL_Y;
 
        3) процедура выполнит  команду  SET  NOCONTROL=Y  (см.
 
   п.7.3.3).
 
        Например, процедура может содержать командную  строку,
 
   как показано в примере 2.
 
 
        П р и м е р 2.
 
   $ ON CONTROL_Y THEN SHOW TIME
 
        Когда выполняется процедура с командной строкой приме-
 
   ра 2, каждое прерывание YC/Y  вызывает  выполнение  команды
 
   SHOW TIME.  После  выполнения  каждой  команды  SHOW  TIME,
 
   выполнение возобновляется с команды, следующей за  прерван-
 
   ной командой.
 
        На рис. 3 показаны две команды ON CONTROL_Y  и  описы-
 
 
 
                              148 
 
                        000152-01 97 04
 
 
   вается поток выполнения, следующий за прерываниями YC/Y.
 
        Действие прерывания  YC/Y  можно  задать  для  каждого
 
   активного командного уровня; действие  YC/Y,  заданное  для
 
   текущего выполняемого командного уровня, подавляет действие
 
   (действия), заданное для предшествующих уровней. Если обра-
 
   ботка YC/Y установлена на командном уровне, то действием по
 
   умолчанию  для  командных   уровней   подпоследовательности
 
   является выход. На рис.4 показана обработка YC/Y  вложенной
 
   командной процедурой.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              149 
 
                        000152-01 97 04
 
 
         поток выполнения, следующий за прерыванием YC/Y
 
 
      .
      .              DBA1:[HIGINS]FILES.COM
      .              ---------------------------------------
      $ @FILES       ! .                                   !
      .              ! .                                   !
      .              ! .                                   !
      .              ! $ ON CONTROL_Y THEN CLEAN_UP        !
      YC/Y (1)       ! .                                   !
                     ! .                                   !
      $ <---------   ! .                                   !
                 !   ! $ TYPE STATUS.OUT;1  (2)            !
                 !   ! $ IF$STATUS THEN DELETE STATUS.OUT;1!
      .          !   ! .                                   !
      $PRIV      !   ! .                                   !
      .          !   ! .                                   !
      .          !   ! $ EXIT                              !
      .          !   ! $ CLEAN_UP:                         !
      YC/Y (4)   !   ! $ DELETE STATUS.OUT;1               !
                 !   ! $ DELETE *.TMP;*                    !
                 ----! $ EXIT (3)                          !
                     ---------------------------------------
   прерывание не
   разрешено...
   продолжение       DBA:1[HIGGINS]PRIV.COM
                     ----------------------------------------
                     ! .                                    !
                     ! .                                    !
                     ! .                                    !
                     ! $ ON CONTROL_Y THEN WRITE SYS$OUTPUT-!
                     ! "прерывание не разрешено...          !
                     !  продолжение"                        !
                     ! .                                    !
                     ! .                                    !
                     ! .                                    !
                     ! $ TYPE STATUS.OUT;1 (5)              !
                     ! $ IF $STATUS THEN DELETE STATUS.OUT;1!
                     ! .                                    !
                     ! .                                    !
                     ! .                                    !
                     ----------------------------------------
 
 
 
                             Рис. 3
 
 
 
        Пояснения к рис. 3:
 
 
        Прерывание YC/Y (1)  появляется  во  время  выполнения
 
   команды TYPE (2). Управление передается на метку  CLEAN_UP.
 
   После выполнения программы  командная  процедура  выполняет
 
 
 
                              150 
 
                        000152-01 97 04
 
 
   выход (3) и возвращает управление на интерактивный  команд-
 
   ный уровень.
 
        Прерывание YC/Y (4)  появляется  во  время  выполнения
 
   команды TYPE (5). Выполняется  команда  WRITE,  заданная  в
 
   команде ON. Затем командная процедура продолжает выполнение
 
   с команды, следующей за прерванной командой.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              151 
 
                        000152-01 97 04
 
 
       Действие прерывания YC/Y по умолчанию для вложенных
 
                            процедур
 
 
    $ @SEARCH       DBA1:[HIGGINS]SEARCH.COM
    .               -------------------------------------
    .               ! .                                 !
    .               ! .                                 !
                    ! .                                 !
    YC/Y  (1)       ! $ ON CONTROL_Y THEN GOTO CLEAN_UP !
    .               ! .                                 !
    .               ! .                                 !
    .               ! .                                 !
                    ! $ @SUBSEARCH                      !
                    ! $ NEXT_STEP:                      !
                    ! .                                 !
                    ! .                                 !
                    ! .                                 !
                    ! $ EXIT                            !
                    ! $ CLEAN_UP:                       !
                    ! .                                 !
                    ! .                                 !
                    ! .                                 !
                    -------------------------------------
 
                    DBA1:[HIGGINS]SUBRERCH.COM
                    -------------------------------------
                    ! .                                 !
                    ! .                                 !
    YC/Y  (2)       ! .                                 !
                    ! $ @SUBSUB                         !
    .               ! .                                 !
    .               ! .                                 !
    .               ! .                                 !
                    -------------------------------------
 
                    DBA1:[HIGGINS]SUBSUB.COM
                    -------------------------------------
                    ! .                                 !
                    ! .                                 !
                    ! .                                 !
    YC/Y  (3)       ! $ ON CONTROL_Y THEN SHOW TIME     !
                    ! .                                 !
                    ! .                                 !
                    ! .                                 !
                    ! $ EXIT                            !
                    -------------------------------------
 
 
 
                             Рис. 4
 
 
 
        Пояснения к рис. 4:
 
        (1) если прерывание YC/Y появляется во время  выполне-
 
 
 
                              152 
 
                        000152-01 97 04
 
 
   ния процедуры SEARCH.COM, управление  передается  на  метку
 
   CLEAN_UP;
 
        (2) если прерывание YC/Y появляется во время  выполне-
 
   ния процедуры SUBSEARCH.COM, то  управление  передается  на
 
   метку NEXT_STEP в процедуре SEARCH.COM.  Так  как  действие
 
   прерывания YC/Y задано в SUBSEARCH.COM, то по  YC/Y  выпол-
 
   няется выход на предыдущий командный уровень;
 
        (3) если прерывание YC/Y появляется во время  выполне-
 
   ния процедуры SUBSUB.COM, выполняется команда SHOW TIME.
 
 
 
        7.3.3. Запрещение и выполнение прерываний YC/Y     
 
 
        Команда SET NOCONTROL=Y полностью блокирует  обработку
 
   прерываний YC/Y, т.е., если в процедуре выполняется команда
 
   SET NOCONTROL=Y, ввод YC/Y не будет  оказывать  влияние  на
 
   последовательность выполняемых команд.
 
        Команда SET NOCONTROL=Y также отменяет  текущую  обра-
 
   ботку YC/Y, установленную командой ON CONTROL_Y.  Для  пов-
 
   торной установки действия интерпретатора команд по  умолча-
 
   нию для обработки прерывания YC/Y необходимо ввести следую-
 
   щие команды: $SET NOCONTROL=Y ; $SET CONTROL=Y.
 
        Первая команда запрещает  обработку  YC/Y  и  отменяет
 
   текущее действие команды ON CONTROL_Y; вторая команда вклю-
 
   чает обработку YC/Y. С этого момента действие по  умолчанию
 
   восстанавливается: если вводится YC/Y во  время  выполнения
 
   процедуры, интерпретатор  команд  выполняет  подсказку  для
 
   команд на командном уровне YC/Y.
 
        Пользователь может ввести команду SET  NOCONTROL=Y  на
 
   любом командном уровне; она влияет на все командные  уровни
 
   до тех пор, пока команда SET CONTROL=Y не включит  повторно
 
 
 
                              153 
 
                        000152-01 97 04
 
 
   обработку YC/Y.
 
 
 
 
                8. Работа с пакетными заданиями
 
 
 
        Пакетное задание состоит из одной или  большего  числа
 
   командных процедур, которые выполняются из другого  процес-
 
   са. Для выполнения пакетного задания  используется  команда
 
   SUBMIT, которая ставит пакетное задание в очередь  пакетных
 
   заданий. Очередь пакетных заданий является списком пакетных
 
   заданий, ожидающих  выполнение.  После  того,  как  система
 
   поместила задание пользователя в очередь пакетных  заданий,
 
   пользователь может продолжить  интерактивное  использование
 
   своего терминала. Таким образом, пакетное задание представ-
 
   ляет пользователю возможность  использовать  свой  терминал
 
   для другой работы, в то время как система выполняет команд-
 
   ную процедуру пользователя.
 
        Задание пользователя выполняется в виде отсоединенного
 
   процесса.
 
        Для  создания  отсоединенного  процесса   используется
 
   информация из записи пользователя в файле авторизации. Сис-
 
   тема выполняет файл команд регистрации пользователя и затем
 
   выполняет командную процедуру (процедуры) в пакетном  зада-
 
   нии. По мере выполнения этих процедур, вывод записывается в
 
   файл регистрации. Когда задание  завершается,  пользователь
 
   может распечатать файл регистрации и/или  сохранить  его  в
 
   одном из своих каталогов.
 
        В общем  случае,  пакетные  задания  используются  для
 
   выполнения командных процедур, которые либо  требуют  много
 
   времени для выполнения,  либо  необходимо  планировать  для
 
 
 
                              154 
 
                        000152-01 97 04
 
 
   выполнения после  определенного  времени,  либо  используют
 
   много системных ресурсов. Для таких процедур, которые будут
 
   использовать много системных ресурсов, можно  задать  пони-
 
   женный приоритет пакетного задания.
 
        В этом разделе приводится описание методов для  предс-
 
   тавления и управления  пакетными  заданиями  и  обсуждаются
 
   следующие темы:
 
        1) представление пакетных заданий;
 
        2) управление выводом пакетного задания;
 
        3) управление заданиями в очереди пакетных заданий;
 
        4) повторный запуск пакетных заданий;
 
        5) синхронизация пакетных заданий.
 
 
 
        8.1. Представление пакетного задания              
 
 
        Команда SUBMIT используется для ввода командной проце-
 
   дуры в  очередь  пакетных  заданий.  По  умолчанию  команда
 
   SUBMIT помещает командную  процедуру  в  очередь  с  именем
 
   SYS$BATCH. Тип файла по умолчанию COM.
 
 
        П р и м е р.
 
 
   $ SUBMIT UPDATE
   JOB UPDATE(QUEUE SYS$BATCH,ENTRY201)STARTED ON SYS$BATCH
 
        В  примере  создается  пакетное  задание,   называемое
 
   UPDATE, которое содержит  командную  процедуру  UPDATE.COM.
 
   Это задание вводится в очередь SYS$BATCH и ему  назначается
 
   номер входа 201. (обычно к  заданию  обращаются  по  номеру
 
   входа). Системное сообщение указывает на  то,  что  очередь
 
   SYS$BATCH запущена для выполнения задания пользователя.
 
        Когда пользователь  представляет  командную  процедуру
 
   для пакетного выполнения, система сохраняет полную специфи-
 
 
                              155 
 
                        000152-01 97 04
 
 
   кацию файла для командной процедуры, включая номер  версии.
 
   Если пользователь корректирует командную процедуру после ее
 
   представления, пакетное задание все еще выполняет  исходную
 
   версию командной процедуры пользователя. Так как  умолчания
 
   регистрации обычно не совпадают с умолчаниями, которые тре-
 
   буются для доступа к файлам в командной процедуре,  исполь-
 
   зуется один из следующих методов  для  гарантии  доступа  к
 
   корректным файлам:
 
        1) используется полная спецификация файла; при обраще-
 
   нии к файлу в командной  процедуре  или  передаче  файла  в
 
   командную процедуру включаются имена устройства и  каталога
 
   в качестве части спецификации файла;
 
        2) используется команда SET DEFAULT. Перед  обращением
 
   к файлу в  командной  процедуре  используется  команда  SET
 
   DEFAULT для задания требуемого устройства или каталога.
 
        По мере выполнения пакетного задания вывод записывает-
 
   ся в журнальный файл. По умолчанию файл журнала имеет то же
 
   имя, что и командная процедура, представленная  пользовате-
 
   лем, но с типом файла  LOG.  Когда  задание  заканчивается,
 
   файл журнала распечатывается и затем удаляется из  каталога
 
   пользователя. В п.8.3.1 описывается способ сохранения  жур-
 
   нальных файлов.
 
 
 
        8.1.1. Проверка   для   пакетных   заданий   в             
 
               командном       файле       регистрации           
 
               пользователя
 
 
        Всякий раз при представлении задания система выполняет
 
   командный файл регистрации пользователя. Пользователь может
 
   включить или опустить выполнение секции  своего  командного
 
 
 
                              156 
 
                        000152-01 97 04
 
 
   файла  регистрации,  когда  выполняется  пакетное  задание,
 
   используя лексическую функцию F$MODE() для проверки  пакет-
 
   ных заданий.
 
        Например, может быть секция в командном файле  регист-
 
   рации, которая содержит команды, логические имена и  симво-
 
   лы, которые используются исключительно для  пакетных  зада-
 
   ний. Эту секцию можно пометить  как  BATCH_COMMANDS,  затем
 
   включить  команду  примера  1  в  начало  командного  файла
 
   регистрации.
 
 
        П р и м е р 1.
 
 
   IF F$MODE() .EQS. "BATCH" THEN GOTO BATCH_COMMANDS
      .
      .
      .
 
        Для  защиты  системы  от  выполнения  любых  команд  в
 
   командном  файле  регистрации   пользователя   используется
 
   команда в начале любого файла, как в примере 2.
 
 
        П р и м е р 2.
 
   IF F$MODE() .NES. "INTERACTIVE" THEN EXIT
 
        Эту команду можно указать  в  любом  месте  командного
 
   файла регистрации пользователя.
 
 
 
        8.1.2. Представление   нескольких    командных    
 
               процедур
 
 
        В команде SUBMIT можно задать несколько командных про-
 
   цедур, подлежащих выполнению в одном задании.
 
 
 
 
 
 
 
 
 
                              157 
                                                           
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $ SUBMIT UPDATE,SORT
   JOB UPDATE(QUEUE SYS$BATCH,ENTRY207)STARTED ON SYS$BATCH
 
        Команда SUBMIT примера  1  создает  пакетное  задание,
 
   которое выполняет процедуру UPDATE.COM, а затем - процедуру
 
   SORT.COM. Если имя  не  задается  с  помощью  квалификатора
 
   /NAME, то команда SUBMIT использует  имя  первой  командной
 
   процедуры в качестве имени задания.  Если  ошибка  в  любой
 
   командной процедуре в задании приводит к ее завершению,  то
 
   завершается и все задание.
 
        Когда выполняется пакетное задание, операционный  кон-
 
   текст первой процедуры (UPDATE.COM) не  защищен  от  второй
 
   процедуры (SORT.COM), то есть,  система  удаляет  локальные
 
   символы, созданные процедурой UPDATE.COM, перед выполнением
 
   процедуры SORT.COM. Глобальные символы, однако,  сохраняют-
 
   ся.
 
        Пользователь не может задавать различные параметры для
 
   отдельных командных процедур в одном задании. В  примере  2
 
   два одинаковых параметра передаются в процедуры  UPDATE.COM
 
   и SORT.COM.
 
 
        П р и м е р 2.
 
 
   $ SUBMIT UPDATE, SORT/PARAMETERS = -
     (DISK1:[ACCOUNT.BILLS]DATA.DAT,DISK2:[ACCOUNT]NAME.DAT)
     JOB UPDATE(QUEUE SYS$BATCH,ENTRY208)STARTED ON SYS$BATCH
 
 
        8.1.3. Управление пакетным заданием              
 
 
        Управление представлением пакетного задания выполняет-
 
   ся с помощью соответствующих параметров с командой SUBMIT.
 
        Пользователь может выполнить следующие операции:
 
 
 
 
                              158 
 
                        000152-01 97 04
 
 
        1) присвоить имя  заданию.  Используется  квалификатор
 
   /NAME для назначения имени пакетного задания.  В  противном
 
   случае имя задания, по умолчанию, соответствует имени файла
 
   первой (или единственной) командной процедуры в задании;
 
        2) задать время, когда  пакетное  задание  запускается
 
   для выполнения. Используется квалификатор /AFTER для  зада-
 
   ния времени, после которого задание может выполняться. Ког-
 
   да используется квалификатор  /AFTER,  задание  остается  в
 
   очереди пакетных заданий до заданного  времени;  затем  оно
 
   выполняется. Для сохранения пакетного задания в очереди  до
 
   тех пор, пока оно не будет специально запущено  пользовате-
 
   лем, используется квалификатор /HOLD. (для выполнения  сох-
 
   раненного     задания     используется     команда      SET
 
   QUEUE/ENTRY/RELEASE);
 
        3) запросить указание о  завершении  задания.  Исполь-
 
   зуется квалификатор /NOTIFY для передачи на терминал  поль-
 
   зователя сообщения, о завершении пакетного задания;
 
        4) передать задание в заданную  очередь.  Используется
 
   квалификатор /QUEUE для передачи пакетных  заданий  в  оче-
 
   редь, отличную от SYS$BATCH. Для выполнения командной  про-
 
   цедуры, которая размещается на удаленном узле, используется
 
   квалификатор /REMOTE. В этом случае  задание  передается  в
 
   очередь SYS$BATCH в удаленном узле;
 
        5)  задать  характеристики  выполнения.   Пользователь
 
   может задать характеристики выполнения, такие  как  рабочий
 
   набор по умолчанию, экстент рабочего набора, размер рабоче-
 
   го набора, приоритет планирования задания и временный лимит
 
   центрального процессора;
 
        6)   передать   параметры.    Используется    параметр
 
   /PARAMETERS для передачи параметров в пакетное задание;
 
 
                              159 
 
                        000152-01 97 04
 
 
        7) сохранить файл регистрации. Используются квалифика-
 
   торы /NOPRINT или /KEEP для  сохранения  файла  регистрации
 
   задания. В подразделе 8.3  приводится  описание  управления
 
   выводом пакетного задания;
 
        8)  создать  повторно  запускаемое  пакетное  задание.
 
   Используется квалификатор /RESTART, чтобы включить  повтор-
 
   ный запуск задания после сбоя  системы.  В  подразделе  8.5
 
   приводится описание повторного запуска пакетных заданий.
 
 
 
        8.2. Передача данных в пакетное задание          
 
 
        Для пакетного задания  входным  потоком  по  умолчанию
 
   (SYS$INPUT) является выполняемая командная  процедура.  Так
 
   как пакетное задание выполняется из отсоединенного  процес-
 
   са, пользователь не может переопределить SYS$INPUT для тер-
 
   минала (как это можно сделать с  интерактивными  командными
 
   процедурами). Поэтому ввод в  пакетное  задание  передается
 
   одним из следующих способов:
 
        1) включить данные в саму командную процедуру;
 
        2) временно определить SYS$INPUT как файл;
 
        3) передать параметры для командной процедуры.
 
        Для включения данных в командную процедуру надо помес-
 
   тить данные на строках после команды или образа, как  пока-
 
   зано в примере 1.
 
 
        П р и м е р 1.
 
 
   $! выполнить AVERAGE.EXE
   $ RUN AVERAGE
   647
   899
   632
   401
   $ EXIT
 
 
 
                              160 
 
                        000152-01 97 04
 
 
        Для  временного  переопределения  входного  потока  по
 
   умолчанию SYS$INPUT в качестве файла, используется  команда
 
   DEFINE/USER_MODE в примере 2.
 
 
        П р и м е р 2.
 
 
   $ DEFINE/USER_MODE SYS$INPUT STATS.DAT
   $ RUN AVERAGE
   $ EXIT
 
        Для передачи параметров в командную процедуру  исполь-
 
   зуется квалификатор /PARAMETERS при представлении пакетного
 
   задания в примере 3.
 
 
        П р и м е р 3.
 
 
   $ SUBMIT/PARAMETERS=(DISK1:[PAYROLL]EMPLOYEES.DAT) CHECKS
   JOB CHECKS(QUEUE SYS$BATCH,ENTRY209)STARTED ON SYS$BATCH
 
        Нельзя  задавать  различные  параметры  для  отдельной
 
   командной процедуры в одном пакетном задании.
 
        Команда SHOW QUEUE/FULL отображает  полную  информацию
 
   об очереди пакетных заданий.  В  это  отображение  включены
 
   любые параметры, которые пользователь передавал в  процеду-
 
   ру. Поэтому не рекомендуется передавать не подлежащую разг-
 
   лашению информацию (такую, как пароль) в пакетное задание.
 
 
 
        8.3. Вывод из пакетного задания                    
 
 
        Если команда SUBMIT используется  без  квалификаторов,
 
   которые изменяют файл регистрации, то он создается в  ката-
 
   логе регистрации пользователя. Этот файл регистрации  имеет
 
   имя, совпадающее с первой командной процедурой  в  пакетном
 
   задании, и тип файла LOG. Один раз в минуту вывод из пакет-
 
   ного задания записывается в файл регистрации. Когда задание
 
   завершается, файл регистрации распечатывается на  системном
 
 
                              161 
 
                        000152-01 97 04
 
 
   печатающем устройстве по умолчанию и удаляется из  каталога
 
   пользователя.
 
        Файл регистрации пакетного задания включает весь вывод
 
   для SYS$OUTPUT и SYS$ERROR. Он также включает по  умолчанию
 
   все командные строки, выполненные  в  командной  процедуре.
 
   Для защиты командных строк от вывода на  печать  используют
 
   либо  команду  SET  NOVERIFY,  либо   лексическую   функцию
 
   F$VERIFY. Когда задание завершается, информация о  заверше-
 
   нии записывается (используя длинную форму системного  сооб-
 
   щения о выходе из системы) в файл регистрации.
 
        При сбое в пакетном задании пользователь может  прове-
 
   рить файл регистрации для определения  места  возникновения
 
   ошибки.
 
 
 
        8.3.1. Сохранение файла регистрации             
 
 
        Для сохранения файла регистрации используются квалифи-
 
   каторы /KEEP или  /NOPRINT.  Квалификатор  /KEEP  сохраняет
 
   файл регистрации после его вывода на  печать;  квалификатор
 
   /NOPRINT сохраняет файл регистрации без его распечатки. Оба
 
   квалификатора сохраняют  файл  в  каталоге  регистрации  по
 
   умолчанию; для задания другого файла и/или  имени  каталога
 
   используется квалификатор /LOG_FILE.
 
        Для  переименования  и  сохранения  файла  регистрации
 
   необходимо использовать квалификатор /LOG_FILE и либо  ква-
 
   лификатор /KEEP, либо квалификатор /NOPRINT, как показано в
 
   примере.
 
 
 
 
 
 
 
 
 
                              162 
 
                        000152-01 97 04
 
 
        П р и м е р.
 
 
   $ SUBMIT/LOG_FILE=DISK2:[JONES.RESULTS]/NOPRINT -
     DISK2:[JONES RESULTS]UPDATE
 
 
        8.3.2. Чтение файла регистрации                                
 
 
        Для  чтения  файла  регистрации  используется  команда
 
   TYPE. Однако, если пользователь попытается отобразить  файл
 
   журнала во время записи в него,  то  выдается  сообщение  о
 
   том, что файл заблокирован другим пользователем.
 
        Система выполняет запись в файл регистрации один раз в
 
   минуту. Для задания другого временного интервала в  команд-
 
   ной процедуре используется команда SET OUTPUT_RATE.
 
 
 
        8.3.3. Включение вывода  всех  команд  в  файл   
 
               регистрации пакетного задания           
 
 
        Обычно, пакетное задание, которое транслирует,  компо-
 
   нует и выполняет программу, создает дополнительный печатный
 
   вывод, такой как листинг трансляции и карта компоновки. Для
 
   получения печатных копий этих файлов пакетное задание может
 
   содержать команду (команды) PRINT, необходимую для их выво-
 
   да на печать, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $ FORTRAN BIGCOMP
   $ PRINT BIGCOMP
   $ LINK/MAP/FULL BIGCOMP
   $ PRINT BIGCOMP.MAP
 
        В результате выполнения пакетного задания в примере  1
 
   создаются три отдельных выходных распечатки: файл регистра-
 
   ции пакетного задания, листинг трансляции и карта компонов-
 
   ки.
 
 
                              163 
 
                        000152-01 97 04
 
 
        Если есть необходимость в том, чтобы файл  регистрации
 
   пакетного  задания  содержал  все  выводные  данные,  нужно
 
   выполнить следующие операции:
 
        1) использовать в  командной  процедуре  команду  TYPE
 
   вместо команды PRINT. Команда TYPE выполняет запись в  файл
 
   SYS$OUTPUT. (в  пакетном  задании  SYS$OUTPUT  эквивалентен
 
   файлу регистрации пакетного задания);
 
        2) использовать квалификаторы в соответствующих коман-
 
   дах для направления вывода в SYS$OUTPUT.
 
        Последний метод показан в примере 2.
 
 
        П р и м е р 2.
 
 
   $ FORTRAN/LIST=SYS$OUTPUT BIGCOMP
   $ LINK/MAP=SYS$OUTPUT/FULL BIGCOMP
 
        Когда эти  команды  выполняются  в  пакетном  задании,
 
   выходные файлы трансляции и компоновки записываются  непос-
 
   редственно в  файл  регистрации.  При  использовании  этого
 
   метода выходной файл (файлы) не сохраняются на диске.
 
 
 
        8.4. Контроль за очередью пакетных заданий    
 
 
        После того, как задание  введено  в  очередь  пакетных
 
   заданий, пользователь может контролировать ее  состояние  с
 
   помощью команды SHOW QUEUE, как показано в примере 1.
 
 
        П р и м е р 1.
 
 
   $ SUBMIT/NOPRINT/PARAMETER=STATS.DAT UPDATE
   $ SHOW QUEUE SYS$BATCH
   BATCH QUEUE SYS$BATCH, ON BOSTON::
 
     JOBNAME         USERNAME       ENTRY        STATUS
    ---------       ----------     -------      --------
     UPDATE          ODONNELL       1080        EXECUTING
 
 
 
 
                              164 
 
                        000152-01 97 04
 
 
        Сначала отображаются имена очереди и узла. Затем отоб-
 
   ражаются имя задания, имя пользователя, номер входа и  сос-
 
   тояние.
 
        Если пользователь не имеет заданий в  очереди,  то  по
 
   команде SHOW QUEUE выводится сообщение, указанное в примере
 
   2.
 
 
        П р и м е р 2.
 
 
   $ SHOW QUEUE SYS$BATCH
   BATCH QUEUE SYS$BATCH, ON BOSTON::
 
        Для отображения полной информации задания используется
 
   квалификатор /FULL, как показано в примере 3.
 
 
        П р и м е р 3.
 
 
   $ SHOW QUEUE/FULL SYS$BATCH
   JOB UPDATE (QUEUE SYS$BATCH, ENTRY 1080) STARTED ON
    SYS$BATCH
   BATCH QUEUE SYS$BATCH, ON BOSTON::
     /BASE_PRIORITY=3 /JOB_LIMIT=5 /OWNER=[EXEC]
    /PROTECTION=(S:E.O:D.G:R,W:W)
 
      JOBNAME       USERNAME     ENTRY     STATUS
     ---------     ----------   -------   --------
 
      UPDATE        ODONNELL     1080     EXECUTING
      SUBMITTED 15-FEB-1984 10:46 /KEEP /PARAM=("STATS.DAT")
     /NOPRINT /PRIO=4
     _BOSTON$DQA2:[ODONNELL]TEMP.COM;1 (EXECUTING)
 
        Квалификатор /FULL отображает статистическую  информа-
 
   цию об очереди пакетных заданий SYS$BATCH и характеристики,
 
   связанные с заданием пользователя.
 
        Для  просмотра  состояния  других  заданий  в  очереди
 
   используется команда SHOW QUEUE/ALL, как показано в примере
 
   4.
 
 
 
 
 
 
 
 
                              165 
 
                        000152-01 97 04
 
 
        П р и м е р 4.
 
 
   SHOW QUEUE/ALL SYS$BATCH
   BATCH QUEUE SYS$BATCH, ON BOSTON::
 
     JOBNAME         USERNAME      ENTRY      STATUS
    ---------       ----------    -------    --------
 
    NO PRIVILEGE                    923      EXECUTING
    NO PRIVILEGE                    939      EXECUTING
    UPDATE           ODONNELL      1080      EXECUTING
 
        Непривилегированный   пользователь,   может   получить
 
   информацию только относительно заданий, которые были предс-
 
   тавлены под его учетным номером.
 
 
 
        8.4.1. Изменение характеристик задания             
 
 
        После того, как задание  представлено  в  очереди,  но
 
   перед тем, как  задание  начнет  выполняться,  пользователь
 
   может использовать команду SET QUEUE/ENTRY с  соответствую-
 
   щими квалификаторами для изменения характеристик, связанных
 
   с заданием. Например, для изменения имени пакетного задания
 
   во время ожидания выполнения в  очереди  пакетных  заданий,
 
   пользователь может ввести следующую команду:
 
   $ SET QUEUE/ENTRY=209/NAME=NEW_NAME SYS$BATCH.
 
        Эта команда изменяет имя  задания  с  номером  209  на
 
   NEW_NAME.
 
        Некоторые изменения можно выполнить с помощью  команды
 
   SET QUEUE/ENTRY, как указывалось выше; полный список квали-
 
   фикатов представлен в документе [1].
 
        Большинство  квалификаторов,  разрешенных  с  командой
 
   SUBMIT,   можно   также   использовать   с   командой   SET
 
   QUEUE/ENTRY.
 
        Пользователь может выполнить следующие изменения:
 
 
 
 
                              166 
 
                        000152-01 97 04
 
 
        1) задержать обработку задания. Используется  квалифи-
 
   катор /AFTER для  задания  времени,  после  которого  можно
 
   выполнять задание; используется квалификатор /HOLD для сох-
 
   ранения задания до тех пор, пока оно  не  будет  специально
 
   запущено пользователем;
 
        2)  высвободить  задание.  Используются  квалификаторы
 
   /NOHOLD или /RELEAS для высвобождения задания, которое было
 
   представлено  с  использованием  квалификаторов  /HOLD  или
 
   /AFTER;
 
        3) передать задание  в  другую  очередь.  Используется
 
   квалификатор /REQUEUE  для  изменения  очереди,  в  которой
 
   будет выполняться задание;
 
        4) изменить  характеристики  выполнения.  Пользователь
 
   может изменить характеристики выполнения, такие как рабочий
 
   набор по умолчанию, экстент рабочего набора, размер рабоче-
 
   го набора, планируемый приоритет задания и временной  лимит
 
   центрального процессора;
 
        5) изменить параметры, подлежащие передаче в  задание.
 
   Используется квалификатор /PARAMETERS для  изменения  пара-
 
   метров.
 
 
 
        8.4.2. Удаление и останов пакетных заданий              
 
 
        Пользователь может удалить пакетное задание до или  во
 
   время выполнения. Для удаления задания, которое ожидает или
 
   уже выполняется в очереди пакетных заданий,
 
   используется  команда  DELETE/ENTRY.  Например,   следующая
 
   команда удаляет задание в очереди SYS$BATCH:
 
   $ DELETE/ENTRY=210 SYS$BATCH
 
        Для  удаления  задания,  которое  представлено  другим
 
 
 
                              167 
 
                        000152-01 97 04
 
 
   пользователем, необходимо иметь специальные привилегии.
 
        Завершение задания по команде  DELETE/ENTRY  обрабаты-
 
   вается операционной системой, как аварийное  завершение.  В
 
   результате файл регистрации пакетного задания не  содержит,
 
   например, стандартное сообщение  о  выходе  из  системы,  в
 
   котором содержится учетная и введенная информация.
 
 
 
        8.5. Повторный запуск пакетных заданий                
 
 
        Если происходит аварийный останов системы при выполне-
 
   нии пакетного задания, то оно не завершается, а после восс-
 
   тановления работоспособности системы,  это  задание  завер-
 
   шается аварийно и выполняется следующее задание в очереди.
 
        Однако,  путем  задания  квалификатора  /RESTART   при
 
   представлении задания, пользователь  может  дать  указание,
 
   чтобы система повторно выполнила задание после восстановле-
 
   ния работоспособности системы.
 
        По умолчанию пакетное  задание  запускается  повторно,
 
   начиная с первой строки. Однако, пользователь может  задать
 
   другую точку запуска, чтобы  не  выполнять  повторно  части
 
   задания, которые были успешно завершены. Для этого  необхо-
 
   димо выполнить следующие операции:
 
        1) имеет смысл пометить каждую возможную точку запуска
 
   в   процедуре,   которая    определяется    командой    SET
 
   RESTART_VALUE. Если пакетное задание прерывается из-за ава-
 
   рийного останова и затем запускается повторно, команда  SET
 
   RESTART_VALUE назначает соответствующее имя метки для  гло-
 
   бального символа BATCH$RESTART;
 
        2) в начале командной процедуры следует проверить зна-
 
   чение символа $RESTART. ($RESTART является глобальным  сим-
 
 
 
                              168 
 
                        000152-01 97 04
 
 
   волом, который устанавливается  системой.  Символ  $RESTART
 
   принимает значение "TRUE", если одно  из  пакетных  заданий
 
   пользователя было повторно запущено  после  того,  как  оно
 
   было прервано из-за аварийного останова системы. В  против-
 
   ном случае, символ $RESTART имеет значение  "FALSE").  Если
 
   значение символа - истина  ("TRUE"),  то  следует  передать
 
   управление на метку BATCH$RESTART. В примере показано обес-
 
   печение повторного запуска в пакетном задании.
 
 
        П р и м е р.
 
 
   $ ! установить величины по умолчанию для каталога,
   $ ! содержащего файл, подлежащий корректировке и
   $ ! сортировке
   $ SET DEFAULT DISK1.[ACCOUNTS.DATA84]
   $
   $ ! проверить на повторный запуск
   $ IF $RESTART THEN GOTO 'BATCH$RESTART'
   $
   $ UPDATE_FILE:
   $ SET RESTART_VALUE=UPDATE_FILE
      .
      .
      .
   $ SORT_FILE:
   $ SET RESTART_VALUE=SORT_FILE
      .
      .
      .
   EXIT
 
        Для представления этой командной процедуры в  качестве
 
   пакетного задания, которое может быть запущено повторно, не
 
   нужно использовать квалификатор /RESTART при  представлении
 
   задания.
 
 
 
        8.6. Синхронизация    выполнения    пакетных                   
 
             заданий
 
 
        Чтобы перевести командную процедуру в состояние ожида-
 
   ния, в ней можно использовать команды SYNCHRONIZE  и  WAIT.
 
 
 
                              169 
 
                        000152-01 97 04
 
 
   команда SYNCHRONIZE заставляет процедуру ожидать завершение
 
   определенного задания, в то время как команда WAIT  застав-
 
   ляет процедуру ожидать, пока  не  пройдет  заданный  период
 
   времени. Например,  если  представляются  одновременно  два
 
   задания для выполнения  совместных  функций,  одно  задание
 
   может содержать команду:
 
   $ SYNCHRONIZE BATCH25
 
        После выполнения этой команды командная  процедура  не
 
   может продолжать выполнение до тех пор, пока задание, иден-
 
   тифицированное именем BATCH25, не завершит  выполнение.  На
 
   рис.5 показан пример  командных  процедур,  которые  должны
 
   работать параллельно, но которые  необходимо  синхронизиро-
 
   вать для правильного выполнения. Каждая процедура  трансли-
 
   рует большие исходные программы на  языке  программирования
 
   Фортран.
 
 
 
    .
    .                           DBA1:[HIGGINS]MAINCOMP.COM
    .                           -----------------------------
    $ SUBMIT MAINCOMP           ! $ FORTRAN ALFHA/LIST      !
      JOB 314 ENTERED ON     (2)! $ SYNCHRONIZE MINCOMP     !
      QUEUE SYS$BATCH   (1)     ! $ LINK/MAP/FULL ALPHA.BETA!
    $ SUBMIT MINCOMP            ! $ EXIT                    !
      JOB 315 ENTERED ON        -----------------------------
      QUEUE SYS$BATCH   (1)
    .                           DBA1:[HIGGINS] MINCOMP.COM
    .                           -----------------------------
    .                           ! $ FORTRAN BETA/LIST       !
                                ! $ EXIT                    !
                                -----------------------------
 
 
 
                             Рис. 5
 
 
 
        Пояснения к рис.5:
 
 
        (1) для представления двух отдельных заданий требуются
 
   отдельные команды SUBMIT. Будут создаваться  два  отдельных
 
 
                              170 
 
                        000152-01 97 04
 
 
   процесса;
 
        (2)  после  выполнения  команды  FORTRAN   выполняется
 
   команда SYNCHRONIZE. Если выполнение задания 315 завершено,
 
   то задание 314 продолжается со следующей  команды.  Однако,
 
   задание 314 не  будет  выполнять  следующую  команду,  если
 
   задание либо продолжается, либо ожидает выполнение;
 
        Команда SYNCHRONIZE, может быть выполнена для заданий,
 
   которые имеют одинаковые номера групп в своих кодах иденти-
 
   фикации пользователя (UIC). Для синхронизации  с  заданием,
 
   имеющим другой номер группы (например, с заданием,  которое
 
   было представлено другим пользователем), необходимо исполь-
 
   зовать номер входа задания. Например:
 
   $ SYNCHRONIZE/ENTRY=454
 
        Эта команда  SYNCHRONIZE  помещает  текущую  командную
 
   процедуру в состояние ожидания, пока не завершится  задание
 
   454.
 
        Команда WAIT может оказаться  полезной  для  командных
 
   процедур, которые должны иметь доступ к  совместно  исполь-
 
   зуемым системным ресурсам, таким как накопители на  магнит-
 
   ных дисках или магнитной ленте. В следующем примере показа-
 
   на процедура, которая запрашивает размещение на  накопителе
 
   на магнитной ленте; если команда не завершена  успешно,  то
 
   процедура сама поместит себя в  состояние  ожидания.  После
 
   пятиминутного интервала процедура повторит запрос.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              171 
 
                        000152-01 97 04
 
 
        П р и м е р.
 
 
   $ TRY:
   $         ALLOCATE DM: RK:
   $         IF $STATUS THEN GOTO OKAY
   $         WAIT 00:05
   $         GOTO TRY
   $ OKAY:
   $ REQUEST/REPLY/TO=DISKS-
        "PLEASE MOUNT BACK_UP_CMB ON "F$TRNLNM("RK")'"
           .
           .
           .
 
        В примере команда IF, следующая за командой  ALLOCATE,
 
   запрашивает проверку значения символа $STATUS. Если величи-
 
   на $STATUS указывает на успешное завершение, командная про-
 
   цедура будет продолжена. В противном случае процедура  фор-
 
   мирует команду WAIT, которая задает  пятиминутный  интервал
 
   времени  ожидания.  По  истечении  пятиминутного   ожидания
 
   выполняется следующая команда GOTO  и  запрос  повторяется.
 
   Процедура продолжает выполнение цикла и попытки распределе-
 
   ния устройства до тех пор, пока не будет  достигнута  цель,
 
   либо пакетное задание не будет удалено или остановлено.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              172 
 
                        000152-01 97 04
 
 
                                                  Приложение 1
 
 
 
                
 
 
 
                 1. Примеры командных процедур
 
 
 
        В данном приложении содержатся  завершенные  командные
 
   процедуры, на примере  которых  демонстрируются  понятия  и
                                       
   методы, описанные в данном документе. В каждом разделе дан-
 
   ного приложения описана одна командная процедура  и  содер-
 
   жится следующее:
 
        1) имя процедуры;
 
        2) текст процедуры;
 
        3) примечания, поясняющие понятия и методы, используе-
 
   мые процедурой;
 
        4) результаты выполнения типовой процедуры.
 
 
 
        1.1. Командная процедура CONVERT.COM  

 
        Эта процедура преобразует абсолютное время (для  буду-
 
   щего времени) в относительное время, т.е. вычисляет  интер-
 
   вал времени между текущим  временем  и  временем,  заданным
 
   пользователем. Процедура поясняет использование лексических
 
   функций F$TIME и F$CVTIME и использование операторов  прис-
 
   ваивания для выполнения арифметических вычислений и  работы
 
   со строками символов.
 
 
 
 
 
 
                              173 
 
                        000152-01 97 04
   
 
        1.2. Командная процедура REMINDER.COM 
             
 
        Эта процедура вызывает определенное сообщение на  тер-
 
   минал пользователя в заданное время.  Процедура  использует
 
   командную процедуру CONVERT.COM для преобразования  времени
 
   из абсолютного в интервал. Затем процедура порождает  подп-
 
   роцесс, который обеспечивает ожидание на заданное  время  и
 
   затем выводит сообщение  на  терминал.  Процедура  поясняет
 
   использование лексических функций  F$ENVIRONT,  F$VERIFY  и
 
   F$GETDVI.
 
 
 
         1.3. Командная процедура DIR.COM                         

 
 
        Процедура имитирует  команду  DIRECTORY/SIZE=ALL/DATE,
 
   печатающую размер в блоках и дату создания заданных файлов.
 
   Процедура  поясняет   использование   лексических   функций
 
   F$PARSE, F$SEARCH, F$FILE_ATTRIBUTES и F$FAO.
 
 
 
         1.4. Командная процедура SYS.COM             


 
        Эта  процедура  возвращает  статистическую  информацию
 
   относительно процесса из текущего  списка  процессов.  Если
 
   текущий процесс имеет  привилегию  GROUP,  то  возвращается
 
   статистическая информация для всех процессов в группе. Ста-
 
   тистическая информация обо всех процессах в системе отобра-
 
   жается в том случае, если текущий процесс имеет  привилегию
 
   WORLD. Эта  процедура  поясняет  использование  лексических
 
   функций F$PID, F$EXTRACT и F$GETJPI.
 
 
 
 
 
 
                              174 
 
                        000152-01 97 04
 
 
         1.5. Командная процедура GETPARMS.COM 

 
        Эта процедура возвращает количество параметров,  кото-
 
   рые были переданы в процедуру. Процедура GETPARMS.COM может
 
   вызываться из другой процедуры для  определения  количества
 
   параметров, переданных в вызывающую процедуру.
 
 
 
         1.6. Командная процедура EDITALL.COM 

 
 
        Процедура вызывает повторный запуск редактора  текстов
 
   EDT для редактирования группы файлов одинакового типа. Про-
 
   цедура поясняет использование лексических функций для выде-
 
   ления имен файлов. Она также иллюстрирует способ  переопре-
 
   деления входного потока команд для программы, вызванной  из
 
   командной процедуры.
 
 
 
          1.7. Командная процедура FORTUSER.COM

 
        Этот пример определенного системой  файла  регистрации
 
   обеспечивает управляющую среду для интерактивного пользова-
 
   теля, который создает, транслирует и выполняет программы на
 
   языке программирования фортран.
 
 
 
         1.8. Командная процедура LISTER.COM 
 
 
        Эта процедура выполняет ввод, формирование и  вывод  в
 
   файл определенной информации. Эта процедура,  в  частности,
 
   иллюстрирует использование команд READ и WRITE.
 
 
 
 
 
 
                              175 
 
                        000152-01 97 04
       
 
        1.9. Командная процедура CALC.COM

 
 
 
        Эта процедура выполняет  арифметические  вычисления  и
 
   преобразует результирующие величины в  шестнадцатиричные  и
 
   десятичные.
 
 
 
        1.10.  Командная процедура BATCH.COM
 
 
 
        Эта процедура принимает  командную  строку,  командную
 
   процедуру или список команд и затем выполняет  эти  команды
 
   как пакетное задание.
 
 
 
 
 
 
 
                  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              176 
 
                        000152-01 97 04
 
 
                 Командная процедура CONVERT.COM
 
 
   $ ! процедура преобразует абсолютное время
   $ ! в интервал времени.
   $ ! интервал времени возвращается в качестве
   $ ! значения глобального символа WAIT_TIME.
   $ ! Р1 - преобразуемое время
   $ ! Р2 - вспомогательный параметр (SHOW),
   $ ! который вызывает вывод на терминал значения
   $ ! WAIT_TIME перед завершением процедуры.
 
   $ !
   $ ! проверка запроса
   $ !
   $ IF P1 .EQS. "?" .OR. P1 .EQS. ""THEN GOTO TELL   (1)
 
   $ ! проверьте параметр: часы должны быть меньше 24;
   $ !                     минуты - меньше 60.
   $ ! строка времени может содержать только часы и минуты.
 
   $ !
   $ ON WARNING THEN GOTO BADTIME     (2)
   $ SAVE_MESSAGE = F$ENVIRONMENT("MESSAGE")
   $ SET MESSAGE/NOFACILITY/NOIDENTIFICATION/NOSEVERITY-
     /NOTEXT
   $ TEMP = F$CVTIME(P1)
 
   $ !
   $ ON ERROR THEN EXIT
   $ SET MESSAGE'SAVE_MESSAGE'
 
   $ !
   $ IF F$LENGTH(P1) .NE. 5 .OR -       (3)
            F$LOCATE(":".P1) .NE. 2 -
            THEN GOTO BADTIME
 
   $ !
   $ ! получение текущего времени
   $ !
   $ TIME = F$TIME()                         (4)
   $ !
   $ ! выделение полей часов и минут из значения текущего
   $ ! времени (TIME) и будущего времени (P1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              177 
 
                        000152-01 97 04
 
 
   $ !
   $ MINUTES = F$CVTIME(TIME,"ABSOLUTE","MINUTE")
                   ! CURRENT MINUTES (5)
   $ HOURS = F$CVTIME(TIME,"ABSOLUTE","HOUR")
                   ! CURRENT HOURS
   $ FUTURE_MINUTES = F$CVTIME(P1,"ABSOLUTE","MINUTE")
                   ! MINUTES IN FOTURE TIME
   $ FITURE_HOURS = F$CVTIME(P1,"ABSOLUTE","HOUR")
                   ! HOURS IN FUTURE TIME
 
   $ !
   $ !
   $ ! преобразование обеих значений времени в минуты
 
   $ !
   $ CURRENT_TIME = HOURS*60 + MINUTES      (6)
   $ FUTURE_TIME = FUTURE_HOURS*60 + FUTURE_MINUTES
 
   $ !
   $ ! вычисление разности между будущим и текущим временем
   $ ! (в минутах)
   $ !
   $ !
   $ MINUTES_TO_WAIT = FUTURE_TIME - CURRENT_TIME   (7)
 
   $ ! если результат меньше 0, то предполагается, что
   $ ! время указано для следующего дня. Требуются
   $ ! дополнительные вычисления.
   $ !
   $ IF MINUTES_TO_WAIT .LT. 0 THEN -       (8)
      MINUTES_TO_WAIT = 24*60 + FUTURE_TIME - CURRENT_TIME
 
   $ !
   $ ! начало цикла для определения значения в часах и
   $ ! минутах (из значения, представленного в минутах)
 
   $ !
   $           HOURS_TO_WAIT = 0
   $ HOURS_TO_WAIT_LOOP:             (9)
   $           IF MINUTES_TO_WAIT .LT. 60 THEN FINISH_COMPUTE
   $           MINUTES_TO_WAIT = MINUTES_TO_WAIT - 60
   $           HOURS_TO_WAIT = HOURS_TO_WAIT + 1
   $           GOTO HOURS_TO_WAIT_LOOP
   $ FINISH_COMPUTE:
 
   $ !
   $ ! построение строки интервала времени в требуемом
   $ ! формате
   $ !
   $ WAIT_TIME == F$STRING(HOURS_TO_WAIT)+":" + F$STRING-
     (MINUTS_TO_WAIT) + ":00.00"           (10)
 
   $ !
   $ ! проверка второго параметра
   $ !
   $ IF P2 .EQS. "SHOW" THEN SYMBOL WAIT_TIME     (11)
 
   $ !
   $ ! нормальное завершение
 
 
                              178 
 
                        000152-01 97 04
 
 
 
   $ !
   $ EXIT
   $ !
   $ BADTIME:                        (12)
   $ ! выход, если первый параметр задан неверно
 
   $ !
   $ SET MESSAGE'SAVE_MESSAGE
   $ WRITE SYS$OUTPUT "неверное задание времени: ",р1,",
   $ WRITE SYS$OUTPUT "часы должны быть меньше 24;
                       минуты - меньше 60"
   $ EXIT %X10000000
 
   $ !
   $ !
   $ TELL:              (13)
   $ ! выход при задании неверного параметра
 
   $ !
   $ EXIT
 
        Пояснения:
 
        (1) проверяется, был ли опущен параметр и содержит  ли
 
   введенная для параметра величина символ знака вопроса  (?).
 
   В любом случае будет выполняться переход на метку TELL;
 
        (2) используется функция F$CVTIME для  проверки  того,
 
   что величина  времени  соответствует  24-часовому  времени;
 
   функция F$CVTIME возвращает предупреждающее сообщение, если
 
   входное время окажется некорректным.  Следовательно,  изме-
 
   няется действие по умолчанию команды  ON,  чтобы  направить
 
   управление на метку BADTIME, если функция F$CVTIME  возвра-
 
   щает ошибку;
 
        Используется функция F$ENVIROMENT для сохранения теку-
 
   щих установок о сообщениях и затем  устанавливается  формат
 
   сообщения так, чтобы не отображались предупреждающие  сооб-
 
   щения и сообщения об ошибке. После проверки величин времени
 
   восстанавливается условие по умолчанию команды ON и  формат
 
   сообщения;
 
        (3) проверяется формат параметра. Он должен соответст-
 
   вовать величине времени в формате: чч:мм;
 
 
                              179 
 
                        000152-01 97 04
 
 
        Команда IF проверяет,  что  длина  введенной  величины
 
   равна 5 символам и что третий символ (смещение 2)  является
 
   двоеточием. Команда  IF  содержит  логический  оператор  OR
 
   (или), если любое выражение  является  истинным  (то  есть,
 
   если длина не равна 5 символам или если отсутствует двоето-
 
   чие в третьем символе), то  будет  выполняться  переход  на
 
   метку BADTIME;
 
        (4) лексическая функция F$TIME помещает величину теку-
 
   щего времени в символ TIME;
 
        (5) функция F$CVTIME выделяет поля "минуты"  и  "часы"
 
   из текущего времени (сохраняемого в  символе  TIME).  Затем
 
   функция F$CVTIME выделяет поля "минуты" и "часы" из  време-
 
   ни, которое нуждается в преобразовании;
 
        (6) эти операторы  присваивания  преобразуют  величины
 
   текущего и будущего времен  в  минуты.  Когда  используется
 
   символ HOURS, MINUTES, FUTURE_HOURS и FUTURE_MINUTES в опе-
 
   раторах присваивания, система автоматически преобразует эти
 
   величины в целые;
 
        (7) вычитается текущее время (в минутах)  из  будущего
 
   времени (в минутах);
 
        (8) если результат меньше 0, то будущее время  интерп-
 
   ретируется как относящееся к следующим суткам. В этом  слу-
 
   чае добавляются 24 часа к будущему времени  и  затем  вычи-
 
   тается текущее время;
 
        (9) вводится цикл, в котором вычисляется  из  величины
 
   MINUTES_TO_WAIT количество часов. Каждый проход цикла  про-
 
   веряется, не больше ли величина  MINUTES_TO_WAIT  60.  Если
 
   это так, то вычитается 60  из  величины  MINUTES_TO_WAIT  и
 
   прибавляется 1 к накапливающему регистру  для  числа  часов
 
   (HOURS_TO_WAIT);
 
 
                              180 
 
                        000152-01 97 04
 
 
        (10) при выходе из цикла соединяются величины часов  и
 
   минут   в   строку   времени.   Символы   HOURS_TO_WAIT   и
 
   MINUTES_TO_WAIT  замещаются  их  эквивалентами   символьных
 
   строк с внутренним двоеточием. Результирующая строка  прис-
 
   ваивается  символу  WAIT_TIME,  который  содержит  величину
 
   дельта-времени для будущего времени.
 
        Символ WAIT_TIME определяется как  глобальный  символ,
 
   так  что  он  не  будет  удаляться  при  выходе   процедуры
 
   WAIT_TIME;
 
        (11) если был введен второй параметр  SHOW,  то  будет
 
   отображаться результирующая величина времени.  В  противном
 
   случае будет выполняться выход;
 
        (12) с метки BADTIME отображается сообщение об ошибке,
 
   которое указывает на  некорректную  введенную  величину,  а
 
   также требуемый формат.  После  формирования  сообщения  об
 
   ошибке командная  процедура  CONVERT.COM  выполняет  выход.
 
   Команда EXIT возвращает состояние ошибки, в которой старшая
 
   цифра устанавливается в 1. Это подавляет отображение  сооб-
 
   щения об ошибке. Процедура точно определяет состояние ошиб-
 
   ки с помощью  команды  EXIT,  так  что  пользователь  может
 
   выполнять процедуру CONVERT.COM из другой процедуры.  Когда
 
   командная  процедура  CONVERT.COM  завершается,  вызывающая
 
   процедура может определить, было ли  успешно  преобразовано
 
   время;
 
        (13) с метки TELL отображается  информация  о  текущем
 
   действии процедуры. Команда TYPE отображает  строки,  пере-
 
   численные во входном потоке данных SYS$INPUT.
 
 
 
 
 
 
 
 
                              181 
 
                        000152-01 97 04
 
 
        П р и м е р 1.
 
 
   $ SHOW TIME
   10-JUN-1984 10:38:26
   $ CONVERT 12:00 SHOW
      WAIT_TIME = "1:22:00.00"
 
        В примере 1 команда SHOW TIME отображает текущие  дату
 
   и время. Процедура CONVERT.COM  выполняется  с  параметрами
 
   12:00 и SHOW. Процедура преобразует абсолютное время  12:00
 
   в дельта-время и отображает его на терминале.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              182 
 
                        000152-01 97 04
 
 
                Командная процедура REMINDER.COM
 
 
   $ ! процедура получения напоминающего сообщения и
   $ ! отображения этого сообщения на терминале пользователя
   $ ! в заданное время
 
   $ !
   $ ! сохранить текущее состояние для проверки процедуры и
   $ ! образа
   $ ! отключить проверку на время выполнения процедуры
   $ !
 
   $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")   (1)
   $ SAVE_VERIFY_PROG = F$VERIFY(0)
 
   $ !
   $ ! поместить текущий процесс в состояние ожидания до тех
   $ ! пор, пока не наступит заданное абсолютное время.
   $ ! затем вызывается звонок на терминале и отображается
   $ ! сообщение
 
   $ !
   $ ! подсказка для абсолютного времени
   $ !
   $
 
   $ GET_TIME:
   $ INQUIRE REMINDER_TIME "введите время для передачи
     напоминания  (HH:MM)"  (2)
   $ INQUIRE MESSAGE_TEXT "введите сообщение"
 
   $ !
   $ ! вызов процедуры CONVERT. COM для преобразования
   $ ! абсолютного времени в дельта-время
 
   $ !
   $ @DISK2:[JONES.TOOLS]CONVERT 'REMINDER_TIME'      (3)
   $ IF .NOT. $STATUS THEN GOTO BADTIME
   $ !
 
   $ !
   $ ! создается командный файл, который будет выполняться в
   $ ! подпроцессе. Подпроцесс будет ожидать до тех пор,
   $ ! пока не настанет заданное время, и затем отобразит
   $ ! сообщение пользователя на терминале. Если
   $ ! пользователь работает на терминале SYS_CRT, то
   $ ! сообщение будет иметь мигающие символы двойного
   $ ! размера. В любом случае, будет звонить звонок
   $ ! терминала, когда отображается сообщение
 
   $ CREATE WAKEUP.COM    (4)
   $ DECK           ! строки, начинающиеся со знака $-данные
   $ WAIT 'WAIT_TIME'     (5)
   $ IF F$CETDVI("SYS$OUTPUT","TT_SYSCRT").NES."TRUE"THEN -
     GOTO OTHER_TERM
   $ BELL[0,7] = %X07 ! создается символ для звучания звонка
 
   $ !
 
 
                              183 
 
                        000152-01 97 04
 
 
   $ SYS_CRT_ONLY:
   $ ! создаются символы для установки специальной графики
   $ ! только для терминала SYS_CRT
 
   $ !
   $  SET_FLASH = "<ESC>[1:5M" ! включить мигание символов
   $  SET_NOFLASH = "<ESC>[OM" ! отключить мигание символов
   $  тор = "<ESC>#3"          ! удвоить размер символов
                               ! (верхняя часть)
   $  BOT = "<ESC>#4"          ! удвоить размер символов
                               ! (нижняя часть)
 
   $ !
   $ ! запись мигающего сообщения двойного размера на
   $ ! терминал и включение звонка
   $ !
   $  WRITE SYS$OUTPUT BELL, SET_FLASH, TOP, MESSAGE_TEXT
   $  WRITE SYS$OUTPUT BELL, BOT, MESSAGE_TEXT
   $  WRITE SYS$OUTPUT F$TIME(), SET_NOFLASH
   $  GOTO CLEAN_UP
 
   $ !
   $ OTHER_TERM:
   $      WRITE SYS$OUTPUT BELL,MESSAGE_TEXT
   $      WRITE SYS$OUTPUT F$TIME()
 
   $ !
   $ CLEAN_UP:
   $      DELETE WAKEUP.COM;*
   $ EоD
 
   $ !
   $ ! WAKEUP.COM создана. Теперь продолжается выполнение
   $ ! команд
   $ !
   $ SPAWN/NOWAIT/INPUT=WAKEUP.COM         (6)
   $ END:                                   (7)
   $ !  восстановить проверку
   $    SAVE_VERIFY_PROG = F$VERIFY(SAVE_VERIFY_PROC, -
        SAVE_VERIFY_IMAGE)
   $    EXIT
   $ !
   $ BADTIME:
   $ WRITE SYS$OUTPUT"время необходимо вводить -
     в формате HH:мм"
   $    GOTO GET_TIME
 
        Пояснения:
 
        (1) используется функция F$ENVIRONMENT для  сохранения
 
   установок  проверки  образа  в  символе  SAVE_VERIFY_IMAGE.
 
   Затем используется функция F$VERIFY для сохранения  устано-
 
   вок проверки процедуры в символе SAVE_VERIFY_IMAGE. Функция
 
   F$VERIFY также выключает оба типа проверки;
 
 
 
                              184 
 
                        000152-01 97 04
 
 
        (2) используется команда INQUIRE для подсказки  време-
 
   ни, когда должно быть передано напоминающее сообщение.  Эта
 
   величина будет использоваться в качестве ввода для процеду-
 
   ры CONVERT.COM.
 
        Выводится также подсказка для текста сообщения;
 
        (3) выполняется вложенная процедура CONVERT.COM. Необ-
 
   ходимо указать диск и каталог в качестве части спецификации
 
   файла; это гарантирует то, что система сможет отыскать про-
 
   цедуры CONVERT.COM  независимо  от  каталога,  из  которого
 
   пользователь выполняет процедуру REMINDER.COM.
 
        Процедура  CONVERT.COM   преобразует   напоминание   в
 
   дельта-время  и  возвращает   его   в   глобальный   символ
 
   WAIT_TIME. Это дельта-время указывает интервал  времени  от
 
   текущего времени до того момента, пока  не  настанет  время
 
   передачи сообщения. Если процедура  CONVERT.COM  возвращает
 
   ошибку,  то  процедура  REMINDER.COм  переходит  на   метку
 
   BADTIME;
 
        (4) используется команда  CREATE  для  создания  новой
 
   процедуры WAKEUP.COM. Эта  процедура  будет  выполняться  в
 
   подпроцессе. Чтобы предоставить возможность команде  CREATE
 
   читать строки, начинающиеся  со  знаков  денежной  единицы,
 
   используются команды DECK и EOD  для  окружения  ввода  для
 
   команды CREATE. Следовательно, все строки  между  командами
 
   DECK и EOD будут записываться в процедуру WAKEUP.COM;
 
        (5) процедура WAKEUP.COM выполняет следующие задачи:
 
          - ожидает,  пока  не  настанет  время,  заданное   с
 
            помощью символа WAIT_TIME;
 
          - создает символ BELL для звучания звонка терминала;
 
          - определяет, соответствует ли терминал типу SYS_CRT
 
            и можно ли принимать  последовательность  АР2  для
 
 
                              185 
 
                        000152-01 97 04
 
 
            отображения мигающих символов удвоенного  размера.
 
            (чтобы удовлетвориться в том, относится ли  терми-
 
            нал к типу  SYS_CRT,  пользователь  должен  ввести
 
            команду SHOW TERMINAL, и убедиться в наличии  ука-
 
            занной характеристики);
 
          - если терминал является терминалом SYS_CRT, то про-
 
            цедура определяет символы SET_FLASH,  тор  и  вот.
 
            Эти  символы  заставляют   терминал   использовать
 
            мигающие  символы  удвоенного  размера.  Процедура
 
            также определяет символ SET_NOFLASH  для  возврата
 
            терминала в его нормальное  состояние.  Для  ввода
 
            символа АР2 (<ESC>), когда создаются эти определе-
 
            ния с использованием редактора  EDT,  надо  дважды
 
            нажать на клавишу ESC;
 
        После определения этих символов,  процедура  выполняет
 
   запись трех строк на терминал. Первая строка включает  зву-
 
   чание  звонка,  включает  мигание  символов  и   отображает
 
   (используя символы  удвоенного  размера)  верхнюю  половину
 
   сообщения пользователя. Вторая строка вновь включает звуча-
 
   ние звонка и отображает нижнюю половину сообщения пользова-
 
   теля. Третья строка записывает текущее время и затем выклю-
 
   чает характеристику мигания для возврата терминала  пользо-
 
   вателя в нормальное состояние.
 
        Если терминал не относится к типу SYS_CRT, то процеду-
 
   ра включает звонок на терминале пользователя  и  отображает
 
   сообщение и время;
 
          - команда  DELETE  заставляет  процедуру  WAKEUP.COM
 
            удалить саму себя после ее выполнения;
 
        (6) после создания процедуры WAKEUP.COM порождается  и
 
   запускается  подпроцесс  для  использования  WAKEUP.COM   в
 
 
                              186 
 
                        000152-01 97 04
 
 
   качестве входного командного  файла.  Квалификатор  /NOWAIT
 
   разрешает пользователю продолжить работу со своего термина-
 
   ла,  пока  подпроцесс  выполняет   команды   из   процедуры
 
   WAKEUP.COM. В заданное время процедура  WAKEUP.COM  отобра-
 
   жает сообщение пользователя на его терминале.
 
        По  умолчанию  команда  SPAWN  передает  глобальные  и
 
   локальные символы в подпроцесс. Следовательно, хотя пользо-
 
   ватель и определил символы WAIT_TIME и MESSAGE_TEXT в  про-
 
   цедуре REMINDER.COM, процедура WAKEUP.COM также может иметь
 
   доступ к этим символам;
 
        (7)  восстанавливаются  исходные  установки   проверки
 
   перед выходом.
 
 
        П р и м е р 2.
 
 
   $ @REMINDER
   введите время для передачи напоминания (ЧЧ:MM): 12:00
   введите сообщение: время обеда
   %DCL-S-SPAWNED, PROCESS BLUTO_1 SPAWNED
   $
      .
      .
      .
   время обеда
   15-APR-1984 12:00:56.99
 
        В примере 2 процедура выводит подсказку  для  величины
 
   времени и сообщения пользователя. Затем процедура порождает
 
   подпроцесс, который будет отображать сообщение  пользовате-
 
   ля. Пользователь может продолжить работу на своем  термина-
 
   ле; в заданное время подпроцесс включит звучание звонка  на
 
   терминале, отобразит сообщение пользователя и время.
 
 
 
 
 
 
 
 
 
 
 
                              187 
 
                        000152-01 97 04
 
 
                   Командная процедура DIR.COM
 
 
   $ !
   $ ! Реализации команды DIRECTORY/SIZE = ALL/DATE
 
   $ !
   $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
   $ P1 = F$PARSE(P1."*.*;*")      ! создать каталог с
   $ !                             ! символами "*"        (1)
   $ FIRST_TIME = "TRUE"           ! заголовок еще не
   $ !                             ! печатается
   $ FILE_COUNT = 0                ! файлы еще не найдены
   $ TOTAL_ALLOC = 0               ! блоки еще не размещены
   $ TOTAL_USED = 0                ! блоки еще не
                                   ! используются
 
   $ LOOP:              (2)
   $       FILESPEC = F$SEARCH(P1)
   $ ! поиск следующего файла в каталоге
   $       IF FILESPEC .EQS. "" THEN GOTO DONE
   $ ! Eсли больше нет файлов, выполнить
   $       IF .NOT. FIRST_TIME THEN GOTO SHOW_FILE
   $ ! PRINT HEADER ONLY ONCE
   $ !
   $ ! создать и вывести строку заголовка
   $ !
   $       FIRST_TIME = "FALSE"           (3)
   $       DIRSPEC = F$PARSE(FILESPEC,,, "DEVICE") -
                   +F$PARSE(FILESPEC,,, "DIRECTORY")
   $       WRITE SYS$OUTPUT ""
   $       WRITE SYS$OUTPUT "DIRECTORY ",DIRSPEC
   $       WRITE SYS$OUTPUT ""
   $       LASTDIR = DIRSPEC
   $
 
   $ !
   $ ! указать имя файла, получить некоторые
   $ ! атрибуты файла и вывести информацию
 
   $ !
   $SHOW_FILE:
   $       FILE_COUNT = FILE_COUNT + 1
   $       FILENAME = F$PARSE(FILESPEC... "NAME") -      (4)
                    + F$PARSE(FILESPEC... "TYPE") -
                    + F$PARSE(FILESPEC... "VERSION")
   $       ALLOC = F$FILE_ATTRIBUTES(FILESPEC, "ALQ")
   $       USED = F$FILE_ATTRIBUTES(FILESPEC, "EOF")
   $       TOTAL_ALLOC = TOTAL_ALLOC + ALLOC
   $       TOTAL_USED = TOTAL_USED + USED
   $       REVISED = F$FILE_ATTRIBUTES(FILESPEC,"RDT")
   $       LINE = F$FAD("!19AS !5UL/!5<!UL!> -
                 !17AS".FILENAME, USED, ALLOC, REVISED)
   $       WRITE SYS$OUTPUT LINE
   $       GOTO LOOP
 
   $ !
   $ ! ввести сводную информацию, восстановить проверку и
 
 
                              188 
 
                        000152-01 97 04
 
 
   $ ! выполнить выход
   $ !
   $ DONE:              (5)
   $       WRITE SYS$OUTPUT ""
   $       WRITE SYS$OUTPUT "TOTAL OF ''FILE_COUNT' FILES. "-
                + "''TOTAL_USED'/''TOTAL_ALLOC' BLOCKS."
   $       SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PRO -
                 CEDURE,SAVE_VERIFY_IMAGE)
   $       EXIT
 
        Пояснения:
 
        (1) эта процедура использует функцию F$PARSE для поме-
 
   щения звездочек в полях пробелов в спецификации  поставляе-
 
   мого пользователем файла Р1. Если  пользователь  не  задает
 
   параметр  при  выполнении  процедуры  DIR.COM,  то  функция
 
   F$PARSE присваивает P1 величину "*.*;*".
 
        Это заставляет процедуру DIR.COM отображать все  файлы
 
   в текущем каталоге по умолчанию;
 
        (2) лексическая функция F$SEARCH выполняет поиск ката-
 
   лога для файла (файлов), заданного с помощью  P1.  Если  P1
 
   содержит символы звездочки "*", то функция F$SEARCH возвра-
 
   щает все согласованные спецификации файлов. После  возврата
 
   спецификации последнего файла процедура переходит на  метку
 
   DONE;
 
        (3) сначала, через цикл,  записывается  заголовок  для
 
   отображения каталога. Этот заголовок  включает  имена  уст-
 
   ройства и каталога. Для получения  этих  имен  используется
 
   функция F$PARSE;
 
        (4) процедура использует лексическую  функцию  F$PARSE
 
   для выделения имени файла из спецификации каждого  файла  в
 
   каталоге. Лексическая функция F$FILE_ATTRIBUTES затем опре-
 
   деляет использованные блоки, размещенные блоки и информацию
 
   о дате создания для каждого файла. Наконец,  функция  F$FAO
 
   форматирует одну строку отображения  для  каждого  файла  в
 
   каталоге. Функция F$FAO использует имя файла  и  информацию
 
 
                              189 
 
                        000152-01 97 04
 
 
   об атрибутах файла в качестве аргументов1
 
        (5) когда функция F$SEARCH возвращает  пустую  строку,
 
   процедура выполняет переход на метку  DONE  и  отображается
 
   сводная  информация,  где  указывается   общее   количество
 
   использованных файлов/блоков  и  общее  количество  блоков,
 
   размещенных в каталоге.
 
 
        П р и м е р 3.
 
 
   $ @DIR [VERN]*.COM
     DIRECTORY DISK4:[VERN]
     BATCH.COM;1            1/3    16-JUN-1984 11:43
     CALC.COM;3             1/3    16-JUN-1984 11:30
     CONVERT.COM;1          5/6    19-JUN-1984 15:23
      .
      .
      .
     LOGIN.COM;34           2/3    16-JUN-1984 13:17
     PID.COM;7              1/3    16-JUN-1984 09:49
     SCRATCH.COM;6          1/3    16-JUN-1984 11:29
 
     TOTAL OF 15 FILES, 22/48 BLOCKS.
 
        Процедура возвращает информацию о всех файлах типа COM
 
   в каталоге [VERN].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              190 
 
                        000152-01 97 04
 
 
                   Командная процедура SYS.COM
 
 
   $ !
   $ ! отображается информация относительно
   $ ! процессов-владельцев, групповых процессов и системных
   $ ! процессов
   $ !
   $ ! включить проверку и сохранить текущие установки
   $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
   $ CONTEXT = ""        ! инициализация PID для поиска
                         ! процесса       (1)
 
   $ !
   $ ! вывод строки заголовка
   $ !
   $ WRITE SYS$OUTPUT " PID USERNAME TERM PROCESS " + -  (2)
         "NAME STATE PRI IMAGE"
 
   $ !
   $ ! вывод информации о процессе
   $ !
   $LOOP:
   $ !
   $ ! получить следующий PID. Если он равен нулю, то
   $ ! выполнить
   $ !
   $      PID = F$PID(CONTEXT)           (3)
   $      IF PID .EQS. "" THEN GOTO DONE
 
   $ !
   $ ! получить спецификацию файла образа и выделить имя
   $ ! файла
   $ !
   $    IMAGNAME = F$GETJPI(PID,"IMAGNAME")    (4)
   $    IMAGNAME = F$PARSE(IMAGNAME,,,"NAME","SYNATAX_ONLY")
 
   $ !
   $ ! получить имя терминала. Если отсутствует, то описать
   $ ! тип процесса.
   $ !
   $   TERMINAL = F$GETJPI(PID,"TERMINAL")   (5)
   $   IF TERMINAL .EQS. "" THEN -
       TERMINAL = "-"+F$EXTRACT(0,3,F$GETJPI(PID,"MODE"))+"-"
   $   IF TERMINAL .EQS. "-INT-" THEN TERMINAL = "-DET-"
   $   IF F$GETJPI(PID,"OWNER") .NE. 0 THEN TERMINAL = "-SUB-"
 
   $ !
   $ ! получить некоторую дополнительную информацию,
   $ ! поместить ее вместе со строкой процесса и вывести ее
   $ !
   $   LINE = F$FAO("!AS !12AS !7AS !15AS !5AS !2UL-     (6)
         /!UL !1OAS", -
         PID,F$GETJPI(PID,"USERNAME"),TERMINAL,-
         F$GETJPI(PID,"PRCNAM"),-
         F$GETJPI(PID,"STATE"),F$GETJPI(PID,"PRI"),-
         F$GETJPI(PID,"PRIB"),IMAGNAME)
   $   WRITE SYS$OUTPUT LINE
 
 
                              191 
 
                        000152-01 97 04
 
 
   $   GOTO LOOP
 
   $ !
   $ ! восстановить проверку и выполнить выход
   $ !
   $DONE:
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,-
            SAVE_VERIFY_IMAGE)
   $ EXIT
 
        Пояснения:
 
        (1) символ CONTEXT инициализируется с нулевой  величи-
 
   ной. Этот символ будет использоваться  функцией  F$PID  для
 
   определения списка номеров идентификации процесса (PID);
 
        (2) выполняется запись заголовка для отображения;
 
        (3) получение первого  номера  идентификации  процесса
 
   (PID). Если в текущем процессе отсутствуют привилегии GROUP
 
   или WORLD, то  возвращается  PID  текущего  процесса.  Если
 
   текущий процесс имеет  привилегию  GROUP,  то  возвращается
 
   первый PID в списке группы. Первый PID в  системном  списке
 
   возвращается в том случае, если текущий процесс имеет  при-
 
   вилегию WORLD. Функция продолжает возвращать следующие  PID
 
   в последовательности до тех пор, пока  не  будет  возвращен
 
   последний PID. В этой точке возвращается нулевая  строка  и
 
   процедура переходит на окончание;
 
        (4)  используется  лексическая  функция  F$GETJPI  для
 
   получения спецификации  файла  образа  для  каждого  номера
 
   идентификации процесса (PID). Функция F$PARSE выделяет  имя
 
   файла из спецификации, возвращенной функцией F$GETJPI;
 
        (5) используется функция F$GETJPI для получения  имени
 
   терминала для каждого PID. Функция F$EXTRACT выделяет  пер-
 
   вые три символа из спецификации MODE, возвращенной функцией
 
   F$GETJPI (PID, "MODE") для определения типа процесса. Функ-
 
   ция  F$GETJPI  используется  вновь  для  определения  того,
 
   является ли процесс подпроцессом;
 
 
                              192 
 
                        000152-01 97 04
 
 
        (6)  используется  лексическая  функция  F$GETJPI  для
 
   получения имени  пользователя,  имени  процесса,  состояния
 
   процесса и базового приоритета процесса для каждого возвра-
 
   щенного PID.  Лексическая  функция  F$FAO  форматирует  эту
 
   информацию для отображения на экране.
 
 
        П р и м е р 4.
 
 
   $ SYS
      PID    USERNAME   TERM   PROCESS NAME STATE PRI IMAGE
   00050011 NETNONPRIV  -NET-  MALL_14411    LEF  9/4 MAIL
   00040013 STOVE       RTAG:  STOVE         LEF  9/4
   00140015 MAROT       -DET-  DMFBOACP      HIB  9/8 F11BACP
   00080016 THOMPSON    -DET-  MTAOACP       HIB 12/8 MTAAACP
   00070017 JUNLES      TTF1:  JUHLES        LEF  9/4
      .
      .
      .
   00040018 MACRO       TTA2:  MACRO         HIB  9/4 RTPAD
 
   0018001A VERN        RTA3:  VERN          LEF  9/4
   0033001B YISHA       RTA7:  YISHA         CUR  4/4
   0002004A SYSTEM      -DET-  ERRFMT        HIB 12/7 LRRFMT
 
        В примере 4 процедура  возвращает  информацию  о  всех
 
   процессах  в  системе.  Текущий  процесс  имеет  привилегию
 
   WORLD.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              193 
 
                        000152-01 97 04
 
 
                Командная процедура GETPARMS.COM
 
 
   $ ! Процедура для счета числа параметров, переданных в
   $ ! командную процедуру. Это число возвращается как
   $ ! глобальный символ PARMCOUNT
 
   $ !
   $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE") (1)
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
 
   $ !
   $ IF P1 .EQS. "?" THEN GOTO TELL     (2)
   $ !
   $ ! цикл для счета числа переданных параметров. Пустые
   $ ! параметры считаются до тех пор, пока не будет передан
   $ ! последний непустой параметр
   $ !
 
   $       COUNT = 0          (3)
   $       LASTNONNULL = 0
   $ LOOP:
   $       IF COUNT .EQ. 8 THEN GOTO END_COUNT
   $       COUNT = COUNT + 1
   $       IF P'COUNT' .NES. "" THEN LASTNONNULL = COUNT
   $ GOTO LOOP
   $ !
   $ END_COUNT:               (4)
 
   $ !
   $ ! поместить число непустых параметров, переданных в
   $ ! символ PARMCOUNT.
   $ !
   $ PARMCOUNT == LASTNONNULL
   $ !
   $ ! восстановить установку проверки, если она была
   $ ! включена, перед выходом
   $ !
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,-
         SAVE_VERIFY_IMAGE)     (5)
   $ EXIT
 
   $ !
   $ TELL:           (6)
   $ TYPE SYS$INPUT
         эта процедура считает число параметров, переданных в
         другую процедуру. Эту процедуру можно вызвать путем
         ввода строки
 
           @GETPARMS 'P1 'P2 'P3 'P4 'P5 'P6 'P7 'P8
 
         в любой процедуре. При возврате, глобальный символ
         PARMCOUNT содержит число параметров, переданных в
         процедуру.
 
   $ !
   $ EXIT
 
 
 
 
                              194 
 
                        000152-01 97 04
 
 
        Пояснения:
 
        (1) сохраняется текущий  образ  и  установка  проверки
 
   перед ее выключением;
 
        (2) если в процедуру был передан в качестве  параметра
 
   знак вопроса, то процедура переходит на метку TELL;
 
        (3) устанавливается цикл для счета  числа  параметров,
 
   переданных в процедуру. Счетчики COUNT и  LASTNNONULL  ини-
 
   циализируются в 0 перед  вводом  цикла.  В  пределах  цикла
 
   счетчик COUNT получает приращение и проверяется на величину
 
   8. Если содержимое COUNT равно 8, то будет передано  макси-
 
   мальное число параметров. Всякий раз при передаче непустого
 
   параметра, величина LASTNNONULL равна числу таких  парамет-
 
   ров.
 
        Каждый раз при выполнении команды IF, она  имеет  раз-
 
   личные величины. В первый раз величина символа COUNT  равна
 
   1 и команда IF проверяет PI. Во второй  раз  она  проверяет
 
   Р2, и так далее;
 
        (4) когда счет параметров достигает 8, процедура пере-
 
   ходит на метку END_COUNT. Символ LASTNNONULL содержит  счет
 
   последнего непустого переданного  параметра.  Эта  величина
 
   помещается в глобальный символ PARMCOUNT. Символ  PARMCOUNT
 
   должен быть определен как глобальный символ так, чтобы  его
 
   величина могла проверяться на уровне вызывающей команды;
 
        (5)  восстанавливаются  исходные  установки  проверки.
 
   Хотя пользователь сохраняет свои текущие установки проверки
 
   процедуры в  символе  SAVE_VERIFY_PROCEDURE,  в  дальнейшем
 
   необходимость в этом символе отсутствует;
 
        (6) команда TYPE отображает данные,  которые  включены
 
   во входной поток.  (в  командной  процедуре  входной  поток
 
   является файлом командной процедуры). Команда TYPE  отобра-
 
 
                              195 
 
                        000152-01 97 04
 
 
   жает инструкции по использованию процедуры GETPARMS.COM.
 
        Пример использования данной процедуры.
 
        Пусть процедура SORTFILES.COM запрашивает у  пользова-
 
   теля три непустых параметра.
 
        Процедура  SORTFILES.COM  может  содержать   следующие
 
   строки:
 
 
   $ @GETPARMS 'P1' 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8'
   $ IF PARMCOUNT .NE. 3 THEN GOTO NOT_ENOUGH
      .
      .
      .
   $NOT_ENOUGH:
   $ WRITE SYS$OUTPUT -
   "THREE NON-NULL PARAMETERS REQUIRED. TYPE SORTFILES HELP
   FOR INFO."
   $ EXIT
 
        Процедура SORTFILES.COM может вызываться, как показано
 
   в примере 5.
 
 
        П р и м е р 5.
 
 
   $ @SORTFILES DEF 4
   THREE NON-NULL PARAMETERS REQUIRED. TYPE SORTFILE HELP FOR
   INFO.
 
        В примере 5  в  процедуре  SORTFILES.COM  определяется
 
   символ GETPARMS как синоним для @GETPARMS и ее  параметров.
 
   Для надлежащего вызова этой процедуры, то есть чтобы  пара-
 
   метры, переданные в SORTFILES, были переданы в GETPARMS без
 
   искажения для  обработки,  синониму  должен  предшествовать
 
   знак апострофа.
 
        Если возвращенная из GETPARMS величина не равна  3,  в
 
   SORTFILES формируется сообщение  об  ошибке  и  выполняется
 
   выход.
 
 
 
 
 
 
 
 
                              196 
 
                        000152-01 97 04
 
 
                 Командная процедура EDITALL.COM
 
 
   $ ! Процедура для редактирования файлов с заданным типом
   $ ! файла
   $ ! используется P1 для указания типа файла
   $ !
   $ ON CONTROL_Y THEN GOTO DONE    ! действие по YC/Y (1)
   $ ON ERROR THEN GOTO DONE
   $ !
   $ ! проверить параметр типа файла. Если он введен,
   $ ! продолжить; в противном случае, выполнить подсказку
   $ ! параметра
   $ !
   $ IF P1 .NES. "" THEN GOTO OKAY       (2)
   $ INQUIRE P1 "ENTER FILE TYPE OF FILES TO EDIT"
 
   $ !
   $ ! перечислить все файлы с заданным типом файла и
   $ ! записать вывод команды DIRECTORY в файл
   $ ! с именем DIRECT.OUT
   $ !
 
   $ OKAY:
   $ DIRECTORY/VERSIONS=1/COLUMNS=1 -       (3)
         /NODATE/NOSIZE -
         /NOHEADING/NOTRAILING -
         /OUTPUT=DIRECT.OUT *.'P1'
   $ IF .NOT. $STATUS THEN GOTO ERROR_SEC    (4)
 
   $ !
   $ OPEN/READ/ERROR=ERROR_SEC DIRFILE DIRECT.OUT (5)
   $ !
   $ ! цикл для чтения файла каталога
   $ !
 
   $ NEWLINE:               (6)
   $  READ/END=DONE DIRFILE NAME
   $  DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
                      ! переопределить SYS$INPUT
   $  EDIT 'NAME'     ! редакция файла
   $  GOTO NEWLINE
   $ !
   $ DONE:      (7)
   $  CLOSE DIRFILE/ERROR=NOTOPEN ! закрытие файла
   $ NOTOPEN:
   $  DELETE DIRECT.OUT;*  ! удалить временный файл
   $ EXIT
   $ !
   $ ERROR_SEC:
   $  WRITE SYS$OUTPUT "ERROR: ",F$MESSAGE($STATUS)
   $  DELETE DIRECT.OUT;*
   $ EXIT
 
        Пояснения:
 
        (1) команда ON  устанавливает  условия  обработки  для
 
   этой процедуры. Если появляется ошибка или вводится  CTRL/Y
 
 
                              197 
 
                        000152-01 97 04
 
 
   во время выполнения этой процедуры, будет выполняться пере-
 
   ход на метку DONE;
 
        (2) проверяется подсказка для типа файла;
 
        (3) команда DIRECTORY перечисляет все  файлы  с  типом
 
   файла, заданным в P1. Вывод  команды  записывается  в  файл
 
   DIRECT.OUT. Квалификатор  /VERSIONS=1  требует,  чтобы  для
 
   каждого файла перечислялись только версии с самыми старшими
 
   номерами. Квалификаторы /NOHEADING и  /NOTRAILING  требуют,
 
   чTобы в вывод не включались  заголовок  и  ключевая  строка
 
   каталога. Квалификатор /COLUMNS=1 обеспечивает вывод одного
 
   имени файла на строке;
 
        (4) команда IF проверяет командой  DIRECTORY  величину
 
   возврата  путем  проверки  символа  $STATUS.  Если  команда
 
   DIRECTORY завершена не успешно,  то  $STATUS  имеет  четную
 
   целую величину и выполняется выход;
 
        (5) команда OPEN открывает выходной  файл  каталога  и
 
   задает ему логическое имя DIRFILE;
 
        (6) команда  READ  читает  строку  из  вывода  команды
 
   DIRECTORY в символ с именем NAME. После чтения  переопреде-
 
   ляется входной поток для сеанса  редактирования  с  помощью
 
   команды  ASSIGN.  Затем  вызывается  редактор,  задавая   в
 
   качестве спецификации файла символ NAME. Когда сеанс редак-
 
   тирования завершается, интерпретатор команд выполняет  чте-
 
   ние следующей строки в файле;
 
        (7) метка DONE является целевой меткой для  квалифика-
 
   тора /END  в  команде  READ  и  для  установки  условий  ON
 
   CONTROL_Y и ON ERROR в  начале  процедуры.  С  этой  меткой
 
   выполняются необходимые  операции  очистки.  Команда  CLOSE
 
   закрывает выходной  файл  команды  DIRECTORY;  квалификатор
 
   /ERROR задает метку на следующей  строке  процедуры.  Такое
 
 
                              198 
 
                        000152-01 97 04
 
 
   использование квалификатора /ERROR  будет  подавлять  любые
 
   сообщения об ошибке, если файл не  открыт,  например,  если
 
   вводится CTRL/Y перед открытием файла каталога.
 
        Вторым шагом в очистке  является  удаление  временного
 
   файла каталога.
 
 
        П р и м е р 6.
 
 
   $ @EDITALL DAT
   *   .
       .
       .
 
        В примере 6 процедура EDITALL вызывается с P1,  задан-
 
   ного как DAT. Процедура создает  распечатку  каталога  всех
 
   файлов в каталоге по умолчанию, типы файлов которого  соот-
 
   ветствуют DAT и вызывает редактор для редактирования каждо-
 
   го файла.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              199 
 
                        000152-01 97 04
 
 
                Командная процедура FORTUSER.COM
 
 
   $! Процедура для создания, компиляции, компоновки и отладки
   $! программ на языке фортран. Пользователи могут вводить
   $! только команды, перечисленные в символьной
   $! таблице OPTION_TABLE.
   $  SET NOCONTROL=Y        (1)
   $  SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
   $  SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
   $  OPTION_TABLE = "EDIT/COMPILE/LINK/RUN/EXECUTE/DEBUG-
      /PRINT/HELP/FILE/DONE/"     (2)
 
   $  TYPE SYS$INPUT       (3)
       интерпретатор команд языка фортран МОС ВП
       введите имя файла, с которым предполагается работать
 
   $ !
   $ ! установить начальную подсказку
   $ !
   $ PROMPT = "INIT"      (4)
   $ GOTO HELP  ! напечатать начальное сообщение для пояснений
 
   $ !
   $ ! после первого сообщения подсказки используется
   $ ! подсказка COMMAND (команда)
   $ !
   $ INIT:
   $ PROMPT = "GET_COMMAND"
   $ GOTO FILE                !получить начальное имя файла
 
   $ !
   $ ! главная подпрограмма грамматического разбора команды.
   $ ! подпрограмма сравнивает текущую команду с вариантами
   $ ! в таблице возможностей. При обнаружении согласования
   $ ! выполняется переход на соответствующую метку.
 
   $ !
   $ GET_COMMAND:
   $   ON CONTROL_Y THEN GOTO GET_COMMAND
   $                ! CTRL/Y сбрасывает подсказку    (5)
   $   SET CONTROL=Y
   $   ON WARNING THEN GOTO GET_COMMAND
   $     ! если такое вообще встречается, сбросьте подсказку
   $   INQUIRE COMMAND "COMMAND"
   $   IF COMMAND .EQS. "" THEN GOTO GET_COMMAND
   $   IF F$LOCATE(COмMAND+"/",OPTION_TABLE) .EQ. F$LENGTH-(6)
                              (OPTION_TABLE)-
                               THEN GOTO INVALID_COMMAND
   $   GOTO 'COMMAND'
 
   $ !
   $ INVALID_COMMAND :       (7)
   $      WRITE SYS$OUTPUT " INVALID COMMAND"
   $ !
 
   $ HELP:            (8)
   $  TYPE SYS$INPUT
 
 
 
                              200 
 
                        000152-01 97 04
 
 
      Приводятся команды, которые может вводить
      пользователь:
 
      FILE    имя программы на языке фортран в текущем
              каталоге пользователя по умолчанию
      EDIT    выполняет редактирование программы
      COMPILE выполняет компиляцию программы с помощью
              интерпретатора команды фортран МОС ВП
      LINK    выполняет компоновку программы для получения
              выполняемого образа
      RUN     выполняет прогон выполняемого образа программы
      EXECUTE выполняет те же функции, что и команды COMPILE,
              LINK и RUN
      DEBUG   выполняет прогон программы под управлением
              отладчика
      PRINT   выполняет постановку в очередь самой последней
              распечатки для вывода на печать
      DONE    выполняет возврат на интерактивный командный
              уровень
      HELP    выполняет вывод на печать данного поясняющего
              сообщения
 
              введите CTRL/Y для повторного запуска
              этого сеанса
 
   $ GOTO 'PROMPT'         (9)
   $ EDIT:             (10)
   $      DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
   $      EDIT 'FILE_NAME'.FOR
   $      GOTO GET_COMMAND
   $ COMPILE:
   $      FORTRAN 'FILE_NAME'/LIST/OBJECT/DEBUG
   $      GOTO GET_COMMAND
   $ LINK:
   $      LINK 'FILE_NAME'/DEBUG
   $      PURGE 'FILE_NAME'.*/KEEP=2
   $      GOTO GET_COMMAND
   $ RUN:
   $      DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
   $      RUN/NODEBUG 'FILE_NAME'
   $      GOTO GET_COMMAND
   $ DEBUG:
   $      DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
   $      RUN 'FILE_NAME'
   $      GOTO GET_COMMAND
   $ EXECUTE:
   $      FORTRAN 'FILE_NAME'/LIST/OBJECT
   $      LINK/DEBUG 'FILE_NAME'
   $      PURGE 'FILE_NAME'.*/KEEP=2
   $      RUN/NODEBUG 'FILE_NAME'
   $      GOTO GET_COMMAND
 
   $ PRINT:
   $      PRINT 'FILE_NAME'
   $      GOTO GET_COMMAND
   $ BADFILE:       (11)
   $      WRITE SYS$OUTPUT "файл должен быть в текущем
          каталоге."
   $ FILE:
 
 
                              201 
 
                        000152-01 97 04
 
 
   $      INQUIRE FILE_NAME "FILE NAME"
   $      IF FILE_NAME .EQS. "" THEN GOTO FILE
   $      IF F$PARSE(FILE_NAME,,,"DIRECTORY") .NES. -
          F$DIRECTORY() -          (12)
          THEN GOTO BADFILE
   $      FILE_NAME =F$PARSE(FILE_NAME,,,"NAME")
   $      GOTO GET_COMMAND
   $ DONE:
   $ EXIT
 
        Пояснения:
 
        (1) команда  SET  NOCONTROL=Y  запрещает  пользователю
 
   прерывать процедуру или любую команду, или программу в этой
 
   процедуре;
 
        (2)  в  таблице  возможностей  перечисляются  команды,
 
   которые разрешено выполнять  пользователю.  Каждая  команда
 
   разделяется символом косой черты;
 
        (3) вывод сообщения о начале работы процедуры;
 
        (4) символьное имя PROMPT задает значение метки в про-
 
   цедуре. При начальном вызове процедуры символ имеет величи-
 
   ну INIT. Текст  команды  HELP  завершается  командой  GOTO,
 
   которая задает м[6~у PROMPT. Когда текст отображается  пер-
 
   вый раз, результатом выполнения команды GOTO является пере-
 
   ход на метку HELP.  Отображается  сообщение  HELP,  которое
 
   поясняет команды, которые может ввести пользователь.  Затем
 
   процедура возвращается на метку INIT, где  величина  PROMPT
 
   изменяется на "GET_COMMAND". Наконец,  процедура  переходит
 
   на метку FILE для  получения  имени  файла.  Следовательно,
 
   когда отображается текст, поясняющий  разрешенные  команды,
 
   процедура переходит на метку GET_COMMAND для получения сле-
 
   дующей команды;
 
        (5) устанавливается действие условия CTRL/Y для  возв-
 
   рата на метку GET_COMMAND, как при получении  предупреждаю-
 
   щего условия. Выводятся подсказки  для  ввода  команд.  Для
 
   завершения сеанса необходимо использовать команду DONE;
 
 
                              202 
 
                        000152-01 97 04
 
 
        (6)  используются  лексические  функции   F$LOCATE   и
 
   F$LENGTH для определения того, включена ли команда в список
 
   возможностей. Функция  F$LOCATE  выполняет  поиск  команды,
 
   введенной пользователем, вслед за  которой  следует  символ
 
   косой черты. (например, если  пользователь  вводит  команду
 
   EDIT, выполняется поиск команды EDIT/.).  Если  команда  не
 
   включена в список вариантов, то выполняется переход на мет-
 
   ку INVALID_COMMAND. Если команда действительная, выполняет-
 
   ся переход на соответствующую метку;
 
        (7) в метке INVALID_COMMAND выполняется запись сообще-
 
   ния об ошибке и отображение поясняющего текста,  в  котором
 
   перечисляются действительные команды;
 
        (8) в поясняющем тексте  перечисляются  действительные
 
   команды. Этот текст отображается  первоначально.  Он  также
 
   отображается всякий раз, когда пользователь выводит команду
 
   HELP или любую недействительную команду;
 
        (9) в заключительной части текста команды HELP команда
 
   GOTO задает символьное  имя  PROMPT.  Когда  эта  процедура
 
   вызывается в первый раз,  символ  имеет  величину  INIT.  В
 
   дальнейшем он имеет величину GET_COMMAND;
 
        (10) каждая корректная команда в  списке  имеет  соот-
 
   ветствующий вход в таблицу возможностей  и  соответствующую
 
   метку в командной процедуре. Для команд, выполняющих чтение
 
   ввода с терминала, например, для  команды  EDIT,  процедура
 
   содержит команду DEFINE, которая определяет  входной  поток
 
   как SYS$COMMAND;
 
        (11) в метке BADFILE отображается сообщение, указываю-
 
   щее на файл, который должен находиться в текущем  каталоге.
 
   Затем выполняется подсказка для другого имени файла;
 
 
 
 
                              203 
 
                        000152-01 97 04
 
 
        (12) после получения имени  файла  проверяется,  соот-
 
   ветствует ли каталог текущему каталогу по умолчанию.  Затем
 
   используется функция F$PARSE  для  выделения  имени  файла.
 
   (каждая команда будет поставлять соответствующий тип  файла
 
   по  умолчанию).  Затем  управление  возвращается  на  метку
 
   GET_COMMAND, чтобы получить команду для обработки файла.
 
        В примере 7 поясняется использование командной  проце-
 
   дуры, выполняемой при регистрации в системе.
 
 
        П р и м е р 7.
 
 
   USERNAME: CLASS30
 
   PASSWORD:
 
            МОС ВП VERSION 1.0
 
       интерпретатор команд языка фортран МОС ВП
 
       введите имя файла, с которым предполагается работать.
 
       Команды, которые может вводить пользователь:
 
   FILE      имя программы на языке фортран в текущем
             каталоге пользователя по умолчанию. Команды
             подпоследовательности обрабатывают этот файл
   EDIT      выполнить редактирование программы
   COMPILE   выполнить компиляцию программы с помощью FORTRAN
             МОС ВП
   LINK      выполнить компоновку программы для получения
             выполняемого образа
   RUN       выполнить прогон выполняемого образа программы
   EXECUTE   выполнить те же функции, что и команды COMPILE,
             LINK и RUN
   DEBUG     выполнить прогон программы под управлением
             отладчика
   PRINT     установить в очередь самую последнюю распечатку
             файла для вывода на печать
   DONE      выполнить возврат на интерактивный командный
             уровень
   HELP      выполнить вывод на печать данного поясняющего
             сообщения
 
   Введите CTRL/Y для повторного запуска этого сеанса
 
   FILE NAME: AVERAGE
   COMMAND: COMPILE
   COMMAND: LINK
   COMMAND: RUN
   COMMAND: FILE
 
 
                              204 
 
                        000152-01 97 04
 
 
   FILE NAME: READFILE
   COMMAND: EDIT
 
        В примере 7 показан вход в систему, отображается пояс-
 
   няющий текст и примеры некоторых команд. Сначала, пользова-
 
   тель задает файл AVERAGE, выполняет компиляцию,  компоновку
 
   и прогон этого файла.  Затем  пользователь  вводит  команду
 
   FILE, чтобы начать работу с другим файлом.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              205 
 
                        000152-01 97 04
 
 
                 Командная процедура LISTER.COM
 
 
   $ ! Процедура для накапливания имен программистов и
   $ ! документирования имен файлов. После ввода всех имен и
   $ ! файлов они сортируются в алфавитном порядке по имени
   $ ! программиста
 
   $ !
   $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE") (1)
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
   $ !
   $ OPEN/WRITE OUTFILE DATA.TMP  ! создать выходной файл (2)
   $ !
 
   $ LOOP:    (3)
   $       INQUIRE NAME "программист (введите ВК для -
                                      завершения)"
   $       IF NAME .EQS. "" THEN GOTO FINISHED
   $       INQUIRE FILE "имя файла сохранения"
   $       RECORD[0,20]:='NAME'    (4)
   $       RECORD[21,20]:='FILE'
   $       WRITE OUTFILE RECORD
   $       GOTO LOOP
   $ FINISHED:
   $        CLOSE OUTFILE
 
   $ !
   $ DEFINE/USER_MODE SYS$OUTPUT: NL: -
                     ! подавить вывод сортировки
   $ SORT/KEY=(POSITION:1,SIZE=20) DATA.TMP DOC.SRT (5)
   $ !
   $ OPEN/WRITE OUTFILE DOCUMENT.DAT       (6)
   $ WRITE OUTFILE "файлы программиста",F$TIME()
   $ WRITE OUTFILE ""
   $ RECORD[0,20]:="имя программиста"
   $ RECORD[21,20]:="имя файла"
   $ WRITE OUTFILE RECORD
   $ WRITE OUTFILE ""
 
   $ !
   $ CLOSE OUTFILE        (7)
   $ APPEND DOC.SRT DOCUMENT.DAT
   $ PRINT DOCUMENT.DAT
 
   $ !
   $ INQUIRE CLEAN_UP "удалить временные файлы?" (8)
   $ IF CLEAN_UP THEN DELETE DATA.TMP;*,DOC.SRT;*
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,-
       SAVE_VERIFY_IMAGE)
   $ EXIT
 
        Пояснения:
 
        (1) сохраняется текущая установка проверки и  устанав-
 
   ливается выключение проверки;
 
 
 
 
                              206 
 
                        000152-01 97 04
 
 
        (2) команда OPEN открывает временный файл для записи;
 
        (3) команда  INQUIRE  выполняет  подсказку  для  имени
 
   программиста и имени файла. В случае пустой строки, то есть
 
   ввода  только  RETURN,  подразумевается,  что  ввод  данных
 
   завершен и выполняется переход на метку FINISHED;
 
        (4) после назначения величин для символов FILE и  NAME
 
   формируется об'единяющая символьная  строка  и  назначается
 
   символу RECORD. В позициях 1-21 символа RECORD записывается
 
   величина символа NAME, в следующие 20 позиций  записывается
 
   величина FILE. Затем величина RECORD записывается в  выход-
 
   ной файл;
 
        (5) после закрытия файла выполняется сортировка выход-
 
   ного файла DATA.TMP. Команда DEFINE направляет вывод коман-
 
   ды SORT на  NL:.  В  противном  случае  эта  статистическая
 
   информация будет отображаться на терминале.
 
        Сортировка выполняется для первых 20 колонок, то есть,
 
   по имени программиста.
 
        Отсортированный выходной файл имеет имя DOC.SRT;
 
        (6) создается окончательный выходной файл DOCUMENT.DAT
 
   с помощью команды OPEN. Первые строки, записываемые в файл,
 
   являются строками заголовка;
 
        (7) файл DOCUMENT.DAT закрывается и к нему добавляется
 
   отсортированный выходной файл DOC.SRT. Затем выходной  файл
 
   устанавливается в очередь  к  системному  печатающему  уст-
 
   ройству;
 
        (8) наконец, выполняется подсказка для удаления проме-
 
   жуточных файлов. Если для подсказки команды INQUIRE вводит-
 
   ся утвердительный ответ (т или Y), то будут  удалены  файлы
 
   DATA.TMP и DOC.SRT. В  противном  случае  эти  файлы  будут
 
   оставлены.
 
 
                              207 
 
                        000152-01 97 04
 
 
        П р и м е р 8.
 
 
   $ @LISTER
   PROGRAMMER: WATERS
   DOCUMENT FILE NAME: CRYSTAL.CAV
   PROGRAMMER: JENKINS
   DOCUMENT FILE NAME: MARIGOLD.DAT
   PROGRAMMER: MASON
   DOCUMENT FILE NAME: SYSTEM.SRC
   PROGRAMMER: ANDERSON
   DOCUMENT FILE NAME: JUNK.J
   PROGRAMMER: RET
   DELETE TEMPORATY FILES:Y
 
        Результирующий выходной файл после выполнения процеду-
 
   ры примера 8 следующий:
 
 
   Файлы программиста 15 апреля 1984 года 16:18:58.79
 
   Имя программиста            Имя файла
 
   ANDERSON                    JUNK.J
   JENKINS                     MARIGOLD.DAT
   MASON                       SYSTEM.SRC
   WATERS                      CRYSTAL.CAV
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              208 
 
                        000152-01 97 04
 
 
                  Командная процедура CALC.COM
 
 
   $ ! процедура для вычисления выражений. Если вводится
   $ ! оператор присваивания, то процедура CALC.COM вычисляет
   $ ! выражение и присваивает результат символу, заданному
   $ ! пользователем. В следующей итерации пользователь может
   $ ! либо использовать свой символ, либо символ Q для
   $ ! представления текущего результата.
 
   $ !
   $ ! если вводится выражение, то после этого процедура
   $ ! CALC.COM вычисляет выражение и присваивает результат
   $ ! символу Q. В следующей итерации пользователь может
   $ ! использовать символ Q для предоставления текущего
   $ ! результата.
 
   $ !
   $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")  (1)
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
   $ START:
   $      ON WARNING THEN GOTO START
   $      INQUIRE STRING "CALC"           (2)
   $      IF STRING .EQS. "" THEN GOTO CLEAN_UP
   $      IF F$LOCATE("=",STRING) .EQ. F$LENGTH(STRING) THEN-
            GOTO EXPRESSION
 
   $ !
   $ ! выполнить, если строка имеет форму:символ = выражение
   $ STATEMENT:    (3)
   $ 'STRING'   ! выполнить операторы присваивания
   $ SYMBOL = F$EXTRACT(0,F$LOCATE("=",STRING)-1,STRING)
   $               ! получить символьное имя
   $ Q = 'SYMBOL'   ! установить Q для будущих итераций
   $ LINE = F$FAо("DECIMAL=!SL HEX=!-!XL OCTAL=!-!оL",Q)
   $ WRITE SYS$OUTPUT LINE
   $ GOTO START
   $ !
 
   $ !
   $ ! выполнить, если строка является выражением
   $ EXPRESSION:        (4)
   $  Q = F$INTEGER('STRING')
   $           ! можно использовать Q в следующей итерации
   $  LINE = F$FAO("DECIMAL = !SL -
               HEX = !-!XL  OCTAL = !-!OL",Q)
   $  WRITE SYS$OUTPUT LINE
   $  GOTO START
 
   $ !
   $ CLEAN_UP:
   $ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,-
            SAVE_VERIFY_IMAGE)
   $ EXIT
 
        Пояснения:
 
        (1) устанавливается условие обработки ошибок,  которое
 
 
 
                              209 
 
                        000152-01 97 04
 
 
   вызывает запуск процедуры.  Если  возникает  предупреждение
 
   или более серьезная ошибка, выполняется переход на  начало,
 
   где восстанавливается условие ON.
 
        Этот метод гарантирует продолжение выполнения процеду-
 
   ры при неправильном вводе выражения;
 
        (2) команда INQUIRE выводит подсказку для арифметичес-
 
   кого выражения. Процедура обрабатывает выражение в  следую-
 
   щих форматах:
 
   имя = выражение
   выражение
 
        Если выражение не вводится, подразумевается  окончание
 
   сеанса работы процедуры и выполняется выход.
 
        Если пользователь вводит выражение в  формате  "имя  =
 
   выражение", то выполнение продолжается с метки STATEMENT. В
 
   противном случае выполняется переход на метку EXPRESSION;
 
        (3) выполняется присваивание результата выражения сим-
 
   волу. Затем выделяется символьное имя и присваивается  сим-
 
   волу Q. Это позволяет  использовать  либо  Q,  либо  символ
 
   пользователя во время следующей итерации  процедуры.  Затем
 
   отображается результат и управление возвращается  на  метку
 
   START;
 
        (4) вычисляется выражение  и  результат  присваивается
 
   символу Q. Это позволяет использовать Q во время  следующей
 
   итерации процедуры. Затем отображается результат и управле-
 
   ние возвращается на метку START.
 
 
 
 
 
 
 
 
 
 
 
 
 
                              210 
 
                        000152-01 97 04
 
 
        П р и м е р 9.
 
 
   $ @CALC
   CALC: 2 * 30
   DECIMAL = 60   HEX = 0000003C  OCTAL = 00000000074
   CALC: Q + 3
   DECIMAL = 63   HEX = 0000003F  OCTAL = 00000000077
   CALC: TOTAL = Q + 4
   DECIMAL = 67   HEX = 00000043  OCTAL = 00000000103
   CALC: 5 + 7
   DECIMAL = 12   HEX = 0000000C  OCTAL = 00000000014
   CALC:<RET>
   $
 
        В примере 9 на каждую подсказку  "CALC:"  пользователь
 
   вводит  арифметическое  выражение.   Процедура   отображает
 
   результат в десятичном,  шестнадцатиричном  и  восьмеричном
 
   представлении. Пустая строка, то  есть  ввод  только  <вк>,
 
   завершает сеанс работы процедуры.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              211 
 
                        000152-01 97 04
 
 
                  Командная процедура BATCH.COM
 
 
   $ VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
   $ VERIFY_PROCEDURE = F$VERIFY(0)
   $!
   $! выключить проверку и сохранить текущие установки. (этот
   $! комментарий должен появляться после выключения проверки;
   $! иначе он будет появляться в файле журнала пакетного
   $! задания)
   $!
 
   $!
   $! если процедура выполняется как пакетное задание
   $! (из секции SUBMIT), TO управление передается в секцию
   $! EXECUTE_BATCH_JOB. Необходимо получить информацию
   $! для выполнения пакетного задания из этой секции
 
   $!
   $ IF F$MODE() .EQS. "BATCH" THEN GOTO EXECUTE_BATCH_JOB (1)
   $!
 
   $!
   $! подготовить командную процедуру к представлению в виде
   $! пакетного задания
   $
   $!
   $! используются следующие правила:
 
   $!
   $! 1) если пользователь выполняет одиночную команду, то
   $!    следует использовать имя команды. Исключить любые
   $!    квалификаторы, которые были включены с командой.
   $! 2) если пользователь выполняет командную процедуру,
   $!    то следует использовать имя файла.
   $! 3) иначе следует использовать BATCH.
 
   $!
   $ JOB_NAME = P1        (2)
   $ IF JOB_NAME .EQS. "" THEN JOB_NAME = "BATCH"
   $ IF F$EXTRACT(0,1,JOB_NAME) .EQS. "@" THEN JOB_NAME= -
           F$EXTRACT(1,999,JOB_NAME)
   $ JOB_NAME = F$EXTRACT(0,F$LOCATE("/",JOB_NAME),JOB_NAME)
   $ JOB_NAME = F$PARSE(JOB_NAME,,,"NAME","SYNTAX_ONLY")
   $ IF JOB_NAME .EQS. "" THEN JOB_NAME = "BATCH"
   $!
 
   $!
   $! получить текущие устройство и каталог по умолчанию
   $!
   $ ORIGDIR = F$ENVIRONMENT("DEFAULT")
   $!
 
   $!
   $! об'единить параметры для формирования командной строки,
   $! подлежащей выполнению. Если пользователь не вводит
   $! командную строку, символ COMMAND будет иметь нулевую
   $! величину.
   $!
 
 
                              212 
 
                        000152-01 97 04
 
 
   $ COMMAND = P1 + " " + P2 + " " + P3 + " " + P4 + " " + -
               P5 + " " + P6 + " " + P7 + " " + P8    (3)
   $!
 
   $!
   $! если пользователь выполняет одиночную команду и если
   $! как команда, так и спецификация исходного каталога
   $! являются достаточно малыми, чтобы быть представленными в
   $! качестве параметров для команды SUBMIT, то тогда
   $! запустить пакетное задание
   $!
   $ IF (P1 .NES. "") .AND. (F$LENGTH(COMMAND) .LE. 255) -
     .AND. (F$LENGTH(ORIGDIR) .LE. 255) THEN GOTO SUBMIT (4)
   $!
 
   $!
   $! если одиночная команда, подлежащая выполнению в
   $! пакетном задании, является очень большой, либо если
   $! пользователь получает подсказку для команды для
   $! выполнения в пакетном режиме, то создать временную
   $! командную процедуру для сохранения таких команд и
   $! получить полное расширенное имя командной процедуры.
   $!
   $ CREATE_TEMP_FILE:       (5)
   $  ON CONTROL_Y THEN GOTO CONTROL_Y_HANDLER   (6)
   $  OPEN/WRITE/ERROR=FILE_OPEN_ERROR TEMPFILE SYS$SCRATCH:-
      'JOB_NAME'.TMP
   $  FILESPEC = F$SEARCH("SYS$SCRATCH:" + JOB_NAME + ".TMP")
 
   $!
   $! по умолчанию, продолжить пакетное задание, если оно
   $! встречает любые ошибки.
   $!
   $ WRITE TEMPFILE "$ SET NOON"
   $!
   $! либо записать одиночную большую команду в файл, либо
   $! выполнить подсказку для многих команд и записать их в
   $! файл
   $!
 
   $ IF COMMAND .NES."     " THEN GOTO WRITE_LARGE_COMMAND
   $
   $ LOOP:
   $   READ/END_OF_FILE=CLOSE_FILE/PROMPT="COMMAND: " -
       SYS$COMMAND COMMAND
   $   IF COMMAND .EQS. "" THEN GOTO CLOSE_FILE
   $   WRITE TEMPFILE "$ ",COMMAND
   $   GOTO LOOP
   $
   $ WRITE_LARGE_COMMAND:
   $  WRITE TEMPFILE "$ ",COMMAND
   $
 
   $! закончить временный файл определением символа так,
   $! чтобы пользователь знал имя удаляемой командной
   $! процедуры, и затем закрыть файл. Определить символ
   $! COMMAND, чтобы он имел значение "выполнить командную
   $! процедуру, только что созданную пользователем". Затем
   $! представить пакетное задание и выполнить эту командную
 
 
                              213 
 
                        000152-01 97 04
 
 
   $! процедуру в пакетном задании.
   $!
 
   $ CLOSE_FILE:        (7)
   $   WRITE TEMPFILE "$ BATCH$DELETE_FILESPEC == -
         """,FILESPEC,""""
   $   CLOSE TEMPFILE
   $   ON CONTROL_Y THEN EXIT
   $   COMMAND = "@" + FILESPEC
   $!
   $!
   $! представить командную процедуру BATCH.COM как пакетное
   $! задание и передать два ее параметра. P1 является
   $! командой (или командной процедурой), подлежащей
   $! выполнению. P2 является каталогом, из которого
   $! выполняется команда.
   $!
 
   $ SUBMIT:      (8)
   $  SUBMIT/NOTIFY/NOPRINT 'F$ENVIRONMENT("PROCEDURE")' -
        /NAME='JOB_NAME' -
        /PARAMETERS=("''COMMAND'","''ORIGDIR'")
   $  GOTO EXIT
   $!
   $!
   $! пользователь ввел Yс/Y в то время, когда файл командной
   $! процедуры был открыт. Закрыть командную процедуру,
   $! удалить ее, если она существует, и выполнить выход.
   $!
 
   $ CONTROL_Y_HANDLER:        (9)
   $   CLOSE TEMPFILE
   $   IF F$TYPE(FILESPEC) .NES. "" THEN DELETE/NOLOG -
               'FILESPEC'
   $   WRITE SYS$OUTPUT "ввод YC/Y привел к завершению -
                 командной процедуры"
   $   GOTO EXIT
   $!
   $!
   $! временная командная процедура не может быть создана.
   $! известить пользователя и выполнить выход.
   $!
 
   $ FILE_OPEN_ERROR:     (10)
   $   WRITE SYS$OUTPUT "COULD NOT CREATE -
         SYS$SCRATCH:",JOB_NAME,".TMP"
   $   WRITE SYS$OUTPUT "PLEASE CORRECT THE SITUATION -
         AND TRY AGAIN."
   $!
   $!
   $! восстановить состояние проверки и выполнить выход.
   $!
 
   $ EXIT:          (11)
   $ VERIFY_PROCEDURE = F$VERIFY(VERIFY_PROCEDURE,-
         VERIFY_IMAGE)
   $ EXIT
   $!
   $!
 
 
                              214 
 
                        000152-01 97 04
 
 
   $! командная процедура BATCH.COM вызвана как пакетное
   $! задание. P1 содержит команду, подлежащую выполнению,
   $! а Р2 содержит спецификацию каталога по умолчанию.
   $! возвратить код состояния, указывающий на состояние
   $! завершения P1.
   $!
 
   $ EXECUTE_BATCH_JOB:          (12)
   $     SET NOON
   $     VERIFY_PROCEDURE = F$VERIFY(VERIFY_PROCEDURE,-
             VERIFY_IMAGE)
   $     SET DEFAULT 'Р2'
   $     'P1'
   $     IF F$TYPE(BATCH$DELETE_FILESPEC) .EQS. "" THEN -
               EXIT $STATUS
   $     STATUS = $STATUS
   $     DELETE /NOLOG 'BATCH$DELETE_FILESPEC'
   $     EXIT STATUS
 
        Пояснения:
 
        (1) эта команда IF проверяет, выполняется ли процедура
 
   BATCH.COM в пакетном режиме.  Когда  пользователь  вызывает
 
   процедуру  BATCH.COM  интерактивно,  он   обеспечивает   (в
 
   качестве параметров) командную строку или командную  проце-
 
   дуру, которая должна выполняться как пакетное задание. Если
 
   пользователь  не   поставляет   параметры,   то   процедура
 
   BATCH.COM выполняет подсказки для  команд,  записывает  эти
 
   команды в файле и затем выполняет  эту  командую  процедуру
 
   как пакетное задание. После того, как  процедура  BATCH.COM
 
   подготовит команду (команды) пользователя для выполнения из
 
   пакетного задания, она использует команду SUBMIT для предс-
 
   тавления самой  себя  как  пакетного  задания  и  выполняет
 
   команду (команды) пользователя из этого задания. (см.  При-
 
   мечание 8). Когда пользователь вызывает процедуру BATCH.COM
 
   в качестве пакетного задания, процедура  выполняет  переход
 
   на метку EXECUTE_BATCH_JOB;
 
        (2) эти команды подготавливают  пакетное  задание  для
 
   выполнения. Вначале процедура  создает  имя  для  пакетного
 
   задания.  Если  передана  командная  строка,  то  процедура
 
 
 
                              215 
 
                        000152-01 97 04
 
 
   BATCH.COM использует команды в качестве имени задания. Если
 
   передана командная процедура, то BATCH.СОМ  использует  имя
 
   файла. Если ввод не  передавался,  то  процедура  BATCH.СОМ
 
   присваивает заданию имя BATCH;
 
        (3) соединяются параметры для  формирования  командной
 
   строки, подлежащей выполнению. Командная строка назначается
 
   символу COMMAND;
 
        (4) команда SUBMIT не может передавать параметр,  пре-
 
   вышающий по размеру 5 символов. Поэтому процедура выполняет
 
   проверку на то, что командная строка и имя каталога  меньше
 
   255 символов в длину. Если обе строки меньше  в  длину  255
 
   символов (и если пользователь, в действительности, не пере-
 
   давал  командную  строку),  процедура  переходит  на  метку
 
   SUBMIT;
 
        (5)  процедура  устанавливает  обработчик   прерываний
 
   CTRL/Y так, чтобы выполнялись операции очистки, если  поль-
 
   зователь вводит CTRL/Y  во  время  выполнения  этой  секции
 
   командной процедуры;
 
        (6) процедура создает временный файл, в котором  будут
 
   содержаться команды, подлежащие выполнению. Если  пользова-
 
   тель поставляет длинную командную строку, процедура  выпол-
 
   няет переход на метку WRITE_COMMAND и записывает команду во
 
   временный файл. Иначе, процедура  выполняет  подсказки  для
 
   команд, подлежащих выполнению. Каждая команда  записывается
 
   во временный файл;
 
        (7) перед тем, как закрыть файл, в  него  записывается
 
   оператор присваивания. Этот оператор присваивает  имя  вре-
 
   менного файла символу BATCH$DELETE_FILESPEC. После закрытия
 
   файла сбрасывается обработчик прерываний CTRL/Y по  умолча-
 
   нию. Затем процедура определяет символ COMMAND так, что при
 
 
                              216 
 
                        000152-01 97 04
 
 
   выполнении COMMAND  будет  вызываться  временный  командный
 
   файл;
 
        (8) процедура запускается как пакетное задание.  Пере-
 
   даются два параметра: команда или командная процедура, под-
 
   лежащая выполнению, и каталог, из  которого  должна  выпол-
 
   няться команда. Затем выполняется переход на метку EXIT;
 
        (9) в этой секции выполняются операции  очистки,  если
 
   пользователь вводит CTRL/Y  во  время  создания  временного
 
   файла;
 
        (10) в этой секции выводится сообщение об ошибке, если
 
   нельзя создать временный файл;
 
        (11) восстанавливаются исходные установки  проверки  и
 
   затем выполняется выход;
 
        (12) эти команды выполняются, если командная процедура
 
   BATCH.COM прогоняется в пакетном режиме. Сначала блокирует-
 
   ся обработка ошибок команды ON и устанавливаются  установки
 
   проверки пользователя по умолчанию.  Затем  устанавливается
 
   умолчание для каталога с помощью Р2 и выполняется  команда,
 
   заданная с помощью Р1. Если был создан временный  файл,  то
 
   этот    файл    удаляется.    Перед    удалением    символа
 
   BATCH$DELETE_FILESPEC сохраняется состояние завершения  Р1.
 
   Это состояние завершения возвращается командой EXIT.
 
 
        П р и м е р 10.
 
 
   $ @BATCH RUN MYPROG
   JOB RUN (QUEUE SYS$BATCH, ENTRY 1715), STARTED ON
   SYS$BATCH
 
        В примере 10 командная процедура BATCH.COM использует-
 
   ся для прогона программы в пакетном задании.
 
 
 
 
 
 
                              217 
 
                        000152-01 97 04
 
 
                                                  Приложение 2
 
 
 
 
 
                   Сводка лексических функций
 
 
 
 
        Для получения полной  информации  относительно  каждой
 
   функции, представленной в данном приложении, следует  обра-
 
   титьсь к документу [1].
 
        F$CVSI (позиция-бита, счетчик, целое)
 
        Выделяет битовые поля из данных типа символьной строки
 
   и преобразует результат, как величину со знаком, в целое.
 
        F$CVTIME (время)
 
        Восстанавливает информацию относительно строк абсолют-
 
   ного времени, дельта-времени и их комбинация.
 
        F$CVUI (позиция-бита, счетчик, целое)
 
        Выделяет битовые поля из данных типа символьной  стро-
 
   ки, и преобразует результат,  как  величину  без  знака,  в
 
   целое.
 
        F$DIRECTORY()
 
        Возвращает строку имени текущего каталога  по  умолча-
 
   нию.
 
        F$EDIT (строка, список-редактирования)
 
        Редактирует символьную  строку  на  базе  спецификаций
 
   редактирования.
 
        F$ELEMENT (номер-элемента, ограничитель, строка)
 
        Выделяет элемент из строки, в которой элементы  разде-
 
   ляются заданными ограничителями.
 
        F$ENVIRONMENT (элемент)
 
        Определяет информацию относительно среды команд DCL.
 
 
 
                              218 
 
                        000152-01 97 04
 
 
        F$EXTRACT (смещение, длина, строка)
 
        Выделяет подстроку из выражения типа символьной  стро-
 
   ки.
 
        F$FAO  (управляющая-строка  [,  аргумент  1,  аргумент
 
   2,..., аргумент 15])
 
        Вызывает подпрограмму системного обслуживания $FAO для
 
   преобразования заданной управляющей строки  в  отформатиро-
 
   ванную выходную строку кода ASCII.
 
        F$FILE_ATTRIBUTES (спецификация-файла, элемент)
 
        Возвращает информацию  об  атрибуте  для  спецификации
 
   файла.
 
        F$GETDVI (имя-устройства, элемент)
 
        Вызывает подпрограмму системного обслуживания  $GETDVI
 
   для возвращения заданного элемента информации для заданного
 
   устройства.
 
        F$GETJPI (идентификатор процесса, элемент)
 
        Вызывает подпрограмму системного обслуживания  $GETJPI
 
   для возврата информации об учете, состоянии и идентификации
 
   процесса.
 
        F$GETSYI (элемент [, узел])
 
        Вызывает подпрограмму системного обслуживания  $GETSYI
 
   и возвращает информацию о состоянии и идентификации локаль-
 
   ной системы.
 
        F$IDENTIFIER (идентификатор, тип-преобразования)
 
        Преобразует идентификатор в  именной  формат  для  его
 
   целого эквивалента или наоборот.
 
        F$INTER (выражение)
 
        Возвращает целый эквивалент заданного выражения.
 
        F$LENGTH (строка)
 
 
 
 
                              219 
 
                        000152-01 97 04
 
 
        Возвращает длину заданной строки.
 
        F$LOCATE (подстрока, строка)
 
        Размещает символ или символьную подстроку  в  пределах
 
   строки и возвращает его (ее) смещение в пределах строки.
 
        F$LOGICAL (логическое-имя)
 
        Транслирует логическое имя  и  возвращает  имя  строки
 
   эквивалентности.
 
        F$MESSAGE (код-состояния)
 
        Возвращает текст сообщения, связанный с заданной вели-
 
   чиной кода состояния системы.
 
        F$MODE()
 
        Указывает режим, в котором выполнятся процесс.
 
        F$PARSE(спецификация-файла,  [,  спецификация   -   по
 
   умолчанию] [, связанная-спецификация] [, поле])
 
        Вызывает подпрограмму обслуживания СУД-32  $PARSE  для
 
   грамматического разбора спецификации файла и возврата  либо
 
   расширенной спецификации файла, либо  спецификации  опреде-
 
   ленного файла, который запрашивает пользователь.
 
        F$PID (символ-контекста)
 
        Для каждого вызова возвращает следующий номер  иденти-
 
   фикации процесса (PID) в последовательности.
 
        F$PRIVILEGE (состояние-привилегии)
 
        Возвращает величину "TRUE" (истина) или "FALSE" (ложь)
 
   в зависимости от того, согласуются ли  привилегии  текущего
 
   процесса  пользователя  с  привилегиями,  перечисленными  в
 
   аргументе.
 
        F$PROCESS()
 
        Возвращает строку имени текущего процесса.
 
        F$SEARCH (спецификация-файла) [, идентификатор-потока)
 
 
 
 
                              220 
 
                        000152-01 97 04
 
 
        Вызывает подпрограмму обслуживания СУД-32 $SEARCH  для
 
   поиска файла каталога и возвращает полную спецификацию фай-
 
   ла для имени файла пользователя.
 
        F$SETPRV (состояние-привилегии)
 
        Устанавливает заданные привилегии и  возвращает  пред-
 
   шествующее состояние этих привилегий для текущего процесса.
 
        F$STRING (выражение)
 
        Возвращает строку результата заданного выражения.
 
        F$TIME()
 
        Возвращает текущие дату и время  в  формате  дд-мм-ггг
 
   чч:мм:сс.тт.
 
        F$TRILNM (логическое-имя [,  таблица]  [,  индекс]  [,
 
   режим] [, регистр] [, элемент])
 
        Транслирует логическое имя и возвращает  эквивалентную
 
   строку имени или требуемые атрибуты логического имени.
 
        F$TYPE (символьное - имя)
 
        Определяет тип данных символа.
 
        F$USER()
 
        Возвращает  текущий  код  идентификации   пользователя
 
   (UIC).
 
        F$VERIFY ([величина-процедуры] [величина-образа])
 
        Возвращает целую 1, если установлена проверка  команд-
 
   ной процедуры; возвращает целый 0, если проверка  командной
 
   процедуры выключена. Функция F$VERIFY также может  устанав-
 
   ливать новые состояния проверки.
 
 
 
 
 
 
 
 
 
 
 
 
                              221 
 
                        000152-01 97 04
 
 
                                                  Приложение 3
 
 
 
 
 
                      Краткий список команд
 
 
 
 
        В таблице перечислены команды, которые  часто  исполь-
 
   зуются в командных процедурах. В этот список также включены
 
   команды, которые используются для управления интерактивными
 
   командными процедурами и пакетными заданиями.
 
 
 
                                                    Таблица 1
 
     Команды DCL, часто используемые в командных процедурах
 
   ----------------------------------------------------------
   Имя команды   !                Функция команды
   ----------------------------------------------------------
                 !
   @             !   Выполняет командную процедуру
                 !
   =             !   Назначение  символа;  приравнивает   имя
                 ! локального  символа  целому выражению  или
                 ! выражению типа символьной строки
                 !
   ==            !   Назначение  символа;  приравнивает   имя
                 ! глобального  символа   целому    выражению
                 ! или выражению типа символьной строки
                 !
   :=            !   Назначение  символа;  приравнивает   имя
                 ! локального  символа  символьной    строке.
                 ! обычно   используется   для  приравнивания
                 ! символа  командной   строке без заключения
                 ! строки в знаки кавычек
                 !
   :==           !   Назначение   символа;  приравнивает  имя
                 ! глобального  символа  символьной   строке.
                 ! обычно  используется  для    приравнивания
                 ! символа  командной   строке без заключения
                 ! строки в знаки кавычек
                 !
   ASSIGN        !   Приравнивает    логическое   имя   имени
                 ! физического  устройства, полной специфика-
                 ! ции файла или  другому логическому  имени,
                 ! и помещает имя  строки  эквивалентности  в
                 ! таблицу логических имен  процесса,  группы
                 ! процесса, группы или системы
                 !
   CLOSE         !   Закрывает  файл, который был открыт  для
 
 
                              222 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 1
   ----------------------------------------------------------
   Имя команды   !                Функция команды
   ----------------------------------------------------------
                 ! ввода  или вывода с помощью команды  OPEN,
                 ! и отменяет  назначение логического  имени,
                 ! заданного, когда файл был открыт
                 !
   CONTINUE      !   Возобновляет  выполнение командной  про-
                 ! цедуры  или образа, которое было  прервано
                 ! по вводу CTRL/Y или CTRL/C
                 !
   DEASSIGN      !   Отменяет назначение  логического  имени,
                 ! выполненное  с  помощью  команд  ALLOCATE,
                 ! ASSIGN или DEFINE
                 !
   DECK          !   Помечает  начало  потока входных  данных
                 ! потока для   командной   процедуры,  когда
                 ! первый   непустой  символ  в  любой записи
                 ! данных во входном   потоке является знаком
                 ! ($)
                 !
   DEFINE        !   Приравнивает   логическое   имя    имени
                 ! физического  устройства,  полной  специфи-
                 ! кации файла или другому  логическому имени
                 ! и помещает  имя   строки эквивалентности в
                 ! таблицу  логических  имен  процесса группы
                 ! или систем
                 !
   DELETE/ENTRY  !   Удаляет один или большее число входов из
                 ! очереди  к  печатающему  устройству или из
                 ! очереди пакетных заданий
                 !
   DELETE/SYMBOL !   Удаляет  определение  символа из таблицы
                 ! локальных символов или из таблицы глобаль-
                 ! ных символов
                 !
   EOD           !   Помечает конец потока входных данных для
                 ! командной процедуры
                 !
   EXIT          !   Завершает  обработку  текущей  командной
                 ! процедуры
                 !
   GOTO          !   Передает управление на помеченный опера-
                 ! тор в командной процедуре
                 !
   IF...THEN     !   Проверяет величину выражения и выполняет
                 ! команду,  если результат проверки соответ-
                 ! ствует истине
                 !
   INQUIRE       !   Запрашивает   интерактивное   назначение
                 ! величины для  локального  или  глобального
                 ! символа  во  время  выполнения   командной
                 ! процедуры
                 !
   ON...THEN     !   Определяет направления действий по умол-
                 ! чанию, когда команда  или  программа в ко-
                 ! мандной процедуре (1) встречает ошибки или
                 ! (2) прерывается в результате ввода CTRL/Y
 
 
                              223 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 1
   ----------------------------------------------------------
   Имя команды   !                Функция команды
   ----------------------------------------------------------
                 !
   OPEN          !   Открывает файл для чтения или записи
                 !
   PRINT         !   Устанавливает в очередь один или большее
                 ! число  файлов  для  распечатки   либо   на
                 ! системном печатающем устройстве по умолча-
                 ! нию, либо на заданном печатающем устройст-
                 ! ве
                 !
   READ          !   Выполняет   чтение    одной   записи  из
                 ! заданного   входного   файла  и  назначает
                 ! содержимое  записи  заданному  логическому
                 ! имени
                 !
   SET CONTROL   !   Разрешает  прерывания,  вызванные вводом
                 ! CTRL/Y или CTRL/T
                 !
   SET NOCONTROL !   Блокирует  прерывания,  вызванные вводом
                 ! CTRL/Y или CTRL/T
                 !
   SET NOON      !   Запрещает интерпретатору  команд  прове-
                 ! рять  ошибки, возникающие  при  выполнении
                 ! команд
                 !
   SET NOVERIFY  !   Защищает  командные  строки  в командной
                 ! процедуре от отображения на  терминале или
                 ! распечатки   в   файле  журнала  пакетного
                 ! задания
                 !
   SET ON        !   Заставляет интерпретатор  команд  прове-
                 ! верять ошибки выполнения команд
                 !
       SET       !   Устанавливает   временный   интервал,  с
   OUTPUT_RATE   ! которым   выводные  данные  записываются в
                 ! файл журнала пакетного задания
                 !
       SET       !   Устанавливает проверку величины для пов-
   RESTART_VALUE ! торного запуска секций пакетного   задания
                 !
       SET       !   Изменяет  текущее состояние или атрибуты
   QUEUE/ENTRY   ! файла,  который  установлен  в очередь для
                 ! распечатки или выполнения  пакетного зада-
                 ! ния, но еще не обработан
                 !
   SET VERIFY    !   Вызывает отображение  на  терминале  ко-
                 ! мандных  строк   командной  процедуры  или
                 ! их  распечатку  в  файле журнала пакетного
                 ! задания
                 !
   SHOW QUEUE    !   Отображает  текущее  состояние  входов в
                 ! очередях  вывода  на печать и/или пакетных
                 ! заданий
                 !
   STOP/ABORT    !   Аварийно завершает  задание, которое уже
                 ! выводится на печать
 
 
                              224 
 
                        000152-01 97 04
 
 
                                          Продолжение табл. 1
   ----------------------------------------------------------
   Имя команды   !                Функция команды
   ----------------------------------------------------------
                 !
   STOP/ENTRY    !   Удаляет вход из очереди пакетных заданий
                 ! во время его прогона
                 !
   STOP/REQUEUE  !   Останавливает распечатку задания,  кото-
                 ! рое уже выводится  на  печать, и  помещает
                 ! это задание в конец выходной очереди
                 !
   SUBMIT        !   Вводит  одну или большее число командных
                 ! процедур в очередь пакетных заданий
                 !
   SYNCHRONIZE   !   Помещает  процесс,  сформировавший   эту
                 ! команду, в состояние ожидания до тех  пор,
                 ! пока заданное пакетное  задание не  завер-
                 ! шит выполнение
                 !
   WAIT          !   Помещает  текущий  процесс  в  состояние
                 ! ожидания  до  тех  пор,  пока  не  пройдет
                 ! заданный период времени
                 !
   WRITE         !   Выполняет запись данных в заданный выхо-
                 ! дной файл.
                 !
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              225
 
                        000152-01 97 04
 
 
                 Перечень ссылочных документов
 
 
   1. Операционная система МОС ВП. Подсистема управления.
 
      Диалоговый командный язык. Руководство пользователя
 
      00152-01 92 19-3
 
   2. Операционная система МОС ВП. Подсистема системного
 
      программиста. Управление системой. Справочный материал
 
      00152-01 97 10
 
   3. Операционная система МОС ВП. Подсистема управления.
                         
      Основы интерактивной работы в системе. Справочный
 
      материал 00152-01 97 03
 
 
 
 
 
 
 
                  
 
 
 
                              225K 
 
                        000152-01 97 04
 
 
 
 
 
                  Перечень ссылочных документов
 
 
 
 
   1. Операционная система МОС ВП. Подсистема управления.
 
      Диалоговый командный язык. Руководство пользователя
 
      2б.00152-01 92 19-3
 
   2. Операционная система МОС ВП. Подсистема системного
 
      программиста. Управление системой. Справочный материал
 
      2б.00152-01 97 10
 
   3. Операционная система МОС ВП. Подсистема управления.
 
      Основы интерактивной работы в системе. Справочный
 
      материал 2б.00152-01 97 03
 
 
 
 
 
 
 
 
 
 
 
 
 
   
                       - 226K -  
  
                    00152-01 97 04  
                                                      
   ------------------------------------------------------------
   I                                                          I
   I                  Лист регистрации изменений              I
   I                                                          I
   I----------------------------------------------------------I
   IНомера листов (страниц)IВсего IN     IВходящий IПодп.IДатаI
   I-----------------------IлистовIдоку- IN сопро- I     I    I
   IИ IИз- IЗа- IНо- IАнну-I(стра-Iмента Iводитель-I     I    I
   Iз Iме- Iме- Iвых Iлиро-Iниц)  I      Iного до- I     I    I
   Iм Iнен-Iнен-I    Iван- Iв до- I      Iкум. и   I     I    I
   I. Iных Iных I    Iных  Iкум.  I      Iдата     I     I    I
   I----------------------------------------------------------I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
   I  I    I    I    I     I      I      I         I     I    I
 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!