Job Control Language (JCL) is a programming language for scripting and launching batch jobs on IBM mainframe computers."Every job submitted for execution ... must include JCL statements" ibm.com JCL code determines which programs to run, and with which files and devices for input and output.and many more aspects such as whether the file is to be retained or deleted, the maximum disk space to which it can grow, the name of a tape to be pre-mounted, and indicate under what conditions to skip a step. Parameters in the JCL can also provide accounting information for tracking the resources used by a job and can set which machine the job should run on.

There are two major variants based on host platform and associated lineage. One version is available on the platform lineage that starts with DOS/360 and has progressed to z/VSE. The other version starts with OS/360 and continues to z/OS which includes JES extensions, Job Entry Control Language (JECL). The variants share basic syntax and concepts but have significant differences.Ashley and Fernandez, Job Control Language, p. 1. The VM operating system does not have JCL as such; the CP and CMS components each have command languages.

Generically, a job control language is any programming language for job control; not just the IBM mainframe one.

Terminology JCL-specific terminology includes:

Data set A file, either temporary or permanent; it may be located on a disk drive, tape storage, or another device.Ashley and Fernandez, Job Control Language, p. 5.McQuillen, System/360–370 Assembler Language, pp. 385–386.

Partitioned data set (PDS) A collection of files; a PDS is commonly used to store textual data such as source code, assembler macros (SYS1.MACLIB), system configuration (SYS1.PARMLIB), reusable JCL procedures (SYS1.PROCLIB), etc. As a collection of files, a PDS is like to an archive file (ZIP, TAR, etc.) which in turn is like a file system directory. A PDS can contain executable code (load modules or program objects) which makes a PDS like a Unix-based static library. A member, once stored, cannot be updated although a member can be deleted and replaced, such as via the IEBUPDTE utility. Since the 1989 release of MVS DFP 3.2, an enhanced version, partitioned data set extended (PDSE) has been available.

Member A file (data set) in a PDS. A member can be accessed by specifying the name of the PDS with the member name in parentheses. For example, the system macro GETMAIN in SYS1.MACLIB can be referenced as .McQuillen, System/360–370 Assembler Language, pp. 288–289, 400.

Unix system services (USS) A complete Unix environment running as part of the MVS base control program. It allows Unix files, scripts, tasks, and programs to run on a mainframe in a POSIX-compliant Unix environment without virtualization.

Motivation Originally, mainframe systems were oriented toward batch processing. Many batch jobs require setup, with specific requirements for main storage, and dedicated devices such as magnetic tapes, private disk volumes, and printers set up with special forms.McQuillen, System/360–370 Assembler Language, pp. 22–24. JCL was developed as a means of ensuring that all required resources are available before a job is scheduled to run. For example, many systems, such as Linux allow identification of required datasets to be specified on the command line, and therefore subject to substitution by the shell, or generated by the program at run-time.

On these systems the operating system job scheduler has little or no idea of the requirements of the job. In contrast, JCL explicitly specifies all required datasets and devices. The scheduler can pre-allocate the resources prior to releasing the job to run. This helps to avoid "deadlock", where job A holds resource R1 and requests resource R2, while concurrently running job B holds resource R2 and requests R1. In such cases the only solution is for the computer operator to terminate one of the jobs, which then needs to be restarted. With job control, if job A is scheduled to run, job B will not be started until job A completes or releases the required resources.

Features common to DOS and OS JCL

Jobs, steps and procedures For both DOS and OS the unit of work is the job. A job consists of one or several steps, each of which is a request to run one specific program. For example, before the days of relational databases, a job to produce a printed report for management might consist of the following steps: a user-written program to select the appropriate records and copy them to a temporary file; sort the temporary file into the required order, usually using a general-purpose utility; a user-written program to present the information in a way that is easy for the end-users to read and includes other useful information such as sub-totals; and a user-written program to format selected pages of the end-user information for display on a monitor or terminal.

In both DOS and OS JCL the first "card" must be the JOB card, which:McQuillen, System/360–370 Assembler Language, pp. 380–382. Identifies the job. Usually provides information to enable the computer services department to bill the appropriate user department. Defines how the job as a whole is to be run, e.g. its priority relative to other jobs in the queue.

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.

Basic syntax Both DOS and OS JCL have a maximum usable line length of 80 characters, because when DOS/360 and OS/360 were first used the main method of providing new input to a computer system was 80-column punched cards.Stern and Stern, Structured COBOL Programming, pp. 528–529. It later became possible to submit jobs via disk or tape files with longer record lengths, but the operating system's job submission components ignored everything after character 80.

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, but it can contain a nonblank character to indicate that the JCL statement is continued onto the next card.

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 in OS JCL begins with a pair of slashes and asterisk (//*) or an asterisk in DOS JCL.

Many JCL statements are too long to fit within 71 characters, but can be extended on to an indefinite number of continuation cards by: OS JCL DOS JCL Ending all actual JCL cards except the last at a point where the syntax requires a comma (,) Ending all actual JCL cards except the last at a point where the syntax requires a comma (,) and a non-blank character in column 72 Starting each continuation card with // in column 1 and then at least 1 space Starting each continuation card with spaces and continuing in column 15

The structure of the most common types of card is:Stern and Stern, Structured COBOL Programming, pp. 529, 531. OS JCL DOS JCL// Name field for this statement, following // with no space between. If this statement does not have a name at least one blank immediately follows the //. Space(s) Statement type Space(s) Parameters, which vary depending on the statement type, separated by commas and with no space between them.// (spaces if this is a continuation of a previous line) Statement type for this statement, following // with a space between. Space(s) Name of resource Space(s) Parameters, which vary depending on the statement type, separated by commas and with no space between them. Positional parameters, followed by keyword parameters.

In-stream input DOS and OS JCL both allow in-stream input, i.e. "cards" which are to be processed by the application program rather than the operating system. Data which is to be kept for a long time will normally be stored on disk, but before the use of interactive terminals became common the only way to create and edit such disk files was by supplying the new data on cards.

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.Stern and Stern, Structured COBOL Programming, pp. 529, 537.

OS JCL: 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, e.g. //SYSIN DD *. JCL statements can be included as part of in-stream data by using the DD DATA statements. An operand named DLM allowed specifying a delimiter (default is "/*"). Specifying an alternate delimiter allows JCL to be read as data, for example to copy procedures to a library member or to submit a job to the internal reader. An example,modeled on https://www.ibm.com/support/knowledgecenter/SSLTBW_2.2.0/com.ibm.zos.v2r2.hasc300/has2z1_Submitting_to_the_internal_reader_from_jobs_or_tasks.htm, using knowledge dating back to when Green Cards came from IBM, and Manix worked for a company owning an IBM card sorter which submits a job to the Internal Reader (INTRDR) and then deletes two files is: //SUBM EXEC PGM=IEBGENER //SYSPRINT DD SYSOUT=Z //SYSUT2 DD SYSOUT=(A,INTRDR) //SYSIN DD DUMMY //SYSUT1 DD DATA,DLM=ZZ //RUNLATR JOB ACCT,MANIX,CLASS=A.TYPRUN=HOLD //* ^ a JOB to run later //CPUHOG EXEC PGM=PICALC1K //OUTPUT DD DSN=PICALC.1000DGTS,SPACE=(TRK,1),DISP=(,KEEP) ZZ //* ^ as specified by DLM=ZZ //DROPOLDR EXEC PGM=IEFBR14 //DELETE4 DD DSN=PICALC.4DGTS,DISP=(OLD,DELETE) //DELETE5 DD DSN=PICALC.5DGTS,DISP=(OLD,DELETE) The program called PICALC1K will await (TYPRUN=HOLD) being released manually The program called IEFBR14 will run NOW and upon completion, the two existing files, PICALC.4DGTS and PICALC.5DGTS will be deleted.

DOS JCL: Simply enter the in-stream data after the EXEC card for the program.

Complexity Fred Brooks, who supervised the OS/360 project in which JCL was created, called it "the worst computer programming language ever devised by anybody, anywhere" in The Design of Design, where he used it as the example in the chapter "How Expert Designers Go Wrong". He attributed this to the failure of the designers to realize that JCL is, in fact, a programming language.