【MVS】MVS環境でJCLを作成/実行する

JCLの画像

こんにちは!
今日はMVS環境でJCL(Job Control Language:ジョブ制御言語)を実行してみます。

JCLを作るうえで必要な情報を解説しつつ進めていきますので、良かったら皆さんのLinuxPC上でもハンズオンがてらやってみてください。

ステップ01. はじめに

この記事では、メインフレームを操作する上で欠かせない「JCL(Job Control Language:ジョブ制御言語)」について、その基礎から実践までを分かりやすく解説していきます。

この記事でできるようになること
・ JCLの役割と基本的なルールが理解できる。
・ 簡単なJCLを自分で読み書きできるようになる。
・ 実際にMVS環境でJCLを使って「ジョブ」を実行し、結果を確認できるようになる。

対象となる読者
・ メインフレームの学習を始めたばかりの方
・ 仕事や学習で、これからJCLに触れる必要がある方

前提とする環境
この記事の後半にあるハンズオン(実践)パートは、当ブログの以下の記事を参考に、MVS環境が構築されていることを前提としています。

 

そもそもJCLとは?

JCLとは、現在のWindowsでいうバッチ処理のことです。

もう少し詳しく言うと、MVS(Multiple Virtual Storage:多重仮想記憶)が登場した1970年代、コンピュータの計算能力は非常に貴重な資源でした。CPUを1秒たりとも遊ばせないために、あらかじめ大量の仕事(ジョブ)をまとめて投入し、効率よく連続実行させる「バッチ処理」が主流でした。JCLは、そのバッチ処理を制御するために生まれた、歴史ある言語なのです。

つまり、JCLは単なるスクリプトではなく、高価な計算機資源を最大限に活用するための、「緻密な仕事の指示書」と言えるでしょう。

…また、大昔はこのJCLはPCから作成し実行!していたわけではなく、パンチカードと呼ばれる紙に穴をあけ、カードリーダーに読み込ませていたようです。
加えて、パンチカードは80カラム目(文字目)までしか穿孔(穴あけ)できないという物理的な制約がありました。
その時代の名残もあり、いまだにJCLやメインフレーム環境でのプログラミングのルールの1つとして、1行は80カラム目(文字目)までしか記載できないという制約があります。

現在のプログラミングルールでよく言われる、1行は80文字くらいに収める、というのは大昔の物理的な制約が引き継がれたようです。

 

ステップ02. JCLとは? ~メインフレームに仕事をお願いする「指示書」~

2-1. なぜJCLが必要なのか? バッチ処理の重要性

私たちが普段使うWindowsやMacは、マウスでアイコンをクリックしたり、キーボードでコマンドを打ったりすると、すぐに結果が返ってくる「対話型」の処理が中心です。

一方、メインフレームが得意とするのは、大量のデータをまとめて一括で処理する「バッチ処理」です。例えば、「銀行の全口座の利息を深夜に一斉計算する」「企業の給与計算をまとめて行う」といった処理がこれにあたります。

このようなバッチ処理を行う際に、「どのプログラムを使って」「どのデータを読み込み」「結果をどこに書き出すのか」といった一連の仕事内容を、あらかじめコンピュータに伝えておく必要があります。

その「仕事の指示書」の役割を果たすのが、JCL (Job Control Language) なのです。

 

2-2. JCLの基本的な書式ルール

JCLはいくつかのシンプルなルールを知るだけで、ぐっと読みやすくなります。

  • ステートメントの種類
    JCLの各行は「ステートメント」と呼ばれ、主に以下の3種類で構成されます。
    `//` (斜線2本): 最も基本的な行です。ジョブの名前を定義したり、プログラムやデータを指定したりします。
    `//*` (斜線2本とアスタリスク): この行はコメントとして扱われ、処理には影響しません。メモを残したいときに使います。
    `/*` (斜線とアスタリスク): データの終わりなど、特別な区切りを示すために使います。

  • コーディング領域
    JCLは1行のどこにでも書けるわけではありません。おおよそ、以下のような領域に書くのがルールです。
    1~2桁目: `//` や `//*` などのステートメント識別子を書きます。
    3桁目以降: 命令(オペランド)やパラメータを記述します。
    72桁目まで: JCLの記述は通常72桁目までで終えます。
    73~80桁目: 連番や識別子を記述する領域で、ほとんど使いません。

下の画像では、1-5行目までが基本的な行で、5-10行目までがコメントです。

JCLの画面

今は「そんなルールがあるんだな」くらいで大丈夫です。
次の章で実際のJCLを見ながら、少しずつ慣れていきましょう。

 

ステップ03. JCLの三大要素!これだけは覚えよう

見ている方も一緒にJCLを作成できるように、まずはIPLからTSOでログインまで以下の記事をみて実施してみてください。

また、今回JCLを作成し保管する場所は前回の記事で作成した区分データセットの中なので、よかったら以下の記事から進めていってください。

MVS環境でデータセットを作ってみる

 

3-1.JCL用のメンバーを作成する

JCLを作成するには、まず前回作成した区分データセットの中に、メンバーを作成します。

メンバーは、区分データセットの中に作成するデータで、「Windows等で例えると、フォルダの中にファイルを作成する」とイメージしてもらえばOKです。
IPLが終わって、TSOにログインした画面から進めていきます。
まずは、ISPFの画面で「3.4」と入力してEnterを押しましょう。

ISPF画面

次の画面で、以下のように入力してEnterを押しましょう。

Data set name prefix ==> HERC01_________________________
Volume serial number ==> WORK02

DATASET UTILITY画面

すると、WORK02というボリューム(記憶装置)に前回作成したデータセットが確認できると思います。

TABでカーソルをHERC01.TEST.PDS.LIBの場所に持っていき、Eを押してEnterを押しましょう。

DATASET一覧

前回の記事で作成したTEST01があると思います。

今回は新しくメンバーを作成しましょうCommandの箇所に「S△JCL001」と入力してEnterを押しましょう。

JCL編集画面
JCL編集画面

まずは、先ほど説明した「//」を10行書きましょう。

…10行も連続で「//」をいちいち入力するのは面倒なので、画面の左側にある赤いシングルクォーテーションが並んでいるところ(※)に、コマンドを入力して一気に作成しましょう。(行コマンドは多用するので、覚えておきましょう)

※行コマンドフィールド(Line Command Field)といいます

まずは1行分「//」と入力し、行コマンドフィールドに「R10」と入力してEnterを押しましょう。

行コマンド
行コマンド結果

すると、対象の行に入力した情報が複製されます。

行コマンドには、以下の種類があります。

データの挿入・削除・複製

コマンド意味説明
IInsert (挿入)この行の後に新しい行を1行挿入します。`I5`のように数字を付けると、5行挿入します。
DDelete (削除)この行を削除します。`D3`で3行削除、`DD`で囲んだブロックを削除します。
RRepeat (複製)この行を1行複製します。`R5`で5回複製、`RR`で囲んだブロックを複製します。

データのコピー&ペースト、移動

コマンド意味説明
CCopy (コピー)この行をコピーします。`CC`でブロックの開始と終了を指定します。
MMove (移動)この行を移動(切り取り)します。`MM`でブロックの開始と終了を指定します。
AAfter (後に配置)コピー/移動したデータを、この行の**後**に貼り付けます。
BBefore (前に配置)コピー/移動したデータを、この行の**前**に貼り付けます。
OOverlay (上書き)コピー/移動したデータを、この行の上に重ねて貼り付けます。`OO`でブロックを指定します。

使い方:

  1. コピーしたい行の行コマンドフィールドに `C` を入力します。
  2. 貼り付けたい箇所の行に `A` (その行の後) または `B` (その行の前) を入力します。
  3. Enterキーを押すと、コピー&ペーストが実行されます。移動 (`M`) も同様です。

 

表示の制御

コマンド意味説明
XExclude (非表示)この行を画面上から非表示にします。`XX`でブロックを指定します。データ自体は削除されません。
FFirst (先頭表示)非表示になっているブロックの、最初の行を表示します。`F5`で先頭から5行表示します。
LLast (末尾表示)非表示になっているブロックの、最後の行を表示します。`L5`で末尾から5行表示します。
SShow (表示)非表示になっている行の詳細を表示します。
COLSColumns (桁表示)桁位置を示すルーラーを表示します。

 

3-2. JOBステートメント:ジョブの「表紙」

このステップからいよいよJCLを作成していきます。

JCLは、大きく分けて3種類のステートメント(命令文)で構成されています。
それぞれの役割を見ていきましょう。

JOBステートメント

JOBステートメントは、JCLの先頭に置かれ、これから始まる仕事(ジョブ)全体の情報を定義します。いわば「指示書」の表紙です。

//HERC01A  JOB CLASS=A,NOTIFY=HERC01

 

  • //HERC01A: ジョブの名前です。自分で好きな名前を付けられます(8文字以内)。
  • JOB: これがJOBステートメントであることを示します。
  • CLASS=A: ジョブの実行優先度などを指定します。どの順番で仕事に取り掛かるかの指定とイメージしてください。

この行は、「HERC01Aという名前の仕事です。優先度はAで実行してください」というような意味になります。

 

3-2. EXECステートメント:実行する「プログラム」の指定

EXEC(エグゼック)ステートメントは、ジョブの中で具体的に「何をするか」を指定します。
指示書の「手順」にあたる部分で、実行したいプログラム(Program)を指定するのが主な役割です。

//STEP01   EXEC PGM=IEFBR14

//STEP1: この手順(ステップ)の名前です。ジョブ内でユニークな名前を付けます。

  • EXEC: これがEXECステートメントであることを示します。
  • PGM=IEFBR14`: 実行するプログラムの名前を指定します。「IEFBR14」は、”何もしないで正常終了する”という、テストなどでよく使われる特殊なプログラムです。

この行は、「STEP1という手順です。IEFBR14というプログラムを実行してください」という意味になります。

 

3-3. DDステートメント:プログラムが使う「ファイル」の定義

DD(ディーディー)ステートメント(Data Definition)は、EXECで指定したプログラムが使用するファイル(MVSではデータセットと呼びます)を定義します。指示書の「材料」や「成果物の置き場所」を指定する、最も重要で頻出するステートメントです。

//NEWDS    DD DSN=HERC01.JCL.TEST, 
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(TRK,(1,1)),
//            DCB=(LRECL=80,BLKSIZE=800,RECFM=FB),
//            UNIT=3390,VOL=SER=WORK02

 

  • //NEWDS: DD名です。プログラム側と連携するための名前です。
  • DD: これがDDステートメントであることを示します。
  • DSN: データセット名(Dataset Name)を指定します。ファイルのフルパス名のようなものです。
  • DISP: データセットの後処理(Disposition)を指定します。ファイルの状態(新しいのか、既存か)や、処理後にどうするか(保存する、削除する)を指示します。
  • DCB: データセットの物理的な特性(Data Control Block)を指定します。レコード長やブロックサイズなど、ファイルの「形」を定義します。
        - LRECL=80: 1レコードの長さが80バイトであることを示します。
        - BLKSIZE=800: 800バイトを1ブロックとして処理することを示します。
        - RECFM=FB: レコード形式が「固定長ブロック(Fixed Block)」であることを示します。
  • UNIT=3390:データセットを作成する記憶装置の型番です。
  • VOL=SER=WORK02:データセットを作成する記憶装置の名前です。

そして、できたJCLが以下の画像です。

完成したJCL

DDステートメントはパラメータが多くて複雑に見えますが、まずは「プログラムが使うファイルを指定するんだな」という役割を理解することが大切です。

また、DCBで指定しているデータセットの特性は、前回データセットを作成した際に指定した内容と同じです。

詳細は次のステップで実際に使いながら学びましょう。

 

ステップ04. 【ハンズオン】最初のJCLを実行してみよう

MVS環境で実行(サブミット)してみましょう。

4-1. 今回JCLでやること

今回のハンズオンでは、「JCLを使って、自分用の新しいデータセット(ファイル)を1つ作成する」ことを目指します。具体的には、`IEFBR14`という何もしないプログラムを実行し、その副作用としてDDステートメントで定義したデータセットを作成させます。

4-2. サンプルJCL(コピペOK)

以下が、今回作成するJCLの全文です。

//HERC01A  JOB CLASS=A,NOTIFY=HERC01
//STEP01   EXEC PGM=IEFBR14
//NEWDS    DD DSN=HERC01.JCL.TEST,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(TRK,(1,1)),
//            DCB=(LRECL=80,BLKSIZE=800,RECFM=FB),
//            UNIT=3390,VOL=SER=WORK02

 

さて、作成したらJCLをまずは保存しましょう。

上のCommandの行に、「SAVE」と入力してEnterでデータが保存されます。

JCLの保存

 

4-3. ジョブの投入!SUBMITコマンド

ではいよいよ作成したJCLを実行してみましょう。

作成したJCLのCommandの行に「SUB」と入力してEnterを押しましょう。

SUBは、SUBMITのことで、このコマンドを入れることでJCLが実行されます。

JCLのサブミット

以下のようなメッセージが表示されます。

 JOB HERC01A(JOB00020) SUBMITTED
$HASP165 JOB   20  HERC01A ENDED- MAX COND CODE 0000
*** 
サブミット結果

MAX COND CODE 0000というのが、JCLの正常終了したというメッセージです。

また、このJOBの実行結果はJOBLOGとして書き出されます。
私の環境では、Herculesを起動したLinux内のファイルに書き出されていました。

/mvs-tk5/prt/prt00f.txt

中身を確認してみます。

cat prt00f.txt
                                                J E S 2   J O B   L O G


15.16.02 JOB   20  $HASP373 HERC01A  STARTED - INIT  1 - CLASS A - SYS TK5R
15.16.02 JOB   20  IEF403I HERC01A - STARTED - TIME=15.16.02
15.16.02 JOB   20  IEFACTRT - Stepname  Procstep  Program   Retcode
15.16.02 JOB   20  HERC01A    STEP01              IEFBR14   RC= 0000
15.16.02 JOB   20  IEF404I HERC01A - ENDED - TIME=15.16.02
15.16.02 JOB   20  $HASP395 HERC01A  ENDED


------ JES2 JOB STATISTICS ------


 22 AUG 25 JOB EXECUTION DATE


         8 CARDS READ


        40 SYSOUT PRINT RECORDS


         0 SYSOUT PUNCH RECORDS


      0.00 MINUTES EXECUTION TIME

    1     //HERC01A  JOB CLASS=A,NOTIFY=HERC01,                                   JOB   20
          //            USER=HERC01,PASSWORD=         GENERATED BY IKJEFF10
    2     //STEP01   EXEC PGM=IEFBR14
    3     //NEWDS    DD DSN=HERC01.JCL.TEST,
          //            DISP=(NEW,CATLG,DELETE),
          //            SPACE=(TRK,(1,1)),
          //            DCB=(LRECL=80,BLKSIZE=800,RECFM=FB),
          //            UNIT=3390,VOL=SER=WORK02

IEF236I ALLOC. FOR HERC01A STEP01
IEF237I 291  ALLOCATED TO NEWDS
IEF237I 190  ALLOCATED TO SYS00003
IEF142I HERC01A STEP01 - STEP WAS EXECUTED - COND CODE 0000
IEF285I   HERC01.JCL.TEST                              CATALOGED     *--------0
IEF285I   VOL SER NOS= WORK02.
IEF285I   SYS1.UCAT.TSO                                KEPT          *--------0
IEF285I   VOL SER NOS= TSO001.
IEF373I STEP /STEP01  / START 25234.1516
IEF374I STEP /STEP01  / STOP  25234.1516 CPU    0MIN 00.01SEC SRB    0MIN 00.00SEC VIRT     4K SYS   176K
************************************************************************************************************************************
*     1. Jobstep of job: HERC01A     Stepname: STEP01      Program name: IEFBR14    Executed on 22.08.25 from 15.16.02 to 15.16.02 *
*         elapsed time  00:00:00,07                      CPU-Identifier:  TK5R           Page-in:      0                           *
*             CPU time  00:00:00,01               Virtual Storage used:      4K         Page-out:      0                           *
*           corr. CPU:  00:00:00,01   CPU time has been corrected by  1 / 1,0  multiplier                                          *
*                                                                                                                                  *
*     I/O Operation                                                                                                                *
*     Number of records read via DD * or DD DATA:      0                                                                           *
*     291.......0 190.......0                                                                                                      *
*                                                                                                                                  *
*                                          Charge for step (w/o SYSOUT):          0,01                                             *
************************************************************************************************************************************
IEF375I  JOB /HERC01A / START 25234.1516
IEF376I  JOB /HERC01A / STOP  25234.1516 CPU    0MIN 00.01SEC SRB    0MIN 00.00SEC

                        HH        HH  EEEEEEEEEEEE  RRRRRRRRRRR    CCCCCCCCCC     00000000         11        AAAAAAAAAA
                       HH        HH  EEEEEEEEEEEE  RRRRRRRRRRRR  CCCCCCCCCCCC   0000000000       111       AAAAAAAAAAAA
                      HH        HH  EE            RR        RR  CC        CC  00      0000     1111       AA        AA
                     HH        HH  EE            RR        RR  CC            00     00 00       11       AA        AA
                    HH        HH  EE            RR        RR  CC            00    00  00       11       AA        AA
                   HHHHHHHHHHHH  EEEEEEEE      RRRRRRRRRRRR  CC            00   00   00       11       AAAAAAAAAAAA
                  HHHHHHHHHHHH  EEEEEEEE      RRRRRRRRRRR   CC            00  00    00       11       AAAAAAAAAAAA
                 HH        HH  EE            RR    RR      CC            00 00     00       11       AA        AA
                HH        HH  EE            RR     RR     CC            0000      00       11       AA        AA
               HH        HH  EE            RR      RR    CC        CC  000       00       11       AA        AA
              HH        HH  EEEEEEEEEEEE  RR       RR   CCCCCCCCCCCC   0000000000    1111111111   AA        AA
             HH        HH  EEEEEEEEEEEE  RR        RR   CCCCCCCCCC     00000000     1111111111   AA        AA



                    JJJJJJJJJJ   2222222222     00000000                                              ZZZZZZZZZZZZ
                    JJJJJJJJJJ  222222222222   0000000000                                             ZZZZZZZZZZZZ
                        JJ      22        22  00      0000                                                     ZZ
                        JJ                22  00     00 00                                                    ZZ
                        JJ                22  00    00  00                                                   ZZ
                        JJ               22   00   00   00                                               ZZZZZZZ
                        JJ             22     00  00    00                                               ZZZZZZZ
                        JJ           22       00 00     00                                                ZZ
                  JJ    JJ         22         0000      00                                               ZZ
                  JJ    JJ       22           000       00                                              ZZ
                  JJJJJJJJ      222222222222   0000000000                                              ZZZZZZZZZZZ
                   JJJJJJ       222222222222    00000000                                              ZZZZZZZZZZZZ


****Z   END   JOB   20  HERC01A                         ROOM        3.16.02 PM 22 AUG 25  PRINTER2  SYS TK5R  JOB   20   END   Z****
****Z   END   JOB   20  HERC01A                         ROOM        3.16.02 PM 22 AUG 25  PRINTER2  SYS TK5R  JOB   20   END   Z****
****Z   END   JOB   20  HERC01A                         ROOM        3.16.02 PM 22 AUG 25  PRINTER2  SYS TK5R  JOB   20   END   Z****
****Z   END   JOB   20  HERC01A                         ROOM        3.16.02 PM 22 AUG 25  PRINTER2  SYS TK5R  JOB   20   END   Z****

このJOBLOGの中で重要なのは、IEFBR14   RC= 0000の箇所です。
これは、先ほどと同じようにCOND CODE 0000というのと同じ意味です。

JCLでジョブを実行すると、各ステップ(STEP)の終了時に 条件コード(Condition Code, COND CODE) が設定されます。
これは、プログラムが正常に終了したか、異常終了したかを示す番号で、ジョブ管理や次のステップ実行の判断に使われます。

RC= 0004や、RC= 0008、RC= 0016だった場合は、何かしら問題が発生しているので、JOBLOGを確認しましょう。

4-4. JOB実行結果の確認

JOBが正常終了したのが確認できたので、最後にデータセットが本当に作成されたのか確認してみましょう。

何度かF3を押して画面を戻っていきデータセットをリストする画面を表示しましょう。

データセットをリストする画面

特に何も変えずに、Enterを押しましょう。

データセットの一覧

JCLで作成された、HERC01.JCL.TESTが確認できました。

中身は何も入っていないですが、JCLでデータセットを作成することができました。

以上が今回やりたかったJCLの作成/実行の手順です。

 

ステップ05. 最後に

今回はJCLを作成し、実行するところまで実施しました。

いかがだったでしょうか?
Windowsで.batという拡張子のファイルを作成して実行する方がとても簡単ですね。

今回の例は非常にシンプルなデータセット作成でしたが、現実のメインフレームでは、複雑なジョブが連携して、日々膨大なデータ処理をこなしています。
今日学んだ「JOB、EXEC、DD、COND CODE」の基本が理解できれば、そうしたジョブの挙動も少しずつ追えるようになるかもしれませんね。

Comments