日本-日本語

製品  >  ソフトウェア  >  OpenVMS  >  マニュアル

OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第 1 章:OpenVMS オペレーティング・システムの概要
第 2 章:DCL を使用したシステムとの会話
第 3 章:ファイル情報の格納
第 4 章:ディレクトリ・ファイルの編成
第 5 章:拡張ファイル指定
第 6 章:ディスクとテープ・ドライブの使用方法
第 7 章:Mail を使用して他のユーザと通信する
第 8 章:EVE エディタによるテキスト・ファイルの編集
第 9 章:ファイルのソートとマージ
第 10 章:資源へのアクセスの制御
第 11 章:デバイスとファイルの論理名定義
第 12 章:シンボル,コマンド,式の定義
第 13 章:コマンド・プロシージャの概要
第 14 章:DCL での拡張プログラミング
第 15 章:レキシカル関数を使用しての情報の取得と処理
第 16 章:プロセスとバッチ・ジョブ
付録 A :文字セット
付録 B :コマンド・プロシージャの例
用語集
索引
PDF
OpenVMS ホーム
OpenVMS | HPE 日本

OpenVMS
ユーザーズ・マニュアル


目次 索引



GOSUB コマンドは,コマンド・プロシージャの中のラベルの付いたサブルーチンに制御を渡します。コマンド・プロシージャの中にラベルがない場合には,実行は継続されず,強制終了されます ( ラベルについての詳細は, 第 13 章 を参照してください )。GOSUB コマンドは,プロシージャ・レベルあたり最大 16 までネストすることができます。

GOSUB コマンドは,ローカル・サブルーチン・コールの 1 つで,新しいプロシージャ・レベルは作成しません。このため,現在のコマンド・レベルで定義されているすべてのラベルとローカル・シンボルを GOSUB によって起動されたサブルーチンで使用できます。

RETURN コマンドは,サブルーチンを終了して, GOSUB コマンドの後のコマンドに制御を戻します。 RETURN コマンドには $STATUS に割り当てる値を指定することができます。これは,サブルーチンの終了時に DCL が $STATUS に割り当てる値を変更するものです。この値は,0 〜 4 の整数であるか,またはそれと同等な式でなければなりません。値を指定すると,DCL はそれを条件コードとして解釈します。値を指定しなければ,$STATUS の現在の値が保持されます。

次の例は,GOSUB コマンドを使用して制御をサブルーチンに渡す方法を示しています。

$! 
$! GOSUB.COM 
$! 
$ SHOW TIME 
$ GOSUB TEST1            (1)
$ WRITE SYS$OUTPUT "GOSUB level 1 has completed successfully." 
$ SHOW TIME 
$ EXIT 
$! 
$! TEST1 GOSUB definition 
$! 
$ TEST1: 
$     WRITE SYS$OUTPUT "This is GOSUB level 1." 
$     GOSUB TEST2       (2)
$     RETURN %X1        (3)
$! 
$! TEST2 GOSUB definition 
$! 
$ TEST2: 
$     WRITE SYS$OUTPUT "This is GOSUB level 2." 
$     WAIT 00:00:02 
$     RETURN            (4)

例を確かめる場合は,次の点に注意してください。

  1. 最初の GOSUB コマンドは TEST1 のラベルが付いたサブルーチンに制御を渡す。

  2. プロシージャは,TEST1 サブルーチンの中のコマンドを実行して, TEST2 のラベルが付いたサブルーチンに分岐する。

  3. TEST1 サブルーチンの中の RETURN コマンドは,メイン・コマンド・プロシージャに制御を戻し,正しく実行されたことを示す 1 の値を $STATUS に渡す。

  4. TEST2 サブルーチンの中のRETURN コマンドは,TEST1 サブルーチンに制御を戻す。このコマンドは 3 番目のコマンドの前に実行されることに注意。



14.17 新しいコマンド・レベルの作成

新しいコマンド・レベルを作成するには,次の 2 種類の方法があります。

  • コマンド・プロシージャの内部でプロシージャ実行 (@) コマンドを使用して,別のコマンド・プロシージャを起動することにより,コマンド・プロシージャをネスティングする方法 ( 第 13 章 を参照 )

  • CALL コマンドを使用して,コマンド・プロシージャの内部に存在するサブルーチンを呼び出す方法



14.17.1 CALL コマンドの使用

CALL コマンドは,コマンド・プロシージャの中のラベルが付いたサブルーチンに制御を渡して,新しいコマンド・レベルを作成します。CALL コマンドを使用すると, 1 つのファイルの中に 2 つ以上の関連コマンド・プロシージャを保持できるため,プロシージャを管理しやすくなります。サブルーチン・ラベルは一意でなければならず,コマンド・プロシージャの中の CALL コマンドの前後に置きます。サブルーチン・ラベルの入力規則については, 第 13 章 を参照してください。

ラベルに加えて,サブルーチンには最大 8 個のオプション・パラメータを渡すことができます。パラメータについての詳細は, 第 14.2 節 を参照してください。

CALL コマンドを使用する場合には,次の規則に従ってください。

  • 出力は SYS$OUTPUT に送信する。

  • サブルーチンからファイルに出力を送信できるように,オプションの /OUTPUT 修飾子を指定する。

  • 出力ファイルに対しては,省略時のファイル・タイプ .LIS を使用する。

  • 出力ファイル指定でワイルドカード文字を使用することはできない。



CALL コマンドを使用する場合には,次の省略時の設定が使用されます。

  • CALL コマンドで呼び出したサブルーチンとプロシージャ実行 (@) コマンドで呼び出したプロシージャは,最大 32 コマンド・レベルまでネストすることができる。

  • SET SYMBOL コマンドによってマスクされている場合を除いて,外側のレベルで定義されたローカル・シンボルは内側のどのプロシージャまたはサブルーチン・レベルでも使用でき,グローバル・シンボルはどのコマンド・レベルでも使用できる。

  • ラベルは,定義されたときのレベルでのみ有効。



SUBROUTINE コマンドと ENDSUBROUTINE コマンドは, CALL サブルーチンの始まりと終わりを定義します。 SUBROUTINE コマンドのすぐ前にサブルーチンへのエントリ・ポイントを定義するラベルを置きます。 ENDSUBROUTINE コマンドのすぐ前に EXIT コマンドを置くことができますが,サブルーチンを終了する必要はありません。 ENDSUBROUTINE コマンドは,サブルーチンを終了して, CALL コマンドのすぐ後のコマンド行に制御を渡します。

サブルーチンの中のコマンド行が実行されるのは,サブルーチンを CALL コマンドで呼び出す場合だけです。コマンド・プロシージャを行ごとに実行する場合,コマンド言語インタプリタは,SUBROUTINEコマンドと ENDSUBROUTINE コマンドの間のすべてのコマンドをスキップします。

サブルーチン・エントリ・ポイントの有効範囲を定義したり,ラベル参照を使用するときには,次のような制限事項が適用されます。

  • 別のサブルーチンの中で定義されるサブルーチン・エントリ・ポイントは,該当サブルーチンに対してローカルとなる。サブルーチン・エントリ・ポイントが別のサブルーチン・ブロックの中にある場合には,そのサブルーチンは呼び出せない。

  • サブルーチン・エントリ・ポイントが IF-THEN-ELSE ブロックの中にある場合には, IF-THEN-ELSE ブロックの外からはこのサブルーチンを呼び出せない。

  • すべての SUBROUTINE コマンドには,サブルーチンの終わりを示すための ENDSUBROUTINE コマンドがなければならない。

次の例では,呼び出しは正しくありません。これは,CALL BAR コマンドが MAIN サブルーチンの外部に存在するからです。

$ CALL BAR 
$ 
$ MAIN: SUBROUTINE 
$ 
$     BAR: SUBROUTINE 
$     ENDSUBROUTINE 
$ 
$ ENDSUBROUTINE 

この CALL コマンドが正しく機能するようにするには,このコマンドを, SUBROUTINE と ENDSUBROUTINE で囲まれる部分に指定しなければなりません。

この例に示した呼び出しは, IF-THEN-ELSE ブロックの内部に存在するため,実行できません。

$ IF 1 
$ THEN 
$    BOB:SUBROUTINE 
$    ENDSUBROUTINE 
$ ENDIF 
$ CALL BOB 

次の例には,SUB 1 と SUB2 という 2 つのサブルーチンがあります。これらのサブルーチンは,CALL コマンドで呼び出されるまでは実行されません。

$ 
$! CALL.COM 
$ 
$! Define subroutine SUB1. 
$! 
$ SUB1: SUBROUTINE 
        .
        .
        .
$       CALL SUB2       !Invoke SUB2 from within SUB1. 
        .
        .
        .
$       @FILE           !Invoke another command procedure file. 
        .
        .
        .
$       EXIT 
$ ENDSUBROUTINE !End of SUB1 definition. 
$! 
$! Define subroutine SUB2. 
$! 
$ SUB2: SUBROUTINE 
$       EXIT 
$ ENDSUBROUTINE !End of SUB2 definition. 
$! 
$! Start of main routine. At this point, both SUB1 and SUB2 
$! have been defined but none of the previous commands have 
$! been executed. 
$! 
$ START: 
$       CALL/OUTPUT=NAMES.LOG  SUB1 "THIS IS P1" 
        .
        .
        .
$       CALL SUB2 "THIS IS P1" "THIS IS P2" 
        .
        .
        .
$ EXIT          !Exit this command procedure file. 

CALL コマンドが SUB1 サブルーチンを起動して,出力をNAMES.LOG ファイルに切り換えます。 SUB1 サブルーチンは SUB2 サブルーチンを呼び出しています。プロシージャは SUB2 を実行して,プロシージャ実行 (@) コマンドによってコマンド・プロシージャ FILE.COM を起動します。 SUB1 のすべてのコマンドが実行されると,メイン・プロシージャの中の CALL コマンドが SUB2 をもう一度呼び出します。 SUB2 の実行が終わると,プロシージャは終了します。

14.18 場合分け文の使用

場合分け文は,特殊な形式の条件コードであり,変数または式の値に応じて,一連のコマンド・ブロックの中の 1 つのブロックだけを実行します。普通,場合分け文で有効な値は,それぞれのコマンド・ブロックの先頭にあるラベルです。場合分け文は,指定された値を GOTO 文のターゲット・ラベルとして使用することによって,該当するコード・ブロックに制御を渡します。

場合分け文を作成するには,次のようにします。

  1. ラベルをリストする。

  2. 場合分け文を作成する。

  3. コマンド・ブロックを作成する。



14.18.1 ラベルのリスト

ラベルをリストするには,スラッシュ ( または,区切り文字として選択した文字 ) で区切られたラベルのリストが入っている文字列をシンボルに定義します。このシンボル定義はコマンド・ブロックの前に置かなくてはなりません。

次の例は, COMMAND_LIST シンボルをラベル PURGE, DELETE,EXIT と同じにしています。

$ COMMAND_LIST = "/PURGE/DELETE/EXIT/" 



14.18.2 場合分け文の作成

場合分け文を作成するには,次の手順に従ってください。

手順 操作
1 INQUIRE コマンドを使用して場合分け変数の値を得る。
2 IF コマンドと一緒にF$LOCATE と F$LENGTH を使用して,場合分け変数の値が有効かどうかを判別する。
3 場合分け変数が有効な場合には,場合分け文 (GOTO コマンド ) を実行して,該当するコード・ブロックに制御を渡す。

場合分け変数が有効でない場合は,メッセージを表示して処理を終了するか,別の場合分け値を要求する。

次の例では,ラベルが完全なコマンド名に定義されています。したがって,F$LOCATE は,コマンド名の検索文字列の中に区切り文字を含めて,コマンドが短縮されないようにしています。

$GET_COMMAND: 
$ INQUIRE COMMAND - 
  "Command (EXIT,PURGE,DELETE)" 
$ IF F$LOCATE ("/"+COMMAND+"/",COMMAND_LIST) .EQ. - 
   F$LENGTH (COMMAND_LIST) THEN GOTO ERROR_1 
$ GOTO 'COMMAND' 
   .
   .
   .
$ERROR_1: 
$ WRITE SYS$OUTPUT "No such command as ''COMMAND'." 
$ GOTO GET_COMMAND 

それぞれのコマンド・ブロックには,1 つ以上のコマンドを指定できます。コマンド・ブロックの先頭には固有のラベルを付けます。それぞれのコマンド・ブロックを終わるときには,コマンド・ブロックのリストにないラベルに制御を渡します。

コマンド・ブロックの作成

次の例では,それぞれのコマンド・ブロックに,1つ以上のコマンドを指定しています。コマンド・ブロックの先頭には固有のラベルを付けます (PURGE:, DELETE:)。それぞれのコマンド・ブロックを終わるときには,コマンド・ブロックのリストにないラベル(GOTO GET_COMMAND) に制御を渡します。

$GET_COMMAND: 
   .
   .
   .
$PURGE: 
$ INQUIRE FILE 
$ PURGE 'FILE' 
$ GOTO GET_COMMAND 
$ ! 
$DELETE: 
$ INQUIRE FILE 
$ DELETE 'FILE' 
$ GOTO GET_COMMAND 
$ ! 
$EXIT: 



14.19 ループの作成

コマンド・ブロックの先頭に,変数をテストするループを作成できます ( 第 13 章 を参照 )。しかし,次の操作を実行すれば,ループの最後に終了変数をテストするループを作成することもできます。

手順 操作
1 ループを開始する。
2 ループ本体の中のコマンドを実行する。
3 終了変数を変更する。
4 終了変数をテストする。

条件が満足されない場合は,ループの始めに戻る。

5 ループを終了する。

ループの終わりにある終了変数をテストする場合は,終了変数の中の値にかかわらず,ループ本体のコマンドが少なくとも 1 回は実行されます。

次の 2 つの例は, COMMAND が "EX" (EXIT) に定義されたときに終了するループを実行します。 F$EXTRACT は COMMAND を最初の 2 文字に切り捨てます。最初の例では,終了変数の COMMAND がループの始めにテストされ, 2 番目の例では,ループの終わりでテストされます。

$ ! EXAMPLE 1 
$ ! 
$GET_COMMAND: 
$ INQUIRE COMMAND- 
  "Command (EXIT,DIRECTORY,TYPE,PURGE,DELETE,COPY)" 
$ COMMAND = F$EXTRACT(0,2,COMMAND) 
$ IF COMMAND .EQS. "EX" THEN GOTO END_LOOP 
   .
   .
   .
$ GOTO GET_COMMAND 
$END_LOOP: 

$ ! EXAMPLE 2 
$ ! 
$GET_COMMAND: 
$ INQUIRE COMMAND- 
  "Command (EXIT,DIRECTORY,TYPE,PURGE,DELETE,COPY)" 
$ COMMAND = F$EXTRACT(0,2,COMMAND) 
   .
   .
   .
$ IF COMMAND .NES. "EX" THEN GOTO GET_COMMAND 
$ ! End of loop 

ループを一定回数実行するには,終了変数としてカウンタを使用します。次の例では,ユーザによって入力された 10 個のファイル名がローカル・シンボル FIL1,FIL2,...,FIL10 に収められます。

$ NUM = 1                       ! Set counter 
$LOOP:                          ! Begin loop 
$ INQUIRE FIL'NUM' "File"       ! Get file name 
$ NUM = NUM + 1                 ! Update counter 
$ IF NUM .LT. 11 THEN GOTO LOOP ! Test for termination 
$END_LOOP:                      ! End loop 
   .
   .
   .

次の例は,カウンタを使用してループの実行回数を制御します。この例では,ループは 10 回実行されます。終了変数はループの終わりにテストされます。

$! Obtain 10 file names and store them in the 
$! symbols FILE_1 to FILE_10 
$! 
$ COUNT = 0 
$ LOOP: 
$    COUNT = COUNT + 1 
$    INQUIRE FILE_'COUNT' "File" 
$    IF COUNT .LT. 10 THEN GOTO LOOP 
$! 
$ PROCESS_FILES: 
   .
   .
   .

COUNT シンボルを使用してループの中のコマンドの実行回数を記録します。また,シンボル名 FILE_1,FILE_2 から FILE_10 までを作成するのにも COUNT を使用しています。COUNT の値が増分されるのはループの始めですが,テストされるのはループの終わりであることに注意してください。したがって,COUNT が 9 から 10 に増分されると,IF 文が偽の結果を検出する前にループがもう 1 回だけ実行されます ( FILE_10 の値を得ます ) 。

一連の値に対してループを実行するには,F$ELEMENT レキシカル関数を使用します。 F$ELEMENT 関数は,区切り文字によって区切られた項目リストから項目を取り出します。 F$ELEMENT の引数として項目番号,項目区切り文字,リストを指定しなければなりません。

F$ELEMENT レキシカル関数の使用方法についての詳細は,『OpenVMS DCL ディクショナリ』を参照してください。

次の例では,ファイル CHAP1,CHAP2,CHAP3,CHAPA,CHAPB,CHAPC が順に処理されます。

$ FILE_LIST = "1,2,3,A,B,C" 
$ INDEX = 0 
$PROCESS: 
$ NUM = F$ELEMENT(INDEX,",",FILE_LIST) 
$ IF NUM .EQS. "," THEN GOTO END_LOOP 
$ FILE = "CHAP''NUM'" 
$ ! process file named by FILE 
   .
   .
   .
$ INDEX = INDEX + 1 
$ GOTO PROCESS 
$END_LOOP: 
$ EXIT 

次のコマンド・プロシージャは,ループを使用して,FILE_LIST シンボルにリストされたファイルを別のノードのディレクトリにコピーします。

$ FILE_LIST = "CHAP1/CHAP2/CHAP3/CHAP4/CHAP5" 
$ NUM = 0 
$! 
$! Process each file listed in FILE_LIST 
$ PROCESS_LOOP: 
$     FILE = F$ELEMENT(NUM,"/",FILE_LIST) 
$     IF FILE .EQS. "/" THEN GOTO DONE 
$     COPY 'FILE'.MEM MORRIS::DISK3:[DOCSET]*.* 
$     NUM = NUM + 1 
$     GOTO PROCESS_LOOP 
$! 
$ DONE: 
$ WRITE SYS$OUTPUT "Finished copying files." 
$ EXIT 

F$ELEMENT レキシカル関数から戻される最初のファイルは CHAP1 であり,次のファイルは CHAP2 です。以下も同様です。ループを実行するたびに,NUM の値が増分されるため,次のファイル名が入手されます。F$ELEMENT がスラッシュを戻した場合には, FILE_LIST のすべての項目が処理されたため,ループは終了します。

14.20 PIPE コマンドの使用

PIPE コマンドを使用すると,同一コマンド行から 1 つまたは複数の DCL コマンドを実行できます。これにより,コマンドのパイプライン処理,入出力のリダイレクト,条件実行,バックグラウンド処理など,UNIX 形式のコマンドを処理できるようになります。

このようなコマンド処理の形式は,インターネット・ソフトウェアの開発や使用をサポートします。インターネット・ソフトウェアでは,ホスト・システムとターゲット・システムの両方で存在を解析する,パイプライン・コマンドの使用を前提にしています。

これ以降の節では,PIPE コマンドへの割り込み方法,サブプロセスの性能を向上させる方法など, DCL コマンドの実行以外の目的で PIPE コマンドを使用する方法を説明します。

PIPE コマンドについての詳細は,『OpenVMS DCL ディクショナリ: N--Z』を参照してください。

1 つの PIPE コマンドに,複数の DCL コマンドを指定できます。指定した DCL コマンドは,順番に実行されます。次の形式を使用します。

PIPE   command-sequence ; command-sequence [; command-sequences]... 


目次 索引

印刷用画面へ
プライバシー ご利用条件・免責事項