JCLをサブミットして実行後のジョブSYSOUTを読み込み表示するISPFエディター編集マクロ
「REXXからバッチジョブをサブミットして実行後のジョブログを読み込む」の記事で紹介した、JCLをサブミットして実行結果を取得するREXXサンプルを応用したISPFエディターのJOBマクロです。エディターの編集パネルでSUBコマンドを入力すると編集中のデータをJCLとしてサブミットすることができますが、このマクロ「JOB」は、JCLのサブミットに加え実行したジョブの終了を待ち合わせて実行後のジョブのSYSOUTデータを全て読み込んでISPFブラウザーで表示するところまでを一気に行います。
複数のジョブを選択しながら内容を表示するならSDSFを直接使う必要がありますが、編集中のJCLで実行するジョブの実行結果だけを確認するのであればこのマクロも便利です。実際に使う時は、エディターのコマンド行で「SUB」の代わりに「JOB」と入力するだけです。
①REXXプログラム「JOB」をCLISTメンバーとして登録する
任意の区分データセットに下記のREXXプログラムをメンバー名JOBで登録します。できれば「userid.CLIST」のDSNで区分データセットを作るといいです(後述のTSO EXコマンドが簡単になる)。今後はREXXプログラミングも学習してみようとするなら「userid.CLIST」のDSNで作っておくと便利です。
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
/************************* REXX ***************************** * REXX Exec with MVS, TSO and SDSF function under z/OS. * * ======================================================= * * MVS JOB SUBMITTION AND BROWSE JOBS SYSOUT. * * ======================================================= * * USE 'JOB' Command at Editor Panel Command field * * instead of SUBMIT Command. * * * * Place this REXX member into your CLIST dataset and * * concatinate into current SYSPROC/SYSEXEC libraries, * * or place into any dataset in current SYSPROC/SYSEXEC. * * * * CLIST sample for Dynamic concatation. * * (JOB macro ---> &SYSUID..CLIST) * * ===================================== * * FREE DD(SYSPROC) * * ALLOC DD(SYSPROC) DA(CLIST + * * 'VENDOR.CLIST' + * * 'SVTSC.CLIST' + * * 'ISP.SISPCLIB' ) + * * SHR REUSE * * ======================================================= * * This REXX EDITOR macro allocate two working datasets * * during processing. * * DSN=userid.ZZJOBMAC.JCLINx DSORG=PS,RECFM=FB,LRECL=80 * * SPACE=(TRK,(1,1) * * DSN=..MVS temporary dsname DSORG=PS,RECFM=VB,LRECL=260 * * SPACE=(TRK,(10,10) * * ======================================================= * * 2021/SEP/15 T.Kamii(Arteceed) 1st Release Version. * * 2021/SEP/17 T.Kamii(Arteceed) 2nd Release Version. * * 2021/SEP/22 T.Kamii(Arteceed) 2.1 Release Version. * * 2022/OCT/05 T.Kamii(Arteceed) 2.2 Release Version. * * 2023/AUG/05 T.Kamii(Arteceed) 2.3 Release Version. * ************************** REXX ****************************/ rc = SYSCALLS('ON') /* for call SLEEP (UnixSystemService) */ rc = ISFCALLS('ON') /* for call SDSF */ stat = MSG(ON) /* Find available ddname(JCLINx/JOBOUTx) for working dataset and allocate it. ========================================================= */ x=MSG(OFF) DO i=1 TO 8 UNTIL rc=0 ddnjclin='JCLIN'i ddnjobout='JOBOUT'i dsnjclin='ZZJOBMAC.JCLIN'i ADDRESS TSO "ALLOC DD("ddnjclin") DSN("dsnjclin") NEW CATALOG UNIT(SYSALLDA) SPACE(1 1) TRACKS DSORG(PS) RECFM(F B) LRECL(80)" ADDRESS TSO "ALLOC DD("ddnjobout") NEW DELETE UNIT(SYSALLDA) SPACE(10 10) TRACKS DSORG(PS) RECFM(V B) LRECL(260)" END x=MSG(ON) /* Re-allocate the temporary dataset for JCL input to delete at un-allocate later.(non-sms environment only) ========================================================= */ ADDRESS TSO "ALLOC DD("ddnjclin") DSN("dsnjclin") SHR DELETE REUSE" /* Submit batch job. ================= */ x=OUTTRAP('msg.') ADDRESS ISREDIT "MACRO" "REPLACE "dsnjclin" .ZFIRST .ZLAST" ADDRESS TSO "SUBMIT "dsnjclin DO ix=1 to msg.0 UNTIL x = 'IKJ56250I' SAY msg.ix PARSE VAR msg.ix x ' ' y END IF x <> 'IKJ56250I' THEN ix = 1 /* for in case of no shown IKJ56250I in submitted message. R2.2 */ IF rc = 0 THEN DO; PARSE VAR msg.ix x '(' y PARSE VAR y target_jobid ')' y END ELSE EXIT 8 x=OUTTRAP('OFF') /* Synchronize job ended. ====================== */ isfowner = USERID() isfprefix = '*' /* Allow any jobnames R2.2 */ isfcols = 'TOKEN JOBID QUEUE' isfsort = 'JOBID D' target_status = '' DO UNTIL target_status = 'PRINT' ADDRESS SYSCALL "SLEEP (1)" /* CALL SLEEP USS FUNCTION */ ADDRESS SDSF "ISFEXEC ST" /* CALL SDSF/ST FUNCTION */ IF rc <> 0 THEN EXIT 12 DO ix=1 to isfrows UNTIL jobid.ix = target_jobid target_status = queue.ix END END /* Get job all sysout datasets. ============================ */ ADDRESS SDSF "ISFBROWSE ST TOKEN('"token.ix"')" IF rc <> 0 THEN EXIT 12 DO jx=1 to isfline.0 /* loop num of records from */ QUEUE isfline.jx /* isfline.1-x variables and */ END /* stack it to write PS dataset. */ QUEUE '' /* add null line to indicate eod */ ADDRESS MVS "EXECIO * DISKW "ddnjobout" (FINIS" /* write all records from stack */ ADDRESS ISPEXEC "LMINIT DATAID(DDVAR) DDNAME("ddnjobout")" ADDRESS ISPEXEC "BROWSE DATAID(&DDVAR)" /* show it by ISPF Browser */ /* Un-allocate and delete JCLINx/JOBOUTx working datasets. ======================================================= */ ADDRESS TSO "FREE DD("ddnjclin")" ADDRESS TSO "FREE DD("ddnjobout")" rc = SYSCALLS('OFF') rc = ISFCALLS('OFF') EXIT 0 |
SYSOUT出力量が多いジョブを実行することがわかっている場合は、52行目のALLOCコマンドのTRACKSオプションをCYLINDERSに変更したり、割当て数を増やすといいでしょう。さもないとREXX execは実行中にx37ABENDしてしまいます(ABENDしなかった場合でもx37状態になれば途中までしか出力結果は表示されない)。
JOBマクロはTSOセッション内(フォアグラウンド)で直接実行しますから、実行に長時間掛かるジョブのJCLサブミットには向きません。また、SYSOUTの出力量が多いと作業用データセットへのコピー処理に時間が掛かるため、その場合も無応答時間が長くなります。JOBマクロは、ちょっとしたバッチ処理の実行作業を効率よく進めるためには有用ですが、長時間ジョブや大量出力ジョブであればSDSFで実行状況をモニタリングした方がいいでしょう。
ジョブの実行や出力量が予想以上に多く時間が掛かっている時は、ATTNキーを押せばREXX execの処理を途中でキャンセルすることもできます(「REXX execを強制的に終了させる(備忘録)」を参照)。なお、何度も処理をキャンセルした場合は、未解放の作業用データセットが残ってしまっているので、DDLISTユーティリティーでJCLINxとJOBOUTxのDD名を解放するかTSOをログオンし直します。同時起動許容数は8にしているので、並行して8のISPFセッションで同時使用できますが、処理途中でキャンセルした場合は起動許容数がその分減っていきます。
※マクロ実行中は非プロンプト・モードになるので、JOBステートメントが無い場合のジョブ名サフィックス文字の入力を促すプロンプトは表示されません。ユーザーID+Xのジョブ名でサブミットされます(表示されるIKJ56701Iメッセージを参照)。
②編集マクロとしてテストを行う
- 任意のISPFパネル上で下記のコマンドを実行する
- 適当なJCLをエディターで開きSUBの代わりにJOBコマンドを実行する
- ISPFブラウザーが起動されてサブミットしたジョブの実行結果が表示される
1 2 |
TSO ALTLIB ACT APPLICATION(CLIST) DSN(CLIST) TSO ALTLIB DISP |
ALTLIB ACTコマンドは何もメッセージが出なければ正しく実行できています。ALTLIB DISPコマンドの表示結果で、ApplicationレベルのCLISTライブラリーが追加されているかを確認できます。
1 2 3 4 5 |
Current search order (by DDNAME) is: Application-level CLIST DDNAME=SYS00047 System-level EXEC DDNAME=SYSEXEC System-level CLIST DDNAME=SYSPROC *** █; |
1 |
JOB |
テストなので実行時間の短い単純なジョブで試すといいでしょう。JCLが実行されると下記のメッセージが表示されます。***の表示を待って実行キーを押します。
1 2 3 |
JOB jobname(JOBnnnnn) SUBMITTED HH.MM.SS JOBnnnnn $HASP165 jobname ENDED AT SVSCJES2 MAXCC=0000 CN(INTERNAL) *** █; |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Menu Utilities Compilers Help ------------------------------------------------------------------------------------------------ BROWSE userid.ZZJOBMAC.JOBOUT1 Command ===> *********************************************************** Top of Data ************************* 1 J E S 2 J O B L O G -- S Y S T E M S 0 W 1 -- N O D E S V S C J E S 2 0 04.37.05 JOB04014 ---- TUESDAY, 21 SEP 2021 ---- 04.37.05 JOB04014 IRR010I USERID userid IS ASSIGNED TO THIS JOB. 04.37.05 JOB04014 IEF677I WARNING MESSAGE(S) FOR JOB jobname ISSUED 04.37.05 JOB04014 ICH70001I userid LAST ACCESS AT 04:00:51 ON TUESDAY, SEPTEMBER 21, 2021 04.37.05 JOB04014 $HASP373 jobname STARTED - INIT 1 - CLASS A - SYS S0W1 04.37.06 JOB04014 - -----TIMINGS (MINS.)------ |
ジョブのSYSOUT内容等を確認したら、PF3で終了して元のエディター画面に戻ります。
③CLISTライブラリーをSYSPROCまたはSYSEXECに連結する(※テストだけで終えるならこれ以降の作業は不要)
①で登録したREXX編集マクロは、JCL編集画面で「JOB」コマンドとして実行します。そのため、CLISTライブラリーをSYSPROCまたはSYSEXECのDD名で割り振られてデータセットに連結するため割り振り直します。ALTLIBコマンドを使ってCLISTライブラリーをアクティブにする方法では、画面分割で新しいISPFセッションが起動する度にエディター起動前にALTLIBコマンドを実行しなければならず面倒です。
ISPFエディターの編集マクロやREXX exec、CLISTは共用するのであれば、元々のSYSPROC(またはSYSEXEC)に連結されるライブラリーに入れてしまうのが簡単です。しかし、個人的に使うものであれば共用ではなく個人のライブラリー・データセットに入れることになるので、自分のTSOユーザー空間だけでSYSPROC(またはSYSEXEC)に連結する方法を考えねばなりません。以下はその一例です。なお、マクロ名は使いやすくするためにSUBに対してJOBと同じ3文字で付けています(JCLをサブミットするコマンドSUBに対して、ジョブを実行して結果まで表示するのでコマンドJOB)。マクロのコマンド名は8文字以内であれば、元のISPFコマンドと被らなければ任意の名前に変更できます。
- TSOログオンパネルの自動実行コマンドを控える
- 現在のSYSPROCライブラリーを控える(DDLISTコマンドを実行)
- CLISTライブラリー連結用CLISTを作成する
- TSOログオンパネルの自動実行コマンドを変更する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
------------------------------- TSO/E LOGON ----------------------------------- Enter LOGON parameters below: RACF LOGON parameters: Userid ===> xxxxxxx Password ===> New Password ===> Procedure ===> ISPFPROC Group Ident ===> Acct Nmbr ===> INFODIV1 Size ===> 20480 Perform ===> Command ===> ISPF PANEL(ISR@PRIM) Enter an 'S' before each option desired below: -Nomail -Nonotice -Reconnect -OIDcard PF1/PF13 ==> Help PF3/PF15 ==> Logoff PA1 ==> Attention PA2 ==> Reshow You may request specific help information by entering a '?' in any entry field |
画面下方のCommandフィールドの内容を控えます。この例では「ISPF PANEL(ISR@PRIM)」です。
1 2 3 4 5 6 7 8 9 10 |
Current Data Set Allocations Row 139 of 158 Command ===> Scroll ===> CSR Volume Disposition Act DDname Data Set Name Actions: B E V M F C I Q VPUSR1 SHR,KEEP > SYSPROC USER.CLIST VPISV1 SHR,KEEP > VENDOR.CLIST VPSYS2 SHR,KEEP > ISP.SISPCLIB VPUSR1 SHR,KEEP > USER.PROCLIB NEW,DEL > SYSTERM ---------- Allocated to the terminal ------- NEW,DEL > SYSTSPRT ---------- Allocated to the terminal ------- |
任意のISPFパネルでDDLISTコマンドを実行します。DD名SYSPROCで連結されているDSNを控えます。ISPFとSDSFだけを使っているのであれば、ほとんどの場合ユーザー用ライブラリーとISP.SISPCLIBだけで十分ですが、どれを外すと何に影響が出るのかがわからない場合は、面倒でも全部控えます。
1 2 3 4 5 6 7 8 9 |
FREE DD(SYSPROC) ALLOC DD(SYSPROC) DA(CLIST + 'USER.CLIST' + <== ここに元々連結されていた 'VENDOR.CLIST' + データセット名を記述する 'ISP.SISPCLIB' + 'USER.PROCLIB') + SHR REUSE WRITE &SYSUID..CLIST WAS CONCATINATED TO SYSPROC LIBRARIES. ISPF PANEL(ISR@PRIM) <== 最後に1で控えたコマンドを記述する |
上記の内容でCLISTを作成します。自分のCLISTライブラリー(userid.CLIST)に適当なメンバー名で作成します(ここではADDCLIBとします)。元々ログオンパネルで何のコマンドも指定されていなければ、最後の行にコマンドを追加する必要はありません。WRITEステートメントだけで終えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
------------------------------- TSO/E LOGON ----------------------------------- Enter LOGON parameters below: RACF LOGON parameters: Userid ===> xxxxxxx Password ===> New Password ===> Procedure ===> ISPFPROC Group Ident ===> Acct Nmbr ===> INFODIV1 Size ===> 20480 Perform ===> Command ===> EX (ADDCLIB) <== ここを変更する()内は作ったCLISTメンバー名 Enter an 'S' before each option desired below: -Nomail -Nonotice -Reconnect -OIDcard PF1/PF13 ==> Help PF3/PF15 ==> Logoff PA1 ==> Attention PA2 ==> Reshow You may request specific help information by entering a '?' in any entry field |
画面下方のCommandフィールドの内容を変更します。ログオン時にuserid.CLISTがSYSPROCライブラリーに連結されて割り振り直され、元々の自動実行コマンドが実行されます。CLISTを間違えて上手く動かなかった場合は、ログオンパネルの自動実行コマンドを元に戻せばログオンできます。
普段何気なくあるいは当たり前のように使っているISPFやSDSFですが、REXXやCLISTによって様々な独自機能を追加することもできます。上記のJOBコマンドも、REXXプログラミングの応用例の1つです。
④作業用データセットをSMS管理にする場合(※オプション作業)
TSOのユーザーIDと同じ名前で始まる(第1修飾子がTSOユーザーIDと同じ)データセットがSMS管理されるシステムの場合は、必要であればREXXプログラムの中で使用する作業用データセットの割り振りもSMS管理データセット用に修正します。
1 2 3 4 5 6 7 8 9 10 11 |
ADDRESS TSO "ALLOC DD("ddnjclin") DSN("dsnjclin") NEW DELETE ~~~~~~ UNIT(SYSALLDA) SPACE(1 1) TRACKS STORCLAS(????????) ~~~~~~~~~~~~~~~~~~ DSORG(PS) RECFM(F B) LRECL(80)" /* Re-allocate the temporary dataset for JCL input to delete at un-allocate later.(non-sms environment only) ========================================================= */ ADDRESS TSO "ALLOC DD("ddnjclin") DSN("dsnjclin") SHR DELETE REUSE" <== 削除 |
REXXソースコードJOBの最初の処理であるddnjclinのALLOCコマンド(48~49行目)のパラメーターを上記のように変更します。48行目のCATALOGをDELETEに変え、49行目のSPACEパラメーターの後にSTORCLASを追加します。また、59行目の「ADDRESS TSO “ALLOC DD(“ddnjclin”) DSN(“dsnjclin”) SHR DELETE REUSE”」の行を削除します。