There are actually 2 IBM JCLs: one for the operating system lineage that begins with DOS/360 and whose latest member is z/VSE; and the other for the lineage from OS/360 to z/OS. They share some basic syntax rules and a few basic concepts, but are otherwise very different.
In both DOS and OS JCL the first "card" must be the JOB card, which:
Procedures (commonly called procs) are pre-written JCL for steps or groups of steps, inserted into a job. Both JCLs allow such procedures. Procs are used for repeating steps which are used several times in one job, or in several different jobs. They save programmer time and reduce the risk of errors. To run a procedure one simply includes in the JCL file a single "card" which copies the procedure from a specified file, and inserts it into the jobstream. Also, procs can include parameters to customize the procedure for each use.
Strictly speaking both operating system families use only 71 characters per line. Characters 73-80 are usually card sequence numbers which the system printed on the end-of-job report and are useful for identifying the locations of any errors reported by the operating system. Character 72 is usually left blank to separate the real JCL from any sequence numbers, but in OS JCL it can contain a continuation character for comments (see below).
All commands, parameter names and values have to be in capitals, except for USS filenames.
All lines except for in-stream input (see below) have to begin with a slash "/", and all lines which the operating system processes have to begin with two slashes "//" - always starting in the first column. However, there are two exceptions: the delimiter statement and the comment statement. A delimiter statements begins with a slash and an asterisk (/*), and a comment statement begins with a pair of slash and asterisk (//*).
Many JCL statements are too long to fit within 71 characters, but can be extended on to an indefinite number of continuation cards by:
The structure of the most common types of card is:
DOS and OS JCL have different ways of signaling the start of in-stream input, but both end in-stream input with "/*" at column 1 of the card following the last in-stream data card. This makes the operating system resume processing JCL in the card following the "/*" card.
DD statements can be used to describe in-stream data, as well as data sets. A DD statement dealing with in-stream data has an asterisk (*) following the DD identifier. JCL statements can be included as part of in-stream data by using the DD DATA statements.
copy oldFile newFile
In the OS/360 family one would use something like
//IS198CPY JOB (IS198T30500),'COPY JOB',CLASS=L,MSGCLASS=X
//COPY01 EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DSN=OLDFILE,DISP=SHR
//SYSUT2 DD DSN=NEWFILE,
//SYSIN DD DUMMY
Some of the complexity is due to poor design - but quite a lot of the complexity is due to the environment in which JCL was expected to be used:
DISP=(NEW,CATLG,DELETE)means "if the program runs successfully, create a new file and catalog it; otherwise delete the new file."
JOBcard tells the operating system how to bill the users (account
IS198T30500), what priority the job has relative to other users' jobs (
CLASS=L), and several other things.
tells the computer to print the program's report on the default printer which is loaded with ordinary paper, not on some other printer which might be loaded with blank checks.
DISP=SHRtells the operating system that other programs can read
OLDFILEat the same time.
Despite these difficulties IBM considered it necessary to retain all the features of the original JCLs, to avoid forcing customers to rewrite all their JCL files. But it later introduced easier alternatives such as CLIST. And of course most users save as a procedure any set of JCL statements which is likely to be used more than once or twice.
// TLBL TAPEFIL,'COPYTAPE.JOB',,,,2
// ASSGN SYS005,DISK,VOL=VOL01,SHR
// DLBL DISKFIL,'COPYTAPE.JOB',0,SD
// EXTENT SYS005,VOL01,1,0,800,1600
In DOS JCL parameters are positional, which makes them harder to read and write:
DOS JCL to some extent mitigates the difficulties of positional parameters by using more statements with fewer parameters than OS JCL. In the example the ASSGN, DLBL and EXTENT statements do the same work (specifying where a new disk file should be stored) as a single DD statement in OS JCL.
Later members of the DOS/360 family reduced the number of situations in which model numbers were required.
OS JCL consists of only 3 basic statements:
Right from the start JCL for the OS family (up to and including z/OS) was more flexible and easier to use.
The examples below use the old style of syntax which was provided right from the launch of System/360 in 1964. The old syntax is still quite common in jobs which have been running for over 20 years with only minor changes - these old jobs are often complex, and converting them to use the CLIST syntax would be tricky and time-consuming.
Although the CLIST syntax is easier to read, programmers still have to provide the same amount of information as they would using the old syntax.
//NEWFILE DD DSN=MYFILE01,UNIT=DISK,SPACE=(TRK,50,10),
// DISP=(NEW,CATLG,DELETE)All of the major parameters of OS JCL statements are identified by keywords and can be presented in any order. A few of these contain 2 or more sub-parameters, like SPACE (how much disk space to allocate to a new file) and DCB (detailed specification of a file's layout) in the example above. Sub-parameters are sometimes positional, as in SPACE, but the most complex parameters, such as DCB, have keyword sub-parameters.
Positional parameter must precede keyword parameters. Keyword parameters always assign values to a keyword using the equals sign (=).
//MYPROC PROC &FNAME=MYFILE01,&SPTYPE=TRK,&SPINIT=50,&SPEXT=10,&LR=100,&BLK=1000
//NEWFILE DD DSN=&FNAME,UNIT=DISK,SPACE=(&SPTYPE,&SPINIT,&SPEXT),
....In this example all the values beginning with ampersands "&" are parameters which will be specified when a job requests that the procedure be used. The PROC statement, in addition to giving the procedure a name, allows the programmer to specify default values for each parameter. So one could use the one procedure in this example to create new files of many different sizes and layouts. For example:
//JOB01 JOB ..........
//STEP01 EXEC MYPROC FNAME=JOESFILE,SPTYPE=CYL,SPINIT=10,SPEXT=2,LR=100,BLK=2000or
//JOB02 JOB ..........
//STEP01 EXEC MYPROC FNAME=SUESFILE,SPTYPE=TRK,SPINIT=500,SPEXT=100,LR=100,BLK=5000
//STEP01 EXEC PGM=MYPROG
//NEWFILE DD DSN=MYFILE01,UNIT=DISK,SPACE=(TRK,50,10),DCB=BLKSIZE=1000,
// DISP=(NEW,CATLG,DELETE)the new file will have a block size of 1000 bytes even if code in program MYPROG says the block size should be something else - so there's no need to change program MYPROG. On the other hand since this example does not specify the LRECL (record length) sub-parameter of DCB, the record length will be whatever MYPROG says.
//MYPR01 EXEC PGM=..........
//NEWFILE DD DSN=&MYFILE,UNIT=DISK,SPACE=(TRK,50,10),
//MYPR02 EXEC PGM=..........
//INPUT01 DD DSN=*.MYPR01.NEWFILEstep MYPR02 uses the file identified as NEWFILE in step MYPR01 (DSN means "dataset name" and specifies the name of the file).
In jobs which contain a mixture of job-specific JCL and procedure calls, a job-specific step can refer back to a file which was fully specified in a procedure, for example
//MYJOB JOB ..........
//STEP01 EXEC MYPROC Using a procedure
//STEP02 EXEC PGM=......... Step which is specific to this job
//INPUT01 DD DSN=*.STEP01.MYPR01.NEWFILEwhere DSN=STEP01.MYPR01.NEWFILE means "use the file identified as NEWFILE in step MYPR01 of the procedure used by step STEP01 of this job". Using the name of the step which called the procedure rather than the name of the procedure allows a programmer to use the same procedure several times in the same job without confusion about which instance of the procedure is used in the referback.
//MYJOB JOB ..........
//* Lines containing only comments.
//******** Often used to divide JCL listing into sections ********
//STEP01 EXEC MYPROC Comment 2 on same line as statement
//STEP02 EXEC PGM=......... Comment 3 has been extended and X
// overflows into another line.
//INPUT01 DD DSN=STEP01.MYPR01.NEWFILE
//INPUT01 DD DSN=MYFILE01,DISP=SHR
// DD DSN=JOESFILE,DISP=SHR
// DD DSN=SUESFILE,DISP=SHRThe 2nd and third statements have no value in the name field, so OS treats them as concatenations. The files must be of the same basic type (almost always sequential), and must have the same record length.
OS JCL refers to the return code as COND ("condition code"), and can use it to decide whether to run subsequent steps. However, unlike most modern programming languages, conditional steps in OS JCL are not executed if the specified condition is true—thus giving rise to the mnemonic, "If it's true, pass on through [without running the code]." To complicate matters further, the condition can only be specified after the step to which it refers. For example:
//MYJOB JOB ...........
//STEP01 EXEC PGM=PROG01
//STEP02 EXEC PGM=PROG02,COND=(4,GT,STEP01)
//STEP03 EXEC PGM=PROG03,COND=(8,LE)
//STEP04 EXEC PGM=PROG04,COND=(ONLY,STEP01)
//STEP05 EXEC PGM=PROG05,COND=(EVEN,STEP03)
This translates to the following pseudocode:
if STEP01's return code is greater than 4 then
if any previous return code is less than or equal to 8 then
if STEP01 abnormally ended then
if STEP03 abnormally ended then
Note that by reading the steps containing COND statements backwards, one can understand them fairly easily. This is an example of logical transposition.