【MVS】MVS環境で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を見ながら、少しずつ慣れていきましょう。
ステップ03. JCLの三大要素!これだけは覚えよう
見ている方も一緒にJCLを作成できるように、まずはIPLからTSOでログインまで以下の記事をみて実施してみてください。
また、今回JCLを作成し保管する場所は前回の記事で作成した区分データセットの中なので、よかったら以下の記事から進めていってください。
3-1.JCL用のメンバーを作成する
JCLを作成するには、まず前回作成した区分データセットの中に、メンバーを作成します。
メンバーは、区分データセットの中に作成するデータで、「Windows等で例えると、フォルダの中にファイルを作成する」とイメージしてもらえばOKです。
IPLが終わって、TSOにログインした画面から進めていきます。
まずは、ISPFの画面で「3.4」と入力してEnterを押しましょう。

次の画面で、以下のように入力してEnterを押しましょう。
Data set name prefix ==> HERC01_________________________
Volume serial number ==> WORK02

すると、WORK02というボリューム(記憶装置)に前回作成したデータセットが確認できると思います。
TABでカーソルをHERC01.TEST.PDS.LIBの場所に持っていき、Eを押してEnterを押しましょう。

前回の記事で作成したTEST01があると思います。
今回は新しくメンバーを作成しましょうCommandの箇所に「S△JCL001」と入力してEnterを押しましょう。


まずは、先ほど説明した「//」を10行書きましょう。
…10行も連続で「//」をいちいち入力するのは面倒なので、画面の左側にある赤いシングルクォーテーションが並んでいるところ(※)に、コマンドを入力して一気に作成しましょう。(行コマンドは多用するので、覚えておきましょう)
※行コマンドフィールド(Line Command Field)といいます
まずは1行分「//」と入力し、行コマンドフィールドに「R10」と入力してEnterを押しましょう。


すると、対象の行に入力した情報が複製されます。
行コマンドには、以下の種類があります。
データの挿入・削除・複製
コマンド | 意味 | 説明 |
I | Insert (挿入) | この行の後に新しい行を1行挿入します。`I5`のように数字を付けると、5行挿入します。 |
D | Delete (削除) | この行を削除します。`D3`で3行削除、`DD`で囲んだブロックを削除します。 |
R | Repeat (複製) | この行を1行複製します。`R5`で5回複製、`RR`で囲んだブロックを複製します。 |
データのコピー&ペースト、移動
コマンド | 意味 | 説明 |
C | Copy (コピー) | この行をコピーします。`CC`でブロックの開始と終了を指定します。 |
M | Move (移動) | この行を移動(切り取り)します。`MM`でブロックの開始と終了を指定します。 |
A | After (後に配置) | コピー/移動したデータを、この行の**後**に貼り付けます。 |
B | Before (前に配置) | コピー/移動したデータを、この行の**前**に貼り付けます。 |
O | Overlay (上書き) | コピー/移動したデータを、この行の上に重ねて貼り付けます。`OO`でブロックを指定します。 |
使い方:
- コピーしたい行の行コマンドフィールドに `C` を入力します。
- 貼り付けたい箇所の行に `A` (その行の後) または `B` (その行の前) を入力します。
- Enterキーを押すと、コピー&ペーストが実行されます。移動 (`M`) も同様です。
表示の制御
コマンド | 意味 | 説明 |
X | Exclude (非表示) | この行を画面上から非表示にします。`XX`でブロックを指定します。データ自体は削除されません。 |
F | First (先頭表示) | 非表示になっているブロックの、最初の行を表示します。`F5`で先頭から5行表示します。 |
L | Last (末尾表示) | 非表示になっているブロックの、最後の行を表示します。`L5`で末尾から5行表示します。 |
S | Show (表示) | 非表示になっている行の詳細を表示します。 |
COLS | Columns (桁表示) | 桁位置を示すルーラーを表示します。 |
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が以下の画像です。

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でデータが保存されます。

4-3. ジョブの投入!SUBMITコマンド
ではいよいよ作成したJCLを実行してみましょう。
作成したJCLのCommandの行に「SUB」と入力してEnterを押しましょう。
SUBは、SUBMITのことで、このコマンドを入れることで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