[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

15 DCLによるプログラミング:コマンド・プロシージャの概要

コマンド・プロシージャとは,DCLコマンドと,DCLコマンドで使用されるデータ行が格納されたファイルです。 本章では,次のことについて説明します。

その他の情報については,次のものを参照してください。

DCLコマンド・プロシージャには,次の2種類があります。

15.1 コマンド・プロシージャを作成するための基礎的な説明

コマンド・プロシージャを作成するには,次の2種類の方法があります。

作成するファイルには,コマンド行,ラベル,コメント,条件文,変数を格納できます。

15.1.1 省略時のファイル・タイプ

コマンド・プロシージャの省略時のファイル・タイプは.COMです。コマンド・ プロシージャの名前を指定するときに,ファイル・タイプとして.COM を指定した場合には,ファイル名を指定するだけで,コマンド・プロシージャを実行できます。SUBMIT コマンドとプロシージャ実行(@)コマンドでは, 特に指定した場合を除き,ファイル・タイプは.COMであるものと解釈されます。

15.1.2 コマンドの作成

コマンド・プロシージャにコマンドを登録する場合には,次のことに注意してください。

15.1.3 コマンド行の作成

コマンド行を作成する場合には,次のことに注意してください。

先頭にドル記号が指定されていないコマンド行も,DCLで正しく解釈されると 思われますが,なるべくDCLコマンド行の先頭にはドル記号を指定してください。

15.2 コマンド行でのラベルの使用

DCLコマンド・プロシージャでは,ループ,コード・セクション,サブルーチンの先頭をマークするためにラベルを使用します。 ラベルを使用する場合には, 次の規則に注意してください。

15.2.1 ローカル・シンボル・テーブル内のラベル

コマンド・インタプリタがラベルを検出すると,ローカル・シンボル・テーブルの特殊なセクションにそのラベルが登録されます。 ラベルのために使用できる容量は制限されています。 コマンド・プロシージャで多くのシンボルを使用し, 多くのラベルが含まれている場合には,コマンド・インタプリタはシンボル・ テーブル空間をすべて使用してしまう可能性があり, エラー・メッセージが表示されます。この場合には,プロシージャにDELETE/SYMBOL コマンドを指定して,不要になったシンボルを削除します( ただし,ラベルを削除することはできません)。

15.2.2 重複するラベル

コマンド・プロシージャで同じラベルを2回以上使用する場合には,ローカル・ シンボル・テーブルの既存の定義は新しい定義に置き換えられます。

重複するラベルが存在する場合には,GOTOコマンドは,DCLが最後に処理したラベルに制御を渡します。 また,GOTOコマンドは重複するラベルを処理するときに, 次の規則も使用します。

15.3 コマンド・プロシージャでのコメントの使用

コマンド・プロシージャを作成する場合には,なるべくコメントを指定してください。 コマンド・プロシージャを更新したり,問題を解決するときに, コメントが指定されていると役立ちます。コメントは次の方法で使用できます。

コマンド・プロシージャにコメントを指定する場合には,次の規則が適用されます。

15.4 コマンド・プロシージャの作成方法

コマンド・プロシージャの作成を開始する前に,コマンド・プロシージャが実行するタスクを会話形式で実行します。 必要なコマンドを入力し,使用される変数と条件, および発生する会話を記録します。

これ以降の節では,簡単なコマンド・プロシージャの作成方法を説明します。 これ以降で使用する例は,CLEANUP.COMというコマンド・プロシージャです。 このコマンド・プロシージャは,ディレクトリを整理するために使用します。

定義

15.5 コマンド・プロシージャの作成手順

コマンド・プロシージャを作成するには,次の手順を実行します。

手順 操作
1 コマンド・プロシージャを設計する。
2 変数を割り当て,条件をテストする。
3 ループを追加する。
4 コマンド・プロシージャを終了する。
5 プログラム・ロジックをテストおよびデバッグする。
6 クリーアップ・タスクを追加する。
7 プロシージャを完成する。

15.5.1 手順1:コマンド・プロシージャを設計する

コマンド・プロシージャを設計するには,次の操作を実行します。

手順 操作
1 プロシージャが実行するタスクを決定する。
2 コマンド・ プロシージャが使用する変数と,その変数のロード方法を判断する。
3 コマンド・ プロシージャが必要とする条件と,条件をテストする方法を判断する。
4 コマンド・プロシージャを終了する方法を決定する。

クリーンアップ操作で一般に実行される特定のコマンドがあります。次の表は, これらのコマンドと,そのコマンドが実行するタスクを示しています。

コマンド 実行するタスク
DIRECTORY カレント・ディレクトリの内容を表示する。
TYPE filespec ファイルを表示する。
PURGE filespec ファイルをパージする。
DELETE filespec ファイルを削除する。
COPY filespec new- filespec ファイルをコピーする。

変数

タスクを実行するときに変化するデータは変数です。ディレクトリにファイルを作成したり, ファイルを削除する場合には,ディレクトリを整理するたびに, ファイル名が異なります。したがって,CLEANUP.COMでファイル名は変数です。

条件

コマンド・プロシージャを実行するたびにテストしなければならないコマンドは, 条件であると考えられます。CLEANUP.COMのコマンドは,実行しなければならない操作に応じて, 一部またはすべてが実行されるため,各コマンドは条件です。

設計の決定

CLEANUP.COMコマンド・プロシージャで使用する変数と条件を判断した後, 変数のロード方法,条件のテスト方法,コマンド・プロシージャの終了方法を判断しなければなりません。CLEANUP.COM コマンド・プロシージャの場合には, 次の判断を下しました。

タスク 実現方法
変数のロード コマンド・プロシージャはターミナルからファイル名を入手する。
条件のテスト コマンド・プロシージャ:

  • ターミナルからコマンド名を入手し,コマンド名をもとにして適切な文を実行する。

  • DELETEコマンドとDIRECTORYコマンドを区別するために,各コマンド名の最初の2 文字を確実に読み込む。
ループの終了 ループを終了するには,EXIT コマンドを入力しなければならない。

コマンド・プロシージャを理解しやすく,また管理しやすくするには,プロシージャが最初のコマンドから最後のコマンドへと順に実行されるように, 文を作成しなければなりません。

15.5.2 手順2:変数を割り当て,条件をテストする

値を変数に割り当てるには,多くの方法があります。この節では, INQUIREコマンドの使い方について説明します。他の方法については,第16章を参照してください。

値を変数に割り当て,条件をテストするには,次の操作を実行します。

手順 操作
1 INQUIREコマンドを使用して,値を変数に割り当てる。
2 実行しなければならない処理を判断する。
3 IF文とTHEN文を使用して条件をテストする。
4 プログラム・スタブを作成し,コマンドのプレースホルダとしてコマンド・ プロシージャに挿入する。
5 必要に応じてエラー・メッセージを作成する。

15.5.2.1 INQUIREコマンドの使用

INQUIREコマンドは,値を要求するプロンプトを表示し,ターミナルから値を読み込み, その値をシンボルに割り当てます。

省略時の設定では,INQUIREコマンドは次の操作を実行します。

次の例は,コマンド・プロシージャCLEANUP.COMの中でコマンド名の入力を求めるコマンドです。INQUIRE コマンドは入力された値をシンボルCOMMAND に割り当てます。

     $ INQUIRE COMMAND-
       "Enter command (DELETE, DIRECTORY, PRINT, PURGE, TYPE)"

15.5.2.2 リテラル文字の保存

INQUIREコマンドを使用するときに,小文字や複数のスペースとタブを保存するには, 応答を引用符(" ")で囲みます。応答の内部で引用符を使用するときは, 引用符で囲んだテキストを引用符で囲みます(""text"")。

15.5.2.3 IFとTHENを使用した条件のテスト

INQUIREコマンドで変数を要求するプロンプトを表示した後,どのような処理を実行するかを判断する文をコマンド・ プロシージャに指定しなければなりません。 たとえば,どのコマンドを実行するかを判断するには,ユーザが入力したコマンドを可能な各コマンドに対してチェックする文を, コマンド・プロシージャに指定しなければなりません。

条件が真であるかどうかをテストするには,IFコマンドとTHENコマンドを使用します。 次の表は,CLEANUP.COMでチェックしなければならない可能性を示しています。

場合 結果
一致するものが見つかった場合 コマンドを実行する
一致するものが見つからない場合 次のコマンドに進む
有効なすべてのコマンドをチェックした後, 一致するものが見つからない場合 エラー・メッセージを出力する

15.5.2.4 プログラム・スタブの作成

プログラム・スタブとは,設計をテストするときに,プロシージャで使用する一時的なコード・ セクションです。通常,プログラム・ スタブは,そのスタブのかわりに実際に使用される機能を示すメッセージを出力します。 全体の設計が正しく動作することを確認した後は,各スタブを正しいコーディングに置き換えます。

例:変数の割り当てと条件のテスト

次の例では,変数の割り当てと条件のテスト方法を示しています。

     $ INQUIRE COMMAND-
       "Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
     $ IF COMMAND .EQS. "EXIT" THEN EXIT
     $!
     $! Execute if user entered DELETE
     $ DELETE:
     $    IF COMMAND .NES "DELETE" THEN GOTO DIRECTORY         【1】 【2】
     $    WRITE SYS$OUTPUT "This is the DELETE section."       【3】
     $! Execute if user entered DIRECTORY
     $ DIRECTORY:                                              【4】
     $    IF COMMAND .NES "DIRECTORY" THEN GOTO PRINT
     $    WRITE SYS$OUTPUT "This is the DIRECTORY section."
        .
        .
        .
     $! Execute if user entered TYPE
     $ TYPE:
     $    IF COMMAND .NES "TYPE" THEN GOTO ERROR               【5】
     $    WRITE SYS$OUTPUT "This is the TYPE section."
     $!
     $ ERROR:
     $    WRITE SYS$OUTPUT "You have entered an invalid command." 【6】
     $!
     $ EXIT

例を確認するときは,次のことに注意してください。

【1】
このIF文は,ユーザが入力したコマンド(COMMAND)が "DELETE"に等しいかどうかをテストする。COMMAND がDELETEに等しい場合には,コマンド・ プロシージャは次のコマンドを実行する。
【2】
この文にはGOTO コマンドも指定されている。GOTOコマンドは,実行の流れをプロシージャ内のラベルに変更するために使用する。 この場合,COMMAND がDELETEに等しくない場合には,プロシージャはDIRECTORYラベルに進む。
【3】
この文はプログラム・スタブである。コマンド・プロシージャのロジックのテストが終了した後, この行はDELETE操作にとって必要な実際のコマンドに置き換えられる。
【4】
これはDIRECTORY サブルーチンのラベルである。各コマンド・ブロックを識別するラベルは, オプション・リストのコマンドと同じである。このため,GOTO文でシンボルCOMMAND を使用できる(これはユーザの要求に等しく定義されている) 。
【5】
このIF文は,"TYPE"コマンドが入力されたかどうかをテストする。"TYPE" が入力された場合には,プロシージャは"This is the TYPE section."を出力する。しかし,これはテストする最後のコマンドであるため, 入力されたコマンドが"TYPE"でない場合には,プログラムはエラー・ メッセージを表示する。
【6】
すべてのコマンドをテストした後, 正しいコマンド名が見つからない場合には,プログラムは"You have entered an invalid command."を出力する。

15.5.3 手順3:ループを追加する

ループとは,条件が満足されるまで繰り返し実行される文の集まりです。 ループは次のように機能します。

  1. ユーザ入力から値を入手します。

  2. コマンドを処理します。

  3. ユーザがコマンド・プロシージャを終了するまで,処理を繰り返します。

ループを作成するには,次の手順を実行します。

手順 操作
1 ループの先頭にラベルを付ける。
2 変数を調べて,ループの中のコマンドを実行する必要があるかどうかを判別する。
3 ループを実行する必要がない場合には,ループの終わりに進む。
4 ループを実行する必要がある場合には, ループ本体の中のコマンドを実行してから, ループの始めに戻る。
5 ループを終了する。

次の例では,CLEANUP.COMコマンド・プロシージャでのループの使い方を示しています。

     $ GET_COM_LOOP:
     $     INQUIRE COMMAND-
     $     "Enter command (DELETE, DIRECTORY. EXIT, PRINT, PURGE, TYPE)"
     $     IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
     $!
     $! Execute if user entered DELETE
     $ DELETE:
     $     IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
     $     WRITE SYS$OUTPUT "This is the DELETE section."
     $     GOTO GET_COM_LOOP
        .
        .
        .
     $ END_LOOP:
     $     WRITE SYS$OUTPUT "Directory ''F$DIRECTORY()' has been cleaned"
     $ EXIT

コマンドを実行した後,ユーザがEXITコマンドを入力するまで,制御はGET_COM_LOOP ラベルに戻されます。EXITコマンドが入力されると,プロシージャはディレクトリが整理されたことを示すメッセージを出力します。

15.5.4 手順4:コマンド・プロシージャを終了する

コマンド・プロシージャを終了するには,次の手順を実行します。

手順 操作
1 どこでコマンド・プロシージャを終了するかを判断する。
2 必要に応じてEXIT またはSTOPコマンドを指定する。

15.5.4.1 EXITコマンドの使用

コマンド・プロシージャでEXITコマンドを使用すると,次のことが可能になります。

次の例は,プロシージャの最後に指定されているエラー処理ルーチンを実行しないようにするために,EXIT コマンドを使用する方法を示しています。

        .
        .
        .
     $ EXIT ! End of normal execution path
     $ ERROR_ROUTINE
        .
        .
        .

次の例は,複数の実行パスを持つプロシージャを終了するために,EXITコマンドを使用する方法を示しています。

     $ START:
     $     IF P1 .EQS. "TAPE" .OR. P1 .EQS. "DISK" THEN GOTO 'P1'
     $     INQUIRE P1 "Enter device (TAPE or DISK)"
     $     GOTO START
     $ TAPE: !Process tape files
        .
        .
        .
     $     EXIT
     $ DISK: ! Process disk files
        .
        .
        .
     $     EXIT

各ラベル(TAPEとDISK)の後のコマンドは,プロシージャで異なるパスを与えます。DISK ラベルの前のEXITコマンドは,プロシージャがそのラベルに明示的に分岐した場合を除き,DISK ラベルの後のコマンドが実行されないようにします。

プロシージャの最後にEXITコマンドを指定する必要はありません。これは, プロシージャのエンド・オブ・ファイルにより,暗黙にEXITコマンドが実行されるからです。 しかし,なるべくEXITコマンドを指定するようにしてください。

15.5.4.2 STOPコマンドの使用

コマンド・プロシージャでSTOPコマンドを使用すると,重大なエラーが発生したときに, プロシージャを終了することができます。会話形式で実行されているコマンド・ プロシージャで STOPコマンドを使用した場合には, 制御はDCLレベルに戻されます。バッチ・モードで実行されているコマンド・ プロシージャの場合には,バッチ・ジョブが終了します。

このコマンド行は,重大なエラーが発生したときに,プロシージャを停止するように要求します。

     $ ON SEVERE_ERROR THEN STOP

15.5.5 手順5:プログラム・ロジックをテストおよびデバッグする

プログラム・スタブを使用してコードを作成した場合には,コマンド・プロシージャの全体的なロジックをテストしなければなりません。 可能性のあるすべての実行パスをテストしなければなりません。

コマンド・プロシージャをテストおよびデバッグするには,次の手順を実行します。

手順 操作
1 コマンド・プロシージャに正しい各コマンドを入力して, プログラム・ロジックをテストする。
2 誤ったコマンドを入力して,プログラム・ロジックのテストを継続する。
3 EXITコマンドを使用して,コマンド・プロシージャを終了することにより, プログラム・ロジックのテストを終了する。
4 必要な場合には,SET VERIFY,SET PREFIX,SHOW SYMBOLコマンドを使用して,プログラムをデバッグする。

次の例では,可能な各コマンドと無効なコマンドを入力および実行して, コマンド・プロシージャをテストし,最後にプロシージャを終了する方法を示しています。

     $ @CLEANUP
       Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): DELETE
       This is the DELETE section.
       Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): DIRECTORY
       This is the DIRECTORY section.
        .
        .
        .
       Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): PRINF
       You have entered an invalid command.
       Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): EXIT
     $

15.5.5.1 コマンド・プロシージャのデバッグ

次のコマンドは,コマンド・プロシージャをデバッグするのに役立ちます。

例: SET VERIFYコマンドの使用によるデバッグ

次の例では,END_LOPというラベルの綴りが誤っています。チェック機能が有効に設定されているため, エラーがどこで発生したのかを正確に判断できます。

     $ SET VERIFY
     $ @CLEAN
     $ GET_COM_LOOP:
     $    INQUIRE COMMAND -
          "Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
      Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): EXIT
     $    IF COMMAND .EQS. "EXIT" THEN GOTO END_LOP
      %DCL-W-USGOTO, target of GOTO not found -
      check spelling and presence of label

エラーを修正するには,ラベルをEND_LOOPに変更します。

例: SET PREFIXコマンドの使用によるデバッグ

次の例ではタイム・スタンプの使い方を示しています。

     $  SET VERIFY
     $  @TEST
     $  SET DEFAULT SYS$LOGIN
     $  SHOW DEFAULT
        USER$:[SMYTHE]
     $  SET PREFIX "(!5%T) "
     $  @TEST
      (17:52)  $ SET DEFAULT SYS$LOGIN
      (17:52)  $ SHOW DEFAULT
        USER$:[SMYTHE]

例: SHOW SYMBOLコマンドの使用によるデバッグ

次の例では,SHOW SYMBOLコマンドを使用して,シンボルCOMMANDがどのように定義されているか判断する方法を示しています。

     $ SET VERIFY
     $ @CLEAN
     $ GET_COM_LOOP:
     $    INQUIRE COMMAND -
          "ENTER COMMAND (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
       ENTER COMMAND (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): EXIT
     $ SHOW SYMBOL COMMAND
      COMMAND = "EXIT"
     $    IF COMMAND .EQS. "exit" THEN GOTO END_LOOP
        .
        .
        .

SHOW SYMBOLコマンドを実行すると,シンボルCOMMANDの値が"EXIT"であることがわかります。INQUIRE コマンドは入力を大文字に自動的に変換しますが, コマンドをテストするIF文では,文字列"exit"で小文字を使用しているため,DCL は文字列が等しくないと判断します。このエラーを修正するには,IF 文に指定した,引用符で囲んだ文字列を大文字にします。文字列の残りの部分は, 大文字でも小文字でもかまいません。

15.5.5.2 実行中にチェック機能をオンにする

コマンド・プロシージャの実行中に割り込みをかけて,チェック機能を有効にすることもできます。 コマンド・プロシージャに SET VERIFYコマンドやCtrl/Y キー・シーケンスが含まれていない限り,次の操作を実行して, チェック機能を有効に設定できます。

手順 操作
1 Ctrl/Yを押して実行に割り込みをかける。
2 SET VERIFYコマンドを入力する。
3 CONTINUEコマンドを入力して, コマンド・プロシージャの実行を続行する(チェック機能を有効にした状態で) 。

15.5.6 手順6:クリーンアップ・タスクを追加する

一般に,コマンド・プロシージャを実行した結果,ユーザのプロセス状態が変化しないようにしなければなりません。 したがって,コマンド・プロシージャには, プロセスをもとの状態に戻す一連のコマンドを指定しなければなりません。 このコマンドは通常,"CLEAN_UP"というラベルの付いたサブルーチンの一部です(CLEANUP.COM の前の例と混同しないでください) 。一般的なクリーンアップ操作としては,ファイルを閉じる操作と, 省略時のデバイスおよびディレクトリをリセットする操作があります。

コマンド・プロシージャにクリーンアップ・タスクを追加するには,次の操作を実行します。

手順 操作
1 CLEAN_UPなどのラベルを使用して,クリーンアップ・ サブルーチンを開始する。
2 F$GETJPIレキシカル関数を使用して,開かれているファイルがあるかどうかテストする。
3 DELETEコマンドまたはPURGEコマンドを使用して, 一時ファイルまたは余分なファイルを削除する。
4 (デバイスやディレクトリなど)省略時の設定を変更した場合には,SET DEFAULT コマンドを使用して,元の状態に復元する。
5 クリーンアップ操作が確実に実行されるように,ON CONTROL_Y 文を指定する。

15.5.6.1 ファイルを閉じる

ファイルが開かれている場合には,プロシージャを終了する前に確実にファイルを閉じてください。 レキシカル関数F$GETJPIを使用すれば,プロセスに対して残されているオープン・ ファイル・クォータ(FILCNT)を調べることができます。FILCNT が,コマンド・プロシージャの開始時と終了時に同じである場合には, 開かれたままになっているファイルはありません。

この例では,ファイルが開かれたままになっていることをユーザに警告するために使用するコマンドを示しています。

     $ FIL_COUNT = F$GETJPI ("","FILCNT")
        .
        .
        .
     $ IF FILCNT .NE. F$GETJPI ("", "FILCNT") THEN-
       WRITE SYS$OUTPUT "WARNING -- file left open)

15.5.6.2 一時ファイルまたは余分なファイルの削除

一時ファイルを作成した場合には,それを削除します。一般に,ファイルを更新した場合には, ファイルをパージして以前のコピーを削除しなければなりません。 自分で作成していないファイルを削除する場合には,そのファイルを削除してもかまわないかどうか確認してください。 たとえば, 重要なデータが格納されているファイルを更新した場合には,バージ操作は必要に応じて省略できます。

省略時のデバイスとディレクトリのどちらか一方または両方を変更した場合には, コマンド・プロシージャを終了する前に,元の省略時の設定に戻さなければなりません。 元の省略時のディレクトリの名前をセーブするには,F$ENVIRONMENT レキシカル関数のDEFAULTキーワードを使用します。コマンド・ プロシージャの最後に,保存したデバイスとディレクトリを復元するSET DEFAULT コマンドを指定します。

この例に示したコマンド行は,デバイスとディレクトリの省略時の設定を保存し, 復元します。

     $ SAV_DEFAULT = F$ENVIRONMENT ("DEFAULT")
        .
        .
        .
     $ SET DEFAULT 'SAV_DEFAULT'

15.5.6.3 一般に変更されるプロセス属性

次の表は,一般に変更されるその他のプロセス属性,これらの属性をセーブするために使用されるレキシカル関数, 復元するために使用されるレキシカル関数またはコマンドを示しています。

属性 セーブのためのレキシカル関数 復元のためのレキシカル関数
DCLプロンプト F$ENVIRONMENT SET PROMPT
省略時の保護 F$ENVIRONMENT SET PROTECTION/DEFAULT
特権 F$SETPRV F$SETPRVまたはSET PROCESS/PRIVILEGES
制御文字 F$ENVIRONMENT SET CONTROL
検査 F$VERIFY F$VERIFY
メッセージ・ フォーマット F$ENVIRONMENT SET MESSAGE
キーの状態 F$ENVIRONMENT SET KEY

これらのレキシカル関数についての詳細は,『OpenVMS DCL Dictionary』を参照してください。

15.5.6.4 クリーンアップ操作を確実に実行するには

コマンド・プロシージャが途中で打ち切られる場合でも,クリーンアップ操作が確実に実行されるようにするには, コマンド・プロシージャの各コマンド・ レベルを次の文で開始します。

     $ ON CONTROL_Y THEN GOTO CLEANUP

ON CONTROL_Yコマンドの使用方法についての詳細は,第16章を参照してください。

15.5.7 手順7:コマンド・プロシージャを完成する

全般的な設計が正しく動作している場合には,次の操作を実行してコマンド・ プロシージャを完成します。

手順 操作
1 コマンド・プロシージャ内の最初のプログラム・ スタブをコマンドに置き換える。
2 コマンド・プロシージャをテストして,新しいコマンドが正しく機能するかどうか確認する。
3 必要に応じて,コマンド・プロシージャをデバッグする。
4 最初のプログラム・ スタブが正常に機能する場合には,次のスタブに移動する。 すべてのプログラム・スタブが置換されるまで,この操作を続行する。

例:プログラム・スタブとコマンドの置換

次の例は,CLEANUP.COMのTYPEセクションのコードを示しています。

     $! Execute if user entered TYPE
     $! TYPE:
     $      IF COMMAND .NES. "TYPE THEN GOTO ERROR
     $      INQUIRE FILE "File to type"
     $      TYPE 'FILE'
     $      GOTO GET_COM_LOOP

既存のコードは次のように置き換えられます。

     $ WRITE SYS$OUTPUT "This is the TYPE section."

例: CLEANUP.COMコマンド・プロシージャ

次の例は,完成したCLEANUP.COMコマンド・プロシージャを示しています。

     $ GET_COM_LOOP:
     $    INQUIRE COMMAND -
          "Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
     $    IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
     $!

     $!Execute if user entered DELETE
     $ DELETE:
     $       IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
     $       INQUIRE FILE "File to delete? "
     $       DELETE 'FILE'
     $       GOTO GET_COM_LOOP
     $!

     $!Execute if user entered DIRECTORY
     $ DIRECTORY:
     $       IF COMMAND .NES. "DIRECTORY" THEN GOTO PRINT
     $       DIRECTORY
     $       GOTO GET_COM_LOOP
     $!

     $!Execute if user entered PRINT
     $ PRINT:
     $       IF COMMAND .NES. "PRINT" THEN GOTO PURGE
     $       INQUIRE FILE "File to print? "
     $       PRINT SYS$OUTPUT 'FILE'
     $       GOTO GET_COM_LOOP
     $!

     $!Execute if user entered PURGE
     $ PURGE:
     $       IF COMMAND .NES. "PURGE" THEN GOTO TYPE
     $       PURGE
     $       GOTO GET_COM_LOOP
     $!

     $!Execute if user entered TYPE
     $ TYPE:
     $       IF COMMAND .NES. "TYPE" THEN GOTO ERROR
     $       INQUIRE FILE "File to type"
     $       TYPE 'FILE'
     $       GOTO GET_COM_LOOP
     $!

     $ ERROR:
     $       WRITE SYS$OUTPUT "You entered an invalid command."
     $       GOTO GET_COM_LOOP
     $!
     $ END_LOOP:
     $ WRITE SYS$OUTPUT "Directory ''F$DIRECTORY()' has been cleaned."
     $
     $ EXIT

15.6 コマンド・プロシージャの実行

コマンド・プロシージャを動作させるには,実行しなければなりません。 コマンド・プロシージャは次の方法で実行できます。

この節では,これらの各方法について説明します。

15.6.1 他のコマンド・プロシージャの内部からのコマンド・ プロシージャの実行

プロシージャ実行コマンド(@)を使用すれば,別のコマンド・プロシージャの内部からコマンド・ プロシージャを実行できます。

次のコマンド・プロシージャWRITEDATE.COMは,コマンド・プロシージャGETDATE.COM を起動します。

     $! WRITEDATE.COM
     $!
     $ INQUIRE TIME "What is the current time in hh:mm format?"
     $ @GETDATE [JONES.COM]GETDATE.COM

15.6.2 リモート・ノードでのコマンド・プロシージャの実行

TYPEコマンドを使用すると,リモート・ノードの別のアカウントのトップ・ レベル・ディレクトリでコマンド・プロシージャを実行できます。次の操作を実行するコマンド・ プロシージャを実行できます。

TYPEコマンドの後にアクセス制御文字列を入力します。次の形式を使用してください。

$ TYPE nodename"username password"::"TASK=command_procedure"

usernameおよびpasswordという変数は,リモート・ノードのアカウントのユーザ名とパスワードです。

このコマンド・プロシージャは,コマンド・プロシージャが存在するリモート・ ノードにログインしているユーザを表示します。

     $!SHOWUSERS.COM
     $!
     $ IF F$MODE() .EQS. "NETWORK" THEN DEFINE/USER SYS$OUTPUT SYS$NET
     $ SHOW USERS

次の例では,SHOWUSERS.COMはノードORIOLEのBIRDのアカウントのトップ・ レベル・ディレクトリに格納されており,パスワードはBOULDER です。SHOWUSERS.COMは,リモート・ノードORIOLEで DCLコマンドSHOW USERSを実行します。TYPEコマンドは,SHOWUSERS.COMからの出力をローカル・ ノード,つまりtypeコマンドを入力したターミナルに表示します。

     $ TYPE ORIOLE"BIRD BOULDER"::"TASK=SHOWUSERS"

                  OpenVMS User Processes at 11-DEC-1998 17:20:13.30
         Total number of users = 4, number of processes = 4

      Username     Node           Interactive  Subprocess   Batch
      FLICKER      AUTOMA                 2         1
      ROBIN        FABLES                 1         2        1
      DOVE         MURMUR                 1
      DUCK         FABLES                 1         1

15.6.2.1 セキュリティに関する注意

TYPEコマンドとアクセス制御文字列を入力すると,ターミナルにパスワードが表示されます。 第18章の説明に従って, セキュリティに関する適切な予防措置をとってください。

15.6.3 DCL修飾子またはパラメータを指定したコマンド・ プロシージャの実行

DCLコマンドのパラメータまたは修飾子を指定するコマンド・プロシージャを作成できます。 この種のコマンド・プロシージャは,1つ以上のコマンドで特定のパラメータまたは修飾子の組み合わせを頻繁に使用するときに便利です。

コマンド行で修飾子やパラメータを指定する場所に,プロシージャ実行コマンド(@) を入力することができます。

このコマンド・プロシージャを使用すると,LINKコマンドに対する修飾子を入力できます。

     $! This command procedure contains command
     $! qualifiers for the LINK command.
     $!
     /DEBUG/SYMBOL_TABLE/MAP/FULL/CROSS_REFERENCE

このコマンド行は,DEFLINK.COMに指定された修飾子を使用して, SYNAPSE.OBJという名前のオブジェクトをリンクします。

     $ LINK SYNAPSE@DEFLINK

このコマンド・プロシージャは,DCLコマンドに対するパラメータCHAP1.TXT ,CHAP2.TXT,CHAP3.TXTを入力するために使用できます。

     $! PARAM.COM
     $! This command procedure contains a list of
     $! parameters that can be used with commands.
     $!
     CHAP1, CHAP2, CHAP3

このコマンド行は,パラメータ・リストのかわりにコマンド・プロシージャPARAM を指定します。次の例では,パラメータはPARAM.COMに指定されているファイル名です。

     $ DIRECTORY/SIZE @PARAM


注意
実行プロシージャ・コマンド(@) を実行すると,指定したファイル全体がDCLのコマンド入力先とされます。

15.6.3.1 制限事項

コマンド・プロシージャを実行する場合には,次の制限事項があります。

15.6.4 会話形式でのコマンド・プロシージャの実行

会話形式でコマンド・プロシージャを実行するには,コマンド・プロシージャ名の前にプロシージャ実行コマンド(@) タイプして入力します。

このコマンドは,WORKDISK:ディスクの[MAINT.PROCEDURES]ディレクトリのプロシージャSETD.COM を実行します。

     $ @WORKDISK:[MAINT.PROCEDURES]SETD <Return>

長いコマンド行を表すためにシンボル名を定義できます。定義したシンボルを使用して, コマンド・プロシージャを実行できます。

シンボルを使用して上記例のコマンド・プロシージャを実行するには,ログイン・ コマンド・プロシージャに次のコマンド行を指定しておきます。

     $ SETD == "@WORKDISK:[MAINT.PROCEDURES]SETD"

ログイン後,次のようにシンボル名を入力すれば,SETD.COMプロシージャを実行することができます。

     $ SETD <Return>

省略時の設定では,コマンド・プロシージャを会話形式で実行する場合, オペレーティング・システムは出力をターミナルに表示します。しかし, 実行コマンドに対して/OUTPUT修飾子を指定すれば,出力をファイルにリダイレクトできます。

コマンド・プロシージャの出力をファイルにリダイレクトする場合には, プロシージャはエラー・メッセージをターミナルに送信し,さらに,出力を受信しているファイルにもエラー・ メッセージを送信します。

このコマンド・プロシージャは,SETD.COMからの出力を,ターミナルではなく, ファイルRESULTS.TXTに書き込みます。

     $ @SETD/OUTPUT=RESULTS.TXT

/OUTPUT修飾子は,コマンド・プロシージャ名のすぐ後に指定しなければならず, 修飾子とプロシージャ名の間にスペースを指定することはできません。 この制限事項が守られないと,DCLは修飾子を,プロシージャに渡すパラメータとして解釈します。

15.6.5 バッチ・ジョブとしてのコマンド・プロシージャの実行

長い処理時間を必要とするコマンド・プロシージャを使用する場合(たとえば, 大きいプログラムをコンパイルしたりアセンブルする場合)には, これらのプロシージャをバッチ・ジョブとして実行すれば,ターミナルを引き続き会話形式で使用することができます。

コマンド・プロシージャをバッチ・モードで実行するには,DCLコマンドSUBMIT を入力して,コマンド・プロシージャをバッチ・キュー(実行を待っているバッチ・ ジョブのリスト)に登録します。ジョブをキューに登録すると, ジョブは省略時のバッチ・ジョブSYS$BATCHに登録され,実行を待っているジョブのキューの最後に追加されます。 前に登録されていたジョブが終了すると, 新たに登録したジョブが実行されます。OpenVMSシステムでは, 同時に実行できるバッチ・ジョブの数は,システム管理者がバッチ・ ジョブを作成するときに指定します。

次の例では,JOB1.COMという名前のコマンド・プロシージャの実行方法を示しています。SUBMIT コマンドは省略時のファイル・タイプ.COMを使用します。 したがって,コマンド・プロシージャのファイル・タイプが.COMである場合には, ファイル・タイプを入力する必要はありません。

     $ SUBMIT JOB1
     Job JOB1 (queue SYS$BATCH, entry 651, started on SYS$BATCH))

15.6.5.1 リモート・バッチ・ジョブ

システムがネットワークの一部として接続されている場合には,コマンド・ プロシージャをリモート・ノードにバッチ・ジョブとして登録できます。 このようにして使用するコマンド・プロシージャでは,ローカル・ファイルの場合と同じコマンドおよび修飾子を使用して, リモート・ノードのファイルを開いたり, 閉じたりするDCLコマンドや,これらのファイルのレコードを読み込んだり, 書き込むコマンドを使用できます。

15.6.5.2 バッチ・ジョブの再起動

省略時の設定では,ジョブが終了するためにシステムに障害が発生した場合には, バッチ・ジョブは最初の行から再実行されます。しかし,コマンド・ プロシージャで次のシンボルを使用すれば,別の場所から再起動することを指定できます。

$RESTARTとBATCH$RESTARTの使用

次の操作手順は,$RESTARTシンボルとBATCH$RESTARTシンボルの使用方法を示しています。

手順 操作
1 プロシージャの可能な各開始点の先頭にラベルを指定する。
2 各セクションの最初の処理として,SET RESTART_VALUE コマンドを使用して, BATCH$RESTARTの値をラベルに等しく設定する。
3 プロシージャを開始するときに$RESTARTをテストする。
4 $RESTARTが真の場合には,BATCH$RESTART を分岐先ラベルとして使用して,GOTO文を実行する。

このコマンド・プロシージャは,ライブラリから多くのモジュールを取り出し, それらのモジュールを連結し,作成されたファイルをソートします。

     $! SORT_MODULES.COM
     !
     $! Set default to the directory containing
     $! the library whose modules are to be sorted
     $ SET DEFAULT WORKDISK:[ACCOUNTS.DATA83]
     $!

     $! Check for restarting
     $ IF $RESTART THEN GOTO "BATCH$RESTART"
     $!

     $ EXTRACT_LIBRARIES:
     $ SET RESTART_VALUE=EXTRACT_LIBRARIES
        .
        .
        .
     $ CONCATENATE_LIBRARIES:
     $ SET RESTART_VALUE=CONCATENATE_LIBRARIES
        .
        .
        .
     $ SORT_FILE:
     $ SET RESTART_VALUE=SORT_FILE
        .
        .
        .
     $ EXIT

このコマンド・プロシージャが途中で打ち切られた場合には, BATCH$RESTARTの値に応じて,ファイルの先頭から再実行されるか, CONCATENATE_LIBRARIESというラベルの付いた文から再実行されるか, SORT_FILEというラベルの付いた文から再実行されます。多くの独立したモジュールを取り出しているため, 各抽出操作は別々のセクションにすることができます。

15.6.6 ディスクおよびテープ・ボリュームでのコマンド・ プロシージャの実行

これ以降の節では,ディスクおよびテープ・ボリューム上でコマンド・プロシージャを実行する方法を説明します。

15.6.6.1 個人用ディスク・ボリュームでの実行

SUBMITコマンドを使用してコマンド・プロシージャをキューに登録する場合には, 割り当てられているデバイス上のファイルにアクセスすることができません。 しかし,/SHARE修飾子を使用してボリュームがマウントされている場合には, 個人用ディスク・ボリュームに存在するコマンド・プロシージャを実行できます。

15.6.6.2 テープ・ボリューム上での実行

次の場合には,テープ・ボリュームに存在するコマンド・プロシージャを実行できます。

上記のいずれかの条件が満足される場合には,次の操作により,コマンド・ プロシージャを実行できます。

手順 操作
1. コマンド・プロシージャを共用ディスク・ボリュームにコピーする。
2. コマンド・プロシージャを共用ディスク・ボリュームで実行する。

15.7 コマンド・プロシージャの終了と割り込み

この節で説明する方法を使用してコマンド・プロシージャを終了する場合には, コマンド・レベルについて理解しておかなければなりません。

コマンド・レベルとは,DCLレベル・インタプリタの入力ストリームです。 ターミナルからコマンドを入力する場合には,コマンドはコマンド・ レベル0で入力されます。単純な会話形式のコマンド・プロシージャ(CLEANUP.COM など)は,コマンド・レベル1で実行されます。プロシージャが終了し,DCL プロンプトが画面に再表示されると,コマンド・レベル0 に戻ります。

15.7.1 終了方法

コマンド・プロシージャの実行中に,そのプロシージャを終了するには, 次の3種類の方法を使用できます。

EXITコマンドによる終了

コマンド・プロシージャは,プロシージャの終わりに到達するか,EXITコマンドを検出すると終了します。 いずれの場合も,次に高いコマンド・レベルに制御が戻ります。EXIT コマンドによって終了する場合,状態値をEXIT コマンドのパラメータとして指定すれば,その状態値を次に高いコマンド・ レベルに戻すことができます。

たとえば,DCLコマンド・レベルでSUBを起動し,SUBがSUB1を呼び出すと, 次のようなアクションが生じます。

  1. SUB1を終了すると,SUB1を呼び出した後のコマンド行でSUBに戻る。

  2. SUBを終了すると,DCLコマンド・レベルに戻る。

STOPコマンドによる終了

STOPコマンドによって終了した場合には,STOPコマンドを実行するコマンド・ レベルにかかわらず,制御はいつでもDCLコマンド・レベルに戻ります。

バッチ・ジョブの中でSTOPコマンドを実行すると,バッチ・ジョブが終了します。

Ctrl/Yによる終了

Ctrl/Yを押して,コマンド・プロシージャを中断させてから,EXITコマンドまたはSTOP コマンドを使用してプロシージャを終了することができます。 この場合,EXITまたはSTOPどちらのコマンドを使用した場合でもDCL レベルに戻ります。

次の例では,Ctrl/Yを押すことにより,TESTALLプロシージャに割り込みがかかります。EXIT コマンドはプロシージャの処理を終了し,DCLレベルに戻ります( プロシージャに割り込みをかけた後,STOPコマンドを入力することもできます) 。

     $ @TESTALL<Return>
     <Ctrl/Y>

     $ EXIT<Return>
     $

15.7.2 終了処理ルーチン

コマンド・プロシージャを中断させる場合,コマンド(イメージ)が終了処理ルーチンを宣言するものであると,EXIT コマンドは終了処理ルーチンに制御を渡します。 ただし,STOPコマンドはこれらのルーチンを実行しません。

15.8 エラー処理

省略時の設定では,コマンド・インタプリタは,コマンドを実行してエラーまたは重大エラーが生じると EXIT コマンドを実行します。このとき, プロシージャは終了して前のコマンド・レベルに戻ります。他の重大度( 成功,警告,通知エラー)の場合には,コマンド・プロシージャの処理が継続されます。

コマンド・インタプリタは以上のようにしてエラー処理を行いますが,ユーザがコマンド・ プロシージャの中のラベルを参照したときに,そのラベルが存在しない場合( たとえば,GOTO ERR1コマンドをコマンド・プロシージャ内に指定したが,ERR1 がプロシージャ内でラベルとして使用されていない場合) には,警告メッセージを出してコマンド・プロシージャは終了します。

システムがエラー処理ルーチンの一部としてEXITコマンドを出した場合は,$STATUS の値は直前のコマンド・レベルに戻されます。このとき,コマンド・ インタプリタは$STATUSの上位桁を1に設定するため,状態値に関連するメッセージを再表示しません。

たとえば,次のコマンド・プロシージャTEST.COMには,出力ファイル指定にエラーがあります。

     $ CREATE DUMMY.DAT\
     THIS IS A TEST FILE
     $ SHOW TIME

このプロシージャを実行すると,CREATEコマンドが$STATUSにエラーを戻し, 対応するメッセージを表示します。このとき,コマンド・インタプリタは$STATUS の値を調べて,エラーが生じたかどうかを判別し,EXITコマンドを出して$STATUS の値を戻します。CREATEコマンドはすでに1回メッセージを表示したため, プロシージャが終了してもエラー・メッセージは再表示されません。DCL コマンド・レベルでは,$STATUSにエラー・メッセージが保持されていますが, 上位桁は1に設定されています。

     $ @TEST
     %CREATE-E-OPENOUT, error opening DUMMY.DAT as output
     -RMS-F-SYN, file specification syntax error
     %DCL-W-SKPDAT, image data (records not beginning with "$") ignored
     $ SHOW SYMBOL $STATUS
       $STATUS = "%X109110A2"
     $ WRITE SYS$OUTPUT F$MESSAGE(%X109110A2)
       %CREATE-E-OPENOUT, error opening !AS as output

15.8.1 省略時のエラー処理

次の表は,コマンド・プロシージャの実行中に,エラーが発生したり,Ctrl/Y による割り込みが発生したときに,実行される省略時の処理を示しています。 これらの省略時の処理は,ON,SET [NO]ON,SET [NO]CONTROL=Yコマンドを使用して変更できます。

割り込み 省略時の処理
エラーまたは重大なエラー プロシージャを終了し, 次のコマンド・レベルに戻る。
DCLコマンド・ レベルまたはコマンド・レベル1でのCtrl/Y プロシージャに割り込みがかかる。 他のイメージによって強制的に終了されない場合には, プロシージャを続行できる。
レベル1より下のコマンド・レベルでのCtrl/Y プロシージャは終了し, 次の上位コマンド・レベルに移動する。

15.9 エラー処理のその他の方法

これ以降の節では,その他のエラー処理方法を説明します。

15.9.1 ONコマンド

ONコマンドは,特定の重大度またはそれ以上の重大度のエラーが生じたときに実行されるアクションを指定します。 このようなエラーが生じた場合には, システムは次のようなアクションをとります。

ONコマンドの処理は1回だけ実行されます。したがって,コマンド・プロシージャがON コマンドに指定された処理を実行した後,省略時のエラー処理はリセットされます。

ONコマンドによって指定された処理は,コマンドが実行されているコマンド・ レベルの内部だけで適用されます。したがって,別のプロシージャを起動するプロシージャの内部で ON コマンドを実行した場合には,ONコマンドの処理は, ネスティングしたプロシージャに適用されません。

ONコマンドの形式は次のとおりです。

ON condition THEN [$] command

ただし,conditionは次のいずれかのキーワードです。

ONキーワード アクション
WARNING コマンド・プロシージャは,警告, エラー,重大エラーが生じたときに指定されたアクションを実行する。
ERROR コマンド・プロシージャは, エラーまたは重大エラーが生じたときに指定されたアクションを実行し, 警告エラーの場合には処理を継続する。
SEVERE_ERROR コマンド・プロシージャは, 重大(回復不可能な)エラーが生じたときに指定されたアクションを実行し, 警告またはエラーが生じた場合には処理を継続する。

特定の重大度レベルに対してONコマンドの処理が設定された場合には,同じ重大度またはそれより重大度の高いエラーが発生したときに, コマンド・ インタプリタは指定された処理を実行します。重大度の低いエラーが発生した場合には, コマンド・インタプリタはファイルの処理を続行します。

例: ONコマンドの使用

このコマンドを使用すれば,省略時のエラー処理を変更して,警告,エラー, または重大なエラーが発生したときに,プロシージャを終了できます。

     $ ON WARNING THEN EXIT

例:エラー発生後の再開

コマンド・プロシージャにこのコマンドが指定されている場合には,エラーまたは重大なエラーが発生するまで, コマンド・プロシージャは通常どおりに実行されます。

     $ ON ERROR THEN GOTO ERR1

このようなエラーが発生すると,プロシージャはERR1から実行を再開します。$STATUS と$SEVERITYは正常終了に設定され,省略時のエラー処理はリセットされます。 別のONコマンドまたはSET NOONコマンドが実行される前に,2 番目のエラーが発生した場合には,プロシージャは終了し,前のコマンド・ レベルに戻ります。ONコマンドで指定されたアクションは,コマンドが実行されているコマンド・ レベルでのみ適用されます。したがって, あるプロシージャ内で他のプロシージャを起動するようにONコマンドを使用した場合,ON コマンドのアクションはネストしたプロシージャには及びません。

図 15-1は,ONコマンド・ アクションを図式化しています。

図 15-1 ONコマンドのアクション

【1】
このONコマンドは,省略時のコマンド・アクション(警告の場合は処理を継続し, エラーまたは重大エラーの場合は終了する)を無効にする。A.FOR をコンパイル中にエラーまたは重大エラーが生じると,次のコマンドの処理に進む。
【2】
前のONコマンドが有効な場合は,省略時のコマンド・ アクションに戻るため,A.FORとB.FORの両方をコンパイル中にエラーまたは重大エラーが生じると, コマンド・プロシージャは終了する。
【3】
C.FORをコンパイル中に警告,エラーまたは重大エラーが生じると, コマンド・プロシージャは終了する。
【4】
コマンドの実行前にコマンド・ プロシージャが終了していなければ,そのコマンドが実行される。

付録 Cのサンプル・コマンド・プロシージャFORTUSER.COM とCALC.COMは,ONコマンドを使用してエラー処理を設定する方法を示しています。

15.10 SET NOONコマンドの使用方法

コマンド・プロシージャの中でSET NOONコマンドを使用すれば,コマンド・ インタプリタがコマンドによって戻される状態をチェックしないようにできます。 このコマンドは,ONコマンドをNO状態に設定します。 SET NOONコマンドを使用しても,コマンド・インタプリタは引き続き値を$STATUS と$SEVERITYに収めますが,エラー・チェックは行いません。エラー・ チェック機能を再開させるには,SET ONコマンドまたはONコマンドを使用します。

プロシージャでエラー・チェックが無効に設定されている場合には,コマンドまたはプログラムを実行した後,$STATUS の値を明示的にチェックできます。

次の例では,RUNコマンドの前にSET NOONコマンドが指定されているため, プログラムTESTAのまたはTESTBがエラーを戻した場合には,コマンド・ プロシージャは実行を続行します。SET ONコマンドは,コマンド・インタプリタによる省略時のエラー・ チェックを復元します。

     $ SET NOON
     $ RUN TESTA
     $ RUN TESTB
     $ SET ON

次の例では,最初のIFコマンドは,$STATUSの値が真であるかどうか(つまり, 値が奇数の数値であるかどうか)を確認します。その場合には, FORTRANコマンドは正常終了しており,LINKコマンドが実行されます。 LINKコマンドを実行した後,$STATUSが再度テストされます。$STATUSの値が奇数である場合には,RUN コマンドが実行されます。奇数でない場合には,RUN コマンドは実行されません。SET ONコマンドは現在のON条件処理を復元します。 つまり,SET NOONコマンドを実行する前に有効だった条件を復元します。

     $ SET NOON
     $ FORTRAN MYFILE
     $ IF $STATUS THEN LINK MYFILE
     $ IF $STATUS THEN RUN MYFILE
     $ SET ON

SET ONまたはSET NOONコマンドは,現在のコマンド・レベル,すなわちコマンドを実行するコマンド・ レベルにだけ適用されます。別のコマンド・ プロシージャを呼び出すコマンド・プロシージャの中でSET NOONコマンドを使用すると, ネストされたプロシージャの中では省略時のエラー・チェック方式が適用されます。SET NOON は,DCLレベルで会話形式で入力しても意味を持ちません。

15.11 Ctrl/Yによる割り込み処理

省略時の設定では,コマンド・プロシージャの実行中にCtrl/Yを押すと, コマンド・インタプリタは,Ctrl/Yコマンド・レベルと呼ばれる特別なコマンド・ レベルでコマンド入力を求めるプロンプトを出します。Ctrl/Yコマンド・ レベルでは,コマンド・インタプリタ内で実行されるDCLコマンドを入力した後,CONTINUE コマンドを入力すれば,コマンド・プロシージャの実行を再開できます。 また,コマンド・プロシージャの実行を強制的に終了するDCL コマンドを入力すれば,プロシージャを終了できます。

この節では,ONコマンドを使用することにより,コマンド・プロシージャがCtrl/Y による割り込みを処理する方法の変更について説明します。

15.11.1 コマンド・プロシージャの中断

会話形式で実行中のコマンド・プロシージャを中断するには,Ctrl/Yを押します。Ctrl/Y を押すと,コマンド・インタプリタはCtrl/Yレベルと呼ばれる新しいコマンド・ レベルを設定して,コマンド入力を求めるプロンプトを出します。 いつ中断が生じるかは,実行中のコマンドまたはプログラムによって異なります。

Ctrl/Yレベルでは,コマンド・インタプリタは以前に設定されたすべてのコマンド・ レベルの状態を格納するため,Ctrl/Yによる中断後に正しい状態を復元できます。

プロシージャの中断後は,次のようにします。


注意
Ctrl/Yを押した後に(コマンド・ レベルから明示的に,またはONルーチンの一部として)コマンド・プロシージャを終了しない場合, 次に入力されるコマンドはこのコマンド・ プロシージャのコンテキストの中で解釈されます。たとえば,会話レベルで次のシンボルを定義したとします。
     MAIL = "mail/edit=(send,reply,forward)"

Ctrl/Yを押して,この定義を含まないコマンド・プロシージャを中断した後,MAIL コマンドを入力してメッセージを送信しても,エディタは自動的には起動されません。


15.11.2 特権イメージの中断

特権イメージの実行を中断した場合,このイメージのコンテキストをセーブしたければ,CONTINUE ,SPAWN,ATTACHのいずれかのコマンドを入力します。 他のコマンドを入力すると(ユーザが生成または接続したサブプロセスの中から入力する場合を除く) ,特権イメージは強制的に終了されます。

15.12 Ctrl/Yアクション・ルーチンの設定

これ以降の節では,Ctrl/Yアクション・ルーチンの設定方法を説明します。

15.12.1 ONコマンドの使用

エラー状態のときのアクションを定義するONコマンドによって,コマンド・ プロシージャの実行中に生じたCtrl/Yによる中断のアクション・ルーチンを定義する方法を指定することもできます。 ユーザが指定するアクションは, 省略時のCtrl/Yアクション(Ctrl/Yコマンド・レベルでコマンド入力を求めるプロンプトを出す) を無効にします。

     $ ON CONTROL_Y THEN EXIT

プロシージャがこのONコマンドを実行した場合,この後のプロシージャの実行中にCtrl/Y による中断が生じると,プロシージャは終了します。このとき, 前のコマンド・レベルに制御が渡されます。

Ctrl/Yを押してON CONTROL_Yを使用するプロシージャを中断した場合は, 次のアクションを実行します。

15.12.2 Ctrl/Yの入力結果

Ctrl/Yアクションを実行しても,省略時のCtrl/Yアクションには自動的に戻りません。Ctrl/Y アクションは,次のいずれかの条件が生じるまで有効です。

Ctrl/Yアクションは各アクティブ・コマンド・レベル内で指定でき,指定されたコマンド・ レベルに対してのみ影響します。

次の例に見られるように,このプロシージャが実行されると,Ctrl/Y割り込みが生じるたびにSHOW TIME コマンドが実行されます。SHOW TIMEコマンドの実行後, プロシージャは,中断されたコマンドの後のコマンドから実行を再開します。

     $ ON CONTROL_Y THEN SHOW TIME

次の図は,Ctrl/Yによる中断後の実行フローを示しています。

図 15-2 Ctrl/Yアクション後の実行フロー

【1】
TYPEコマンドの実行中にCtrl/Yによる割り込みが発生。
【2】
ラベルCLEAN_UPに制御が移る。
【3】
ルーチンの実行完了後にコマンド・ プロシージャは終了し,会話コマンド・レベルに戻る。
【4】
TYPEコマンドの実行中にCtrl/Yによる割り込みが発生。
【5】
ONコマンドで指定されているWRITEコマンドが実行される。
【6】
中断されたコマンドの次のコマンドからコマンド・プロシージャが再開される。

次の図は,ネストされたコマンド・プロシージャの実行中に Ctrl/Yを押すとどうなるかを示しています。

図 15-3 ネストされたコマンド・プロシージャ実行中のCtrl/Y

【1】
SEARCH.COMの実行中にCtrl/Yによる割り込みが生じると,CLEAN_UP ラベルに制御が渡される。
【2】
SUBSEARCH.COMの実行中にCtrl/Y による割り込みが生じると,SEARCH.COMの中のNEXT_STEPラベルに制御が渡される。
【3】
SUBSEARCH.COMではCtrl/Yアクションが指定されていないため,Ctrl/Y 割り込みが生じると,プロシージャは終了して前のコマンド・ レベルに戻る。
【4】
SUBSUB.COMの実行中にCtrl/Yによる割り込みが生じると,SHOW TIME が実行される。

15.13 Ctrl/Yによる割り込みの無効化/有効化

これ以降の節では,Ctrl/Yによる割り込むを有効にする方法,および無効にする方法を説明します。

15.13.1 SET NOCONTROL=Yの使用

SET NOCONTROL=Yコマンドは,Ctrl/Yによる割り込みを無効にします。すなわち, コマンド・プロシージャがSET NOCONTROL=Yコマンドを実行した場合は,Ctrl/Y を押しても割り込みは生じません。

SET NOCONTROL=Yコマンドは,ON CONTROL_Yコマンドによって設定された現在のCtrl/Y アクションも取り消します。省略時のCtrl/Yアクションに戻すには, 次の2つのコマンドを使用します。

     $ SET NOCONTROL=Y
     $ SET CONTROL=Y

SET NOCONTROL=Yコマンドは,Ctrl/Yの処理を無効にし,現在のON CONTROL_Yの処理を取り消します。SET CONTROL=YコマンドはCtrl/Yの処理を有効にします。 この時点で,省略時の処理が再度有効になります。 つまり,プロシージャの実行中にCtrl/Yが押された場合には,コマンド・ インタプリタは,Ctrl/Yコマンド・レベルでコマンドを要求するプロンプトを表示します。

SET NOCONTROL=Yコマンドはどのコマンド・レベルでも使用できます。SET CONROL=YコマンドによってCtrl/Yによる割り込みを使用可能にするまで, すべてのコマンド・レベルでCtrl/Yは無効です。

15.13.2 SET CONTROL=Yコマンドの使用

ON CONTROL_Yコマンドは,別のON CONTROL_YまたはSET NOCONTROL=Yコマンドが実行されるか, コマンド・プロシージャが終了するまで有効です。

Ctrl/Yが無効に設定されているときに,無限に終了しないループを終了するには,DCL コマンドSTOPを使用して,別のターミナルからプロセスを削除しなければなりません。 省略時のCtrl/Yの処理を無効に設定した場合には, できるだけただちにリセットしてください。省略時のCtrl/Yの処理をリセットするには,SET NOCONTROL=Y コマンドの後にSET CONTROL=Yコマンドを実行します。

このコマンド・プロシージャでは,ファイルの内容を表示しているときにCtrl/Y を押すと,制御はラベルEND_TYPEに渡されます。

        .
        .
        .
     $! Type a file
     $ IF COMMAND .NES. "TY" THEN GOTO END_TYPE
     $ ON CONTROL_Y THEN GOTO END_TYPE
     $ TYPE 'FILESPEC'
     $END_TYPE:
     $!
     $! Reset default
     $ SET NOCONTROL=Y
     $ SET CONTROL=Y
        .
        .
        .


注意
ON CONTROL_YコマンドとSET NOCONTROL=Yコマンドは特別な用途で使用します。一般に,Ctrl/Yによる割り込みを無効にすることはおすすめしません。Ctrl/Y が無効なときに非終了ループを終了するには, ループ・プロシージャを実行しているプロセスを別のターミナルから削除しなければなりません。

15.14 条件コードを使用しているコマンド・ プロシージャでのエラーの検出

コマンド・プロシージャの中のそれぞれのDCLコマンドの実行が終了すると, コマンド・インタプリタは,コマンドの終了理由を説明する条件コードをセーブします。 このコードを見ると,処理が完了したのか,情報またはエラー・ メッセージが出されたのかがわかります。

コマンド・インタプリタは,コマンド・プロシージャの中のそれぞれのコマンドを実行し終わると, 条件コードを調べます。特別なアクションが必要なエラーが生じた場合は, システムはそのアクションを実行します。それ以外の場合には, プロシージャの中の次のコマンドが実行されます。

15.14.1 条件コードの表示($STATUS)

コマンド・インタプリタは,条件コードを32ビットのロングワードとして予約グローバル・ シンボル$STATUSにセーブします。$STATUSは,次のようなシステム・ メッセージ・コードの形式に従います。

コマンドの実行が完了した場合,$STATUSは奇数値になります(ビット0〜2 には1または3が指定されます)。何らかの警告またはエラーが生じた場合は,$STATUS は偶数値になります(ビット0〜2に0,2,または4が指定されます) 。コマンド・インタプリタは,$STATUSの現在の16進値を保持して表示します。SHOW SYMBOL $STATUS コマンドを入力すると,$STATUSのASCII 変換値が表示されます。

次の例では,ファイル名が誤って入力されています。

     $ CREATE %FILE.LIS
     %CREATE-E-OPENOUT, error opening %FRED.LIS; as output
     -RMS-F-WLD, invalid wildcard operation
     $ SHOW SYMBOL $STATUS
       $STATUS = " %X109110A2"
     $ WRITE SYS$OUTPUT F$MESSAGE(%X109110A2)
       %CREATE-E-OPENOUT, error opening !AS as output

15.14.2 EXITコマンドを含む条件コード

コマンド・プロシージャが終了すると,コマンド・インタプリタは前のコマンドの条件コードを$STATUS に戻します。条件コードは,最後に実行されたコマンドが正常終了したかどうかに関する情報を提供します。

コマンド・プロシージャでEXITコマンドを使用する場合には,DCL が$STATUSに割り当てる値を変更する値を指定できます。この値は状態コードと呼び, 整数式として指定しなければなりません。

コマンド・プロシージャに,ネスティングしたコマンド・プロシージャが含まれており, 複数のコマンド・レベルを作成する場合には,EXITコマンドを使用して, 省略時の条件コードを明示的に無効にする値を戻すことができます。

次の2つのコマンド・プロシージャについて調べてみましょう。

     $! This is file A.COM
     $!
     $ @B
        .
        .
        .

     $! This is file B.COM
     $!
     $ ON WARNING THEN GOTO ERROR
        .
        .
        .
     $ ERROR:
     $ EXIT 1

B.COMのONコマンドは,B.COMの実行中に警告,エラー,重大なエラーのいずれかが発生した場合には, プロシージャの制御がラベルERRORに渡されることを示しています。 ここでは,条件コードは明示的に1に設定されており, 正常終了を示します。したがって,B.COMが終了すると,エラーが発生したかどうかとは無関係に, 正常終了コードがA.COMに戻されます。

15.14.3 重大度レベルの決定

$STATUSの下位3ビットは,コマンドが終了する原因となった条件の重大度を示します。 条件コードのこの部分は,予約されているグローバル・シンボル$SEVERITY に格納されます。$SEVERITYシンボルの値は0〜4の範囲であり, 各値はそれぞれ次の重大度レベルを表現します。

重大度
0 警告
1 正常終了
2 エラー
3 情報
4 致命的な(重大な)エラー

正常終了コードと情報コードは奇数の数値であり,警告コードとエラー・ コードは偶数の数値です。

15.14.4 正常終了のテスト

次に示すように,$SEVERITYまたは$STATUSに対して論理テストを実行するIF コマンドを使用すれば,コマンドの正常終了をテストできます。

     $ IF $SEVERITY THEN GOTO OKAY
     $ IF $STATUS THEN GOTO OKAY

これらのIFコマンドは,$SEVERITYおよび$STATUSの値が真(奇数)の場合には, ラベルOKAYに分岐します。$SEVERITYと$STATUSの現在の値が奇数の場合には, コマンドまたはプログラムは正常終了しています。コマンドまたはプログラムが正常終了しなかった場合には,$SEVERITY と$STATUSの値は偶数です。 したがって,IF式は偽になります。

条件が真であるかどうかをテストするかわりに,偽であるかどうかをテストすることもできます。 次の例を参照してください。

     $ IF .NOT. $STATUS THEN  . . .

コマンド・インタプリタは条件コードの重大度レベルを使用して,ON コマンドによって定義される処理を実行するかどうかを判断します。第15.9節の説明を参照してください。

15.15 $STATUSを設定しないコマンドの使用

大部分のDCLコマンドは,正常終了したときに状態値とエラー・メッセージを生成するシステム・ ユーティリティを起動します。しかし,正常終了したときに,$STATUS と$SEVERITYの値を変更しないコマンドがいくつかあります。 これらのコマンドは次のとおりです。

CONTINUE DECK DEPOSIT
EOD EXAMINE GOTO
IF RECALL SET SYMBOL /SCOPE
SHOW STATUS SHOW SYMBOL STOP
WAIT

これらのコマンドを正しく実行できなかった場合には,条件コードは$STATUS に格納され,重大度レベルは$SEVERITYに格納されます。

15.16 ログイン・コマンド・プロシージャ

ログイン・コマンド・プロシージャとは,ユーザがログインするたびに, オペレーティング・システムが自動的に実行するコマンド・プロシージャです。 また,ユーザがキューに登録した各バッチ・ジョブの先頭で,システムはこのプロシージャを実行します。

ログイン・コマンド・プロシージャには,次の2種類があります。

15.16.1 システム全体のログイン・コマンド・プロシージャ

システム全体で有効なログイン・コマンド・プロシージャには,次の特徴があります。

システムまたはグループ・ログイン・コマンド・プロシージャを設定する場合, システム管理者は,論理名SYS$SYLOGINを該当するログイン・コマンド・ プロシージャに定義します。このログイン・コマンド・プロシージャは, すべてのシステム・ユーザに対して適用するように指定することも, 特定のユーザ・グループに対してのみ適用されるように指定することもできます。

15.16.2 パーソナル・ログイン・コマンド・プロシージャ

ユーザは,ログインするたびに同じコマンドを実行するパーソナル・ログイン・ コマンド・プロシージャを作成できます。

ログイン・コマンド・プロシージャのファイル指定は,システム管理者が割り当てます。 ほとんどの場合,ログイン・コマンド・プロシージャはLOGIN.COM という名前にします。システム管理者が特に指定しない限り, ログイン・コマンド・プロシージャをLOGIN.COMという名前にします。

注釈の付いた完成したLOGIN.COMプロシージャについては,付録 C を参照してください。

15.16.3 専用アカウントのログイン・コマンド・プロシージャ

システム管理者は,特別なコマンド・プロシージャの名前をアカウントのLGICMD フィールドに置くことによって,専用のアカウントを設定できます。 専用のアカウントにログインした場合に実行できるのは, コマンド・プロシージャでそのアカウントに指定された機能だけで,完全なDCL コマンド・セットは実行できません。専用アカウントについての詳細は, 『OpenVMSシステム管理者マニュアル』を参照してください。


[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]