INTRDRとは、内部読み取りプログラム(Internal reader)と呼ばれる、JES2のリーダー・プログラムのことです。ジョブは、JES2によって実行されますが、そのジョブを定義したJCLを読み取る機能が、リーダーです。JES2のリーダーは、元々は紙カードに記録されたJCLを読み取るため、カードリーダー・デバイスに対してI/Oを行っていました。今日では紙カードもカードリーダーもまず使われることはなく、代わりにDASDや磁気テープ上のデータセットにJCLが作成されます。そこに書かれたJCLを読み取るのが、JES2のINTRDR(内部読み取りプログラム)です。
INTRDRはプログラムではあるものの、呼び出して使うサブルーチン的なものではなく、JCLのDDステートメントに定義して使用するか、TSOやISPFなど対話処理のコマンドによって間接的に使用します。この時に使用されるコマンドがSUBMITであることから、INTRDRにジョブを読み取らせることを、JCLをサブミットする、などと呼んでいます。
INTRDRの使い方①
サブミットしたいジョブのJCLを、IEBGENERユーティリティなど、順次データセットのコピーを行うプログラムを使って、コピー先にSYSOUT、ライター名(出力プログラム名)として「INTRDR」を指定します。この場合、クラスは省略するか適当なものでかまいません。
1 2 3 4 5 6 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- //SUBMIT EXEC PGM=IEBGENER //SYSPRINT DD DUMMY //SYSUT1 DD DISP=SHR,DSN=MY.JCLLIB(TESTJOB1) //SYSUT2 DD SYSOUT=(,INTRDR) //SYSIN DD DUMMY |
- MY.JCLLIB内のメンバーTESTJOB1が、JCLとして読み取られ実行される。
INTRDRの使い方②
エディターやブラウザーで、サブミットしたいジョブのJCLを開き、SUB[MIT]コマンドを実行することで、ジョブをサブミットできます。
TSOコマンド「SUBMIT」を使って、ジョブをサブミットできます。パラメーターに、サブミットするJCLの’データセット名(メンバー名)’を指定します。
TSOの場合は、直接SUBMITコマンドを使うより、CLIST(コマンドプロシージャ)と組み合わせる方が一般的でしょう。CLIST内で、サブミットするJCLそのものを生成することで、入力パラメーターや状況に応じてJCL内容を変更することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- /* /* SAMPLE CLIST: /* SUBMIT DATASET PRINT JOB. /* PROC 0 WRITENR PLEASE ENTER INPUT DATASET NAME ==> READ &INDSN SET &SYSOUTTRAP = 1 SUBMIT * END(##) //&SYSUID.A JOB //PRINT EXEC PGM=IEBGENER //SYSPRINT DD DUMMY //SYSUT1 DD DISP=SHR,DSN=&INDSN //SYSUT2 DD SYSOUT=* //SYSIN DD DUMMY // ## WRITE &SYSOUTLINE1 |
MSPとVOS3では、SUBMITコマンドの入力ソースに端末やCLISTを指定できません。代わりに、一旦ワークデータセットに書き出し、そのデータセットをSUBMITコマンドで指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/* /* SAMPLE CLIST: /* SUBMIT DATASET PRINT JOB. (MVS3.8) /* PROC 0 CONTROL NOFLUSH WRITENR PLEASE ENTER INPUT DATASET NAME ==> READ &INDSN /* SET &INDSN = USR1.JCL(IEHLIST) ALLOCATE DD(JCLWORK) DA(JCLWORK) UNIT(SYSALLDA) NEW TRACKS SPACE(1) OPENFILE JCLWORK OUTPUT SET &JCLWORK = &STR(//&SYSUID.A JOB ,&SYSUID,CLASS=A,MSGCLASS=C) PUTFILE JCLWORK SET &JCLWORK = &STR(//PRINT EXEC PGM=IEBGENER) PUTFILE JCLWORK SET &JCLWORK = &STR(//SYSPRINT DD DUMMY) PUTFILE JCLWORK SET &JCLWORK = &STR(//SYSUT1 DD DISP=SHR,DSN=&INDSN) PUTFILE JCLWORK SET &JCLWORK = &STR(//SYSUT2 DD SYSOUT=*) PUTFILE JCLWORK SET &JCLWORK = &STR(//SYSIN DD DUMMY) PUTFILE JCLWORK SET &JCLWORK = &STR(//) PUTFILE JCLWORK CLOSFILE JCLWORK SUBMIT JCLWORK FREE DD(JCLWORK) DELETE |
INTRDRの使い方③
プログラムからINTRDRにJCLを書き出すこともできます。例えばCOBOLでJCLを作り、それを順次ファイルへ書き出せばジョブを実行できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- //SUBMIT EXEC PGM=COBOLPGM //SYSUT2 DD SYSOUT=(,INTRDR) FILE-CONTROL. SELECT OUTFILE ASSIGN TO SYSUT2. * DATA DIVISION. FILE SECTION. FD OUTFILE RECORDING MODE IS F BLOCK CONTAINS 0 RECORDS RECORD CONTAINS 80 CHARACTERS. 01 OUTDATA PIC X(80). * WORKING-STORAGE SECTION. 01 I PIC 99 VALUE 0. 01 JCL. 02 R1 PIC X(80) VALUE '//JOBNAME JOB CLASS=A,MSGCLASS=C'. 02 R2 PIC X(80) VALUE '//PRINT EXEC PGM=IEBGENER'. 02 R3 PIC X(80) VALUE '//SYSPRINT DD DUMMY'. 02 R4 PIC X(80) VALUE '//SYSUT1 DD DISP=SHR,DSN=INPUT.PS'. 02 R5 PIC X(80) VALUE '//SYSUT2 DD SYSOUT=*'. 02 R6 PIC X(80) VALUE '//SYSIN DD DUMMY'. 01 JCLRECS REDEFINES JCL. 02 REC PIC X(80) OCCURS 6. * PROCEDURE DIVISION. * OPEN OUTPUT OUTFILE. LOOP. ADD 1 TO I. MOVE REC(I) TO OUTDATA. WRITE OUTDATA. IF I < 6 THEN GO TO LOOP. CLOSE OUTFILE * STOP RUN. |
プログラム内で定義したJCLデータが、SYSUT2に指定したINTRDRに書き出され、ジョブとして実行されます。
すでに紹介したGENERユーティリティや上記のCOBOLプログラムでは、INTRDRを順次データセットとして扱います。書き出したJCLを実際に実行させるには、データセットをクローズする必要があります。しかし、アセンブラー・プログラムなら、INTRDRをVSAMデータセットとして扱うことも可能です。複数のジョブをサブミットする場合でも、CLOSEと再OPENを繰り返す必要がありません(ただし、ジョブの区切りとしてENDREQマクロを発行する)。また、サブミットされたJOBのJOBIDが戻されるので、プログラムでJOBIDを処理に使うこともできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
OPEN ACB OPEN INTRDR : LA R3,JCLDATA GR3 --> NEXT JCL CARD LOOP DS 0H ST R3,RPL+RPLAREA-IFGRPL SET PUT DATA AREA ADDRESS PUT RPL=RPL SEND OVER 1 CARD IMAGE LA R3,80(,R3) LOCATE TO NEXT CARD CLI 0(R3),X'FF' END OF JOB STREAM ? BNE LOOP NO, LOOP FOR NEXT CARD ENDREQ RPL=RPL GIVE JES2 END OF FILE LA R3,RPL+RPLRBAR-IFGRPL GR3 --> JOBID FIELD ADDRESS : : CLOSE ACB CLOSE INTRDR : : ACB ACB DDNAME=SYSUT2 ACB RPL RPL ACB=ACB,OPTCD=SEQ,AREALEN=80,RECLEN=80 JCLDATA DS 0H DC CL80'//JOBNAME JOB CLASS=A,MSGCLASS=C' DC CL80'//PRINT EXEC PGM=IEBGENER' DC CL80'//SYSPRINT DD DUMMY' DC CL80'//SYSUT1 DD DISP=SHR,DSN=INPUT.PS' DC CL80'//SYSUT2 DD SYSOUT=*' DC CL80'//SYSIN DD DUMMY' DC XL1'FF' END OF JCL INDICATOR : IFGRPL AM=VSAM RPL |
サンプルなので、エラーの判定を省略しています。正しく書き出されれば、JOBIDはRPLのRPLRBARフィールドに設定されます(CL8’JOBnnnnn’)。なお、スプールや空きジョブ番号など、JES2リソースが不足した状態では、発行したPUTマクロまたはENDREQマクロが完了しません。この場合は、JES2側で必要な対処を行う必要があります(例えば不要なジョブ出力を消去する)。応答がないからと言って、プログラムをキャンセルしても意味がありません。COBOLやTSOコマンドであっても同じです。