Основы JCL для начинающих: от теории к практике

Этот курс предназначен для знакомства с языком управления заданиями (JCL) в среде мейнфреймов IBM. Вы изучите базовый синтаксис, ключевые операторы и научитесь создавать рабочие сценарии с разбором реальных примеров.

1. Введение в JCL: структура, синтаксис и основные правила написания кода

Введение в JCL: структура, синтаксис и основные правила написания кода

Добро пожаловать в курс «Основы JCL для начинающих». Если вы решили погрузиться в мир мейнфреймов (Mainframes) и операционной системы z/OS, то первое, с чем вам предстоит столкнуться — это JCL. Это не просто «еще один язык программирования», это ключ к управлению мощнейшими вычислительными машинами в мире.

В этой первой статье мы разберем фундамент: что такое JCL, зачем он нужен, почему он выглядит именно так (спойлер: виноваты перфокарты) и как написать свой первый корректный код.

Что такое JCL и зачем он нужен?

JCL расшифровывается как Job Control Language (Язык Управления Заданиями). Важно сразу понять главное отличие: JCL — это не язык программирования в привычном смысле, как Python, Java или C++. Вы не пишете на нем алгоритмы, циклы for или сложную бизнес-логику.

JCL — это скриптовый язык, который служит «посредником» между вашей программой и операционной системой мейнфрейма (z/OS). Он говорит системе:

  • Кто запускает задачу (информация о пользователе).
  • Какую программу нужно выполнить.
  • Где находятся данные для этой программы (входные файлы) и куда положить результат (выходные файлы).
  • > Представьте, что мейнфрейм — это огромная кухня ресторана, а операционная система — шеф-повар. Программы — это рецепты. А JCL — это заказной чек (тике́т), который официант передает на кухню. В чеке написано: «Столик №5 (JOB), приготовить стейк (EXEC), используя мясо из холодильника №2 (DD)». Без этого чека кухня не узнает, что ей делать, даже если рецепты идеальны.

    !Схема показывает роль JCL как инструкции для операционной системы по запуску программ и работе с данными.

    Наследие перфокарт: правило 80 колонок

    Когда вы впервые видите код JCL, он может показаться архаичным. Причина кроется в истории. JCL создавался в эпоху, когда основным носителем информации были перфокарты. Стандартная перфокарта имела 80 колонок в ширину.

    Хотя физические перфокарты давно исчезли, структура JCL в z/OS до сих пор строго привязана к этому формату. Каждая строка кода JCL — это виртуальная перфокарта длиной в 80 символов.

    Структура строки JCL

    Строка JCL делится на строго определенные поля. Нарушение границ этих полей приведет к ошибке JCL Error, и ваше задание не запустится.

    Рассмотрим анатомию строки:

    | Поле | Колонки | Описание | | :--- | :--- | :--- | | Identifier (Идентификатор) | 1-2 | Почти всегда это два слеша //. Они говорят системе: «Это строка JCL». | | Name (Имя) | 3-10 | Имя задания, шага или файла. Должно начинаться с 3-й колонки. | | Operation (Операция) | 11+ | Команда, которую нужно выполнить (например, JOB, EXEC, DD). | | Parameter (Параметры) | После операции | Аргументы для команды. Отделяются от операции пробелом. | | Comments (Комментарии) | После параметров | Необязательный текст для пояснения кода, отделяется пробелом. | | Sequence (Нумерация) | 73-80 | Исторически использовалось для нумерации карт. Сейчас обычно игнорируется системой, но писать код здесь нельзя. |

    !Визуализация структуры строки JCL с разметкой по колонкам.

    Три кита JCL: JOB, EXEC, DD

    Любое задание (Job) в JCL строится на трех основных операторах. Если вы запомните их, вы поймете 90% логики любого JCL-скрипта.

    1. JOB (Задание)

    Это «паспорт» вашего задания. Оператор JOB всегда идет первым. Он сообщает системе имя задания, информацию о владельце, бухгалтерские данные и глобальные настройки.

    Пример:

    * MYJOB01 — имя задания. * JOB — операция. * Остальное — параметры (номер счета, имя программиста, класс выполнения).

    2. EXEC (Выполнение)

    Это команда «На старт!». Оператор EXEC (Execute) указывает, какую именно программу или процедуру нужно запустить.

    Пример:

    * STEP1 — имя шага (Step name). * EXEC — операция. * PGM=IEFBR14 — параметр, указывающий имя программы (в данном случае это системная «пустышка», которая ничего не делает, но полезна для тестов).

    3. DD (Определение данных)

    Это связующее звено. DD (Data Definition) связывает внутреннее имя файла, которое использует программа, с реальным физическим файлом (датасетом) на диске или ленте.

    Пример:

    * DD1 — имя, которое ищет программа внутри своего кода. * DD — операция. * DSN=... — реальное имя файла в системе.

    Синтаксис и правила написания

    JCL очень чувствителен к синтаксису. Одна лишняя запятая или пробел могут «уронить» задание. Вот свод основных правил, которые нужно выучить наизусть.

    1. Идентификатор //

    Все исполняемые строки JCL обязаны начинаться с // в колонках 1 и 2. Исключение составляют только данные внутри потока (in-stream data), но об этом мы поговорим в следующих статьях.

    2. Имена (Name Field)

    * Имя должно начинаться строго в колонке 3. * Длина имени: от 1 до 8 символов. * Допустимые символы: A-Z, 0-9 и национальные символы (@, #, $). * Первый символ не может быть цифрой.

    3. Пробелы имеют значение

    В JCL пробел — это разделитель полей. * Между именем и операцией должен быть хотя бы один пробел. * Между операцией и параметрами должен быть хотя бы один пробел. * ВНИМАНИЕ: Если вы случайно поставите пробел внутри списка параметров, система посчитает, что параметры закончились и дальше идет комментарий.

    Неправильно:

    (Здесь пробел после запятой перед PARM приведет к ошибке или игнорированию параметра PARM, так как система сочтет его комментарием).

    Правильно:

    4. Комментарии

    Чтобы оставить заметку для себя или коллег, используйте строку, начинающуюся с //* в колонках 1-3.

    Также можно писать комментарии в конце исполняемой строки, отделив их пробелом от последнего параметра.

    5. Перенос строки (Continuation)

    Часто параметры не помещаются в одну строку (помните про ограничение до 71-й колонки, так как 72-80 часто резервируются). Чтобы перенести код на следующую строку:
  • Завершите текущую строку запятой ,.
  • На следующей строке начните с // в колонках 1-2.
  • Оставьте пробелы с 3-й по 15-ю колонку (рекомендуется).
  • Продолжайте писать параметры с 4-й по 16-ю колонку (обычно начинают с 16-й для аккуратности).
  • Пример переноса:

    Параметры: Позиционные и Ключевые

    В поле операндов параметры делятся на два типа:

  • Позиционные параметры: Должны идти в строгом порядке сразу после операции. Их смысл зависит от их места в строке. Например, в операторе JOB первым часто идет информация о бухгалтерии, а вторым — имя программиста.
  • Ключевые параметры (Keyword parameters): Могут идти в любом порядке после позиционных. Они всегда имеют вид КЛЮЧ=ЗНАЧЕНИЕ.
  • * Примеры: CLASS=A, PGM=IEFBR14, DSN=MY.FILE.

    Пример простейшего задания (Hello World)

    Давайте соберем всё вместе и напишем валидный JCL код. Поскольку в JCL нет команды `print(

    2. Оператор JOB: идентификация задания и управление параметрами выполнения

    Оператор JOB: идентификация задания и управление параметрами выполнения

    В предыдущей статье мы заложили фундамент, разобрав структуру строки JCL и «три кита» языка: JOB, EXEC и DD. Мы сравнили JCL с заказным чеком в ресторане, где JOB — это «шапка» чека, определяющая, чей это заказ и кто за него платит.

    Сегодня мы детально разберем оператор JOB. Это первая строка любого задания, и без неё система z/OS просто не примет ваш код к исполнению. Мы узнаем, как правильно представиться системе, как управлять приоритетом выполнения и куда направить отчеты о работе.

    Анатомия оператора JOB

    Оператор JOB выполняет три критически важные функции:

  • Идентификация (Identification): Присваивает заданию уникальное имя.
  • Учет (Accounting): Сообщает системе, на какой счет записать затраченные ресурсы (процессорное время, память).
  • Параметры выполнения (Execution Parameters): Задает глобальные настройки для всего задания (приоритет, лимиты времени, уведомления).
  • Базовый синтаксис выглядит так:

    !Структура оператора JOB с разделением на имя, операцию и типы параметров.

    Имя задания (Job Name)

    Как мы помним, имя начинается с 3-й колонки. В корпоративной среде имя задания часто строго регламентировано. Обычно оно состоит из вашего логина (User ID) и одного-двух дополнительных символов.

    > Важно: Если ваш User ID в системе — USER01, то система безопасности (например, RACF) может разрешить вам запускать только задания, чьи имена начинаются с USER01 (например, USER01A, USER01T). Попытка запустить MYJOB01 приведет к ошибке доступа.

    Позиционные параметры

    Сразу после оператора JOB следуют два позиционных параметра. «Позиционные» означает, что их порядок менять нельзя.

    1. Учетная информация (Accounting Information)

    Это первый параметр. Он может быть простым числом или списком значений в скобках. Эти данные используются биллинговой системой мейнфрейма, чтобы выставить счет вашему департаменту за использование дорогостоящего машинного времени.

    Примеры: * (123456) — просто номер счета. * (1234,DEPT01) — номер счета и отдел.

    2. Имя программиста (Programmer Name)

    Это второй параметр. Это строка длиной до 20 символов, которая помогает идентифицировать владельца задания в логах. Если имя содержит пробелы, его обязательно нужно заключить в апострофы.

    Пример:

    Ключевые параметры (Keyword Parameters)

    После позиционных параметров следуют ключевые. Они записываются в формате КЛЮЧ=ЗНАЧЕНИЕ и могут идти в любом порядке. Именно они дают вам контроль над тем, как будет выполняться задание.

    Рассмотрим самые важные из них.

    CLASS: Где ждать выполнения?

    Параметр CLASS определяет, в какую очередь (Input Queue) попадет ваше задание. Значение — это один символ (A-Z, 0-9).

    Представьте аэропорт. Есть стойки регистрации для эконом-класса, бизнес-класса и экипажа. В z/OS системные администраторы настраивают классы похожим образом:

    * CLASS=A: Обычные задания, средний приоритет. * CLASS=X: Быстрые тестовые задания, но с ограничением по времени. * CLASS=Z: Тяжелые ночные задания, которые запускаются, когда нагрузка на систему минимальна.

    MSGCLASS: Куда отправить отчет?

    Не путайте с CLASS. Параметр MSGCLASS (Message Class) управляет выводом (Output Queue). Когда задание завершится, система сформирует системный лог (JES Log). Куда его деть?

    * MSGCLASS=H (Hold): Положить в очередь удержания. Вы сможете просмотреть его с экрана через утилиту SDSF. * MSGCLASS=A: Отправить сразу на физический принтер (да, в некоторых банках это до сих пор используется). * MSGCLASS=X: Часто используется как стандартный класс для просмотра с экрана.

    MSGLEVEL: Насколько подробным должен быть отчет?

    Этот параметр регулирует «болтливость» системы. Он состоит из двух цифр: MSGLEVEL=(S,M).

  • S (Statements) — нужно ли печатать в лог текст вашего JCL-кода?
  • * 0 — печатать только строку JOB. * 1 — печатать все строки JCL (включая процедуры). * 2 — печатать только сам JCL (без расшифровки процедур).

  • M (Messages) — нужно ли печатать сообщения о выделении устройств и памяти?
  • * 0 — только если задание упало с ошибкой (ABEND). * 1 — всегда печатать все сообщения.

    > Рекомендация: Для отладки и обучения всегда используйте MSGLEVEL=(1,1). Это даст вам полную картину того, что происходило в системе.

    NOTIFY: Кто узнает о завершении?

    Когда вы запускаете задание, оно уходит «в недра» мейнфрейма. Как узнать, что оно закончилось? Параметр NOTIFY указывает системе отправить сообщение конкретному пользователю.

    Обычно используют специальную системную переменную &SYSUID, которая автоматически подставляет ваш логин.

    Когда задание завершится, вы увидите всплывающее сообщение: JOB MYJOB01 ENDED - COMP CODE=0000.

    TIME: Защита от бесконечных циклов

    Параметр TIME ограничивает процессорное время, которое может потратить задание. Это страховка. Если ваша программа попадет в бесконечный цикл, система принудительно остановит её (ABEND S322), когда выйдет время, и не даст «съесть» все ресурсы машины.

    Формат: TIME=(минуты,секунды).

    Пример:

    (Ограничение: 30 секунд процессорного времени).

    REGION: Сколько памяти нужно?

    Параметр REGION запрашивает объем оперативной памяти для шагов задания. Можно указывать в килобайтах (K) или мегабайтах (M).

    * REGION=4M — выделить 4 мегабайта. * REGION=0M — выделить всю доступную память (использовать с осторожностью!).

    Сводная таблица параметров

    | Параметр | Тип | Описание | Пример | | :--- | :--- | :--- | :--- | | (Account) | Позиционный | Номер счета для биллинга | (1234) | | Name | Позиционный | Имя программиста | 'IVANOV' | | CLASS | Ключевой | Очередь на выполнение (вход) | CLASS=A | | MSGCLASS | Ключевой | Очередь вывода логов (выход) | MSGCLASS=X | | MSGLEVEL | Ключевой | Детализация логов | MSGLEVEL=(1,1) | | NOTIFY | Ключевой | Уведомление пользователя | NOTIFY=&SYSUID | | TIME | Ключевой | Лимит CPU времени | TIME=1440 | | REGION | Ключевой | Лимит памяти | REGION=0M |

    Пример идеального заголовка JOB

    Давайте соберем всё вместе. Допустим, мы пишем учебное задание. Нам нужно видеть полный лог, мы хотим получить уведомление о завершении, и нам не нужно много памяти.

    Обратите внимание на запятые в конце строк. Это правило переноса, которое мы обсуждали в первой статье. Такой код легко читать и легко поддерживать.

    Распространенные ошибки

  • Отсутствие пробела после JOB.
  • Ошибка:* //MYJOB JOB(123)... Правильно:* //MYJOB JOB (123)...
  • Неверный порядок позиционных параметров. Учетная информация всегда первая, имя программиста — второе. Нельзя написать //JOB 'NAME',(ACCT).
  • Забытая запятая при переносе. Если вы разбили параметры на несколько строк, но забыли запятую в конце первой строки, система проигнорирует вторую строку или выдаст ошибку.
  • Заключение

    Оператор JOB — это ваша визитная карточка в системе z/OS. Правильная настройка параметров CLASS и MSGCLASS гарантирует, что ваше задание запустится быстро, а результаты вы найдете там, где ожидаете. Использование NOTIFY и MSGLEVEL сэкономит вам часы при отладке.

    В следующей статье мы перейдем к «сердцу» задания — оператору EXEC, и узнаем, как запускать программы и передавать им параметры.

    3. Оператор EXEC: запуск программ, процедур и управление условиями выполнения (COND)

    Оператор EXEC: запуск программ, процедур и управление условиями выполнения (COND)

    Мы продолжаем наше путешествие по миру JCL. В первой статье мы разобрали структуру «перфокарты», во второй — научились заполнять «паспорт» задания с помощью оператора JOB. Теперь, когда система знает, кто мы такие и кто оплачивает банкет, пришло время перейти к главному блюду.

    Оператор EXEC (Execute) — это сердце любого шага (Step) в JCL. Именно здесь мы говорим системе: «Запусти вот эту программу» или «Выполни вот этот набор инструкций». Если JOB — это заголовок чека, то EXEC — это конкретные позиции заказа.

    В этой статье мы разберем, как запускать программы и процедуры, как передавать им параметры и, самое главное, как управлять логикой выполнения с помощью одного из самых запутанных параметров в JCL — COND.

    Анатомия оператора EXEC

    Оператор EXEC отмечает начало каждого шага задания (Job Step). В одном задании (Job) может быть до 255 шагов. Каждый шаг выполняется последовательно, один за другим, если не указано иное.

    Базовый синтаксис выглядит так:

    Имя шага (Step Name)

    Как и в операторе JOB, имя шага начинается с 3-й колонки. Оно не является строго обязательным, но настоятельно рекомендуется его указывать. Без уникального имени шага вы не сможете ссылаться на него в дальнейшем (например, для проверки условий выполнения или перезапуска задания с определенного места).

    Что мы запускаем: PGM vs PROC

    У оператора EXEC есть два основных способа указать, что именно нужно выполнить. Это первый позиционный параметр.

    1. Запуск программы (PGM)

    Если вы хотите запустить скомпилированную программу (Load Module) или системную утилиту, вы используете ключевое слово PGM.

    В данном примере IEFBR14 — это имя программы. Кстати, IEFBR14 — это знаменитая системная утилита-пустышка. Она не делает абсолютно ничего и сразу завершается успешно. Её часто используют для тестирования синтаксиса JCL или для удаления/создания файлов через параметры DD (о которых мы поговорим в следующей статье).

    2. Запуск процедуры (PROC)

    Процедура (Procedure или PROC) — это заранее написанный кусок JCL-кода, сохраненный в системной библиотеке. Это аналог функций или макросов в языках программирования. Процедуры позволяют не переписывать одни и те же строки кода сотни раз.

    Для запуска процедуры можно использовать ключевое слово PROC, но чаще всего его опускают и просто пишут имя процедуры.

    Или полная форма:

    !Сравнение запуска программы и процедуры: PGM вызывает исполняемый модуль, а PROC вызывает набор JCL-команд.

    Передача данных в программу: Параметр PARM

    Иногда программе нужно передать небольшие вводные данные прямо из JCL, не создавая для этого отдельный файл. Для этого используется ключевой параметр PARM.

    Ограничения PARM: * Максимальная длина строки — 100 символов. * Если в строке есть спецсимволы, её нужно брать в апострофы.

    Программа получит эту строку при запуске и сможет разобрать её, чтобы настроить свою логику (например, режим работы «NEW» и дату).

    Коды возврата (Return Codes)

    Прежде чем переходить к условиям, нужно понять, что такое код возврата. Когда любой шаг завершается, он сообщает системе число — Return Code (RC). Это оценка того, как прошла работа.

    Стандартные значения RC в мире мейнфреймов:

    | Код (RC) | Значение | Описание | | :--- | :--- | :--- | | 0000 | OK | Все прошло успешно. | | 0004 | WARNING | Предупреждение. Задание выполнено, но были мелкие недочеты. | | 0008 | ERROR | Ошибка. Часть задания не выполнена. | | 0012 | SEVERE | Серьезная ошибка. Результаты недостоверны. | | 0016 | TERMINAL | Фатальная ошибка. Программа не смогла работать. |

    Эти коды — основа для управления логикой выполнения следующих шагов.

    Управление потоком: Параметр COND

    Вот мы и подошли к самому сложному для новичков моменту. Параметр COND (Condition) определяет, нужно ли выполнять текущий шаг, основываясь на результатах предыдущих.

    Главная проблема восприятия COND заключается в его обратной логике.

    > В обычных языках программирования (IF): «Если условие истинно, то СДЕЛАЙ это». > В JCL (COND): «Если условие истинно, то ПРОПУСТИ (не делай) это».

    Запомните мантру: «Если True, то Skip» (Если Истина, то Пропусти).

    Синтаксис COND

    Параметр COND может быть указан как в операторе JOB (действует на все шаги), так и в EXEC (действует на конкретный шаг).

    Формат записи:

    * Код: Число, с которым мы сравниваем. * Оператор: Логическое сравнение. * Имя_шага (необязательно): Чей код возврата проверять. Если не указано, проверяются все предыдущие шаги.

    Операторы сравнения

    В JCL используются буквенные обозначения операторов:

    * GT (Greater Than) — Больше () * GE (Greater or Equal) — Больше или равно () * EQ (Equal) — Равно () * NE (Not Equal) — Не равно () * LT (Less Than) — Меньше () * LE (Less or Equal) — Меньше или равно ()

    Как читать условие

    Формула проверки выглядит так:

    Где — результат проверки (Истина/Ложь), — константа, которую вы написали в JCL, — оператор сравнения, — реальный код возврата предыдущего шага.

    Если — Истина, шаг НЕ выполняется.

    #### Пример 1: Простая логика

    Читаем: «Если 4 меньше, чем RC предыдущего шага, то пропустить STEP2».

    Математически:

    Где — наша константа, — оператор LT, — код возврата предыдущего шага.

    * Если предыдущий шаг вернул 0: — Ложь. Шаг выполняется. * Если предыдущий шаг вернул 4: — Ложь. Шаг выполняется. * Если предыдущий шаг вернул 8: — Истина. Шаг пропускается.

    Вывод: Этот шаг запустится, только если предыдущие завершились с кодом 0 или 4 (OK или Warning).

    #### Пример 2: Ссылка на конкретный шаг

    Читаем: «Если 0 равно RC шага STEP1, то пропустить».

    Математически:

    Где — константа, — оператор EQ, — код возврата шага STEP1.

    Это означает: «Выполнять STEP3 только в том случае, если STEP1 завершился с ошибкой (не 0)». Если STEP1 прошел успешно (0), условие станет Истиной, и STEP3 будет пропущен.

    !Визуализация обратной логики COND: если условие выполняется, шаг пропускается.

    Специальные значения COND

    Существуют два особых параметра, которые не требуют цифр:

  • COND=EVEN
  • Выполнить этот шаг, даже если предыдущие шаги упали с ошибкой (Abend). Обычно, если шаг падает аварийно, задание прекращается. EVEN заставляет шаг выполниться в любом случае (например, для очистки временных файлов).

  • COND=ONLY
  • Выполнить этот шаг только если предыдущий шаг упал с ошибкой (Abend). Полезно для отправки уведомлений об аварии.

    Конструкция IF / THEN / ELSE

    В современных версиях z/OS можно использовать более привычную конструкцию IF, которая работает с прямой логикой.

    Это гораздо легче читать, но знание COND обязательно, так как миллионы строк легаси-кода написаны именно с ним.

    Переопределение параметров (Region и Time)

    В операторе EXEC можно указывать параметры REGION (память) и TIME (время процессора), которые мы изучали в статье про JOB.

    Правило простое: EXEC специфичнее JOB. * Если REGION указан в JOB, он применяется ко всему заданию. * Если REGION указан и в JOB, и в EXEC, то для конкретного шага будет использовано значение из EXEC (в большинстве конфигураций, хотя настройки системы могут менять это поведение).

    Пример:

    * STEP1 получит всю доступную память (0M). * STEP2 получит 4 мегабайта (наследуется от JOB).

    Заключение

    Оператор EXEC определяет, что будет делать ваше задание. Мы научились различать программы и процедуры, передавать параметры через PARM и, самое главное, освоили «обратную логику» параметра COND.

    Теперь у нас есть «паспорт» (JOB) и «инструкция к действию» (EXEC). Но чего-то не хватает. Программам нужны данные: файлы для чтения, место для записи отчетов. В следующей статье мы разберем третий кит JCL — оператор DD (Data Definition), который связывает логические файлы программы с физическими данными на дисках.

    Готовьтесь, будет много информации о датасетах!

    4. Оператор DD: определение данных, работа с файлами и параметрами DISP, SPACE, DCB

    Оператор DD: определение данных, работа с файлами и параметрами DISP, SPACE, DCB

    Мы продолжаем наш курс по основам JCL. В прошлых статьях мы научились создавать «паспорт» задания с помощью оператора JOB и отдавать команды на запуск программ через EXEC. Но есть одна проблема: программы редко работают в вакууме. Им нужны данные.

    Представьте, что вы наняли повара (EXEC) приготовить суп. Но если вы не скажете ему, где лежат овощи и в какую кастрюлю налить воду, супа не будет. В мире мейнфреймов роль указателя на ингредиенты и посуду играет оператор DD.

    Сегодня мы разберем третий и последний «кит» JCL — оператор Data Definition. Мы узнаем, как связывать программы с файлами, как создавать новые наборы данных (датасеты) и как управлять их параметрами.

    Что такое DD и зачем он нужен?

    Оператор DD (Data Definition) связывает логическое имя файла, прописанное внутри программы, с физическим устройством или набором данных (Data Set) на дисках мейнфрейма.

    Это разделение — гениальная идея архитекторов z/OS. Программист в коде (например, на COBOL) пишет: «Ччитать данные из файла INPUT». Ему не нужно знать, где именно лежит этот файл, как он называется на диске или сколько места он занимает. Все эти детали указываются в JCL в момент запуска.

    Это позволяет запускать одну и ту же программу с совершенно разными данными, просто меняя JCL, не переписывая код программы.

    !Схема показывает, как JCL связывает внутреннее имя файла в программе с реальным файлом на диске.

    Анатомия оператора DD

    Синтаксис выглядит знакомо:

    * DDNAME (Data Definition Name): Имя, которое начинается с 3-й колонки. Именно это имя ищет программа. Длина — до 8 символов. * DD: Операция. * Параметры: Описание физического файла.

    Рассмотрим ключевые параметры, без которых невозможно представить работу с файлами: DSN, DISP, SPACE и DCB.

    1. DSN: Имя набора данных

    Параметр DSN (или DSNAME) указывает реальное имя файла в файловой системе z/OS.

    Правила именования файлов в z/OS строгие: * Имя состоит из сегментов, разделенных точками. * Максимальная длина всего имени — 44 символа. * Максимальная длина одного сегмента — 8 символов. * Первый символ сегмента должен быть буквой или национальным символом (@, #, N$ — количество записей в блоке. > Теперь для чтения 1000 записей нужно всего 3 обращения к диску. Это в 100 раз быстрее!

    Обычно сейчас ставят BLKSIZE=0, и система сама выбирает оптимальный размер.

    Пример DCB:

    Специальные DD имена

    Существуют зарезервированные имена и значения, которые вы будете встречать постоянно.

    SYSOUT

    Используется для вывода логов программы (аналог stdout).

    Звездочка * означает: «Используй тот же класс вывода, что указан в MSGCLASS в операторе JOB».

    SYSIN и данные в потоке (Instream Data)

    Если вы хотите передать данные программе прямо в тексте JCL, используйте DD *.

    /* в первых двух колонках означает конец данных.

    DUMMY

    Аналог /dev/null в Linux. Если программа требует файл, но он вам сейчас не нужен, отправьте его в никуда.

    Итоговый пример

    Давайте соберем знания из всех статей и напишем шаг копирования файла с помощью утилиты IEBGENER (стандартная утилита копирования).

    Заключение

    Оператор DD — это мост между абстрактным кодом и реальным железом. Мы разобрали, как именовать файлы (DSN), как управлять их судьбой (DISP), как просить место (SPACE) и как определять формат (DCB).

    Теперь вы умеете писать полноценные задания: от заголовка JOB до запуска EXEC и определения данных DD. В следующих статьях мы углубимся в полезные системные утилиты, которые избавят вас от необходимости писать код для рутинных задач копирования и сортировки.

    5. Практика и утилиты: использование процедур, стандартных утилит IBM и отладка ошибок

    Практика и утилиты: использование процедур, стандартных утилит IBM и отладка ошибок

    Поздравляю! Вы прошли теоретический экватор. Мы уже умеем создавать «паспорт» задания (JOB), запускать программы (EXEC) и управлять данными (DD). Но в реальной жизни писать каждый раз JCL с нуля — это долго, неэффективно и чревато ошибками.

    В этой завершающей статье курса мы перейдем к практике. Мы узнаем, как не изобретать велосипед, используя готовые процедуры и стандартные утилиты IBM, а также научимся читать страшные коды ошибок (ABEND), чтобы понимать, почему задание упало.

    Процедуры (PROC): принцип «Напиши один раз, используй везде»

    Представьте, что у вас есть сложный шаг задания: запуск программы с десятью входными файлами. Если эту программу нужно запускать в 50 разных заданиях, копировать 20 строк кода в каждое из них — плохая идея. Если имя одного файла изменится, вам придется править 50 файлов.

    Для решения этой проблемы в JCL существуют процедуры (Procedures или PROCs). Это именованные блоки JCL-кода, которые можно вызывать одной строкой.

    Типы процедур

  • Каталогизированные процедуры (Cataloged Procedures): Хранятся в специальных системных библиотеках (обычно SYS1.PROCLIB). Они доступны всем пользователям системы.
  • Внутренние процедуры (Instream Procedures): Описываются прямо внутри вашего задания (в начале JCL) и доступны только этому заданию.
  • Синтаксис процедуры

    Процедура начинается с оператора PROC и заканчивается оператором PEND.

    Пример внутренней процедуры:

    Когда система видит EXEC MYPROC, она подставляет вместо этой строки всё содержимое между PROC и PEND.

    !Визуализация того, как JCL-интерпретатор разворачивает вызов процедуры в полный код.

    Символические параметры

    Сила процедур — в гибкости. Вы можете использовать переменные (символические параметры), чтобы менять поведение процедуры при вызове. Переменные начинаются с амперсанда &.

    Определение процедуры с параметром:

    Вызов с заменой параметра:

    В этом случае &FILE внутри процедуры заменится на MY.REAL.DATA. Если параметр не передать, используется значение по умолчанию (DEFAULT.FILE).

    Стандартные утилиты IBM: швейцарский нож мейнфреймщика

    Вам не нужно писать программу на COBOL или Assembler, чтобы просто скопировать файл, отсортировать строки или создать пустой датасет. IBM поставляет вместе с z/OS набор мощных утилит.

    Рассмотрим «большую тройку», которую должен знать каждый.

    1. IEFBR14: Искусство ничего не делать

    Название звучит сложно, но это самая простая программа в мире. Она состоит из одной инструкции процессора: «Вернуться обратно» (Branch to Register 14). Она не делает ничего.

    Зачем она нужна? Помните оператор DISP? Система создает или удаляет файлы до и после выполнения программы. Запуская IEFBR14, мы заставляем систему обработать карты DD.

    * Создать файл: DISP=(NEW,CATLG) * Удалить файл: DISP=(OLD,DELETE)

    Пример удаления файла:

    2. IEBGENER: Копирование данных

    Утилита для копирования последовательных наборов данных (Sequential Datasets). Она берет данные из SYSUT1 и перекладывает их в SYSUT2.

    Пример копирования файла:

    * SYSUT1: Откуда берем (Input). * SYSUT2: Куда кладем (Output). * SYSPRINT: Куда писать отчет о работе. * SYSIN: Управляющие команды (DUMMY, если просто копируем всё подряд).

    3. DFSORT (или SORT): Сортировка и фильтрация

    Мощнейшая утилита для сортировки, слияния и фильтрации данных. Она управляется через SYSIN.

    Пример: Отсортировать файл по фамилии (начинается с 1-й колонки, длина 20 символов).

    Команда SORT FIELDS=(1,20,CH,A) означает: * 1: Начать с 1-го байта. * 20: Длина поля 20 байт. * CH: Тип данных — символы (Character). * A: По возрастанию (Ascending).

    Отладка: Что делать, когда всё сломалось?

    В мире мейнфреймов ошибки делятся на два больших лагеря:

  • JCL Errors: Синтаксические ошибки. Задание даже не начало выполняться. Вы забыли пробел, написали DISS вместо DISP или указали несуществующий файл с DISP=OLD.
  • ABEND (Abnormal End): Задание запустилось, но упало в процессе. Это сопровождается кодом ошибки.
  • Топ-5 кодов ABEND, которые нужно знать в лицо

    Коды ошибок в z/OS выглядят как Sxxx (System code) или Uxxxx (User code). Вот самые частые системные коды:

    #### S013 (Open Error) Проблема: Ошибка при открытии файла. Причина: Часто это несоответствие параметров DCB. Например, программа ожидает файл с длиной записи 80 байт (LRECL=80), а вы подсунули ей файл с длиной 100.

    #### S806 (Not Found) Проблема: Система не может найти программу, указанную в PGM=.... Причина: Опечатка в имени программы или вы забыли указать библиотеку (STEPLIB), где эта программа лежит.

    #### Sx37 (B37, D37, E37) — Space Abends Это классика. Ошибка нехватки места на диске. * B37: Закончилось место при записи (не хватило первичного и вторичного пространства). * D37: Закончилось место при первичном выделении (редко, но бывает). * E37: Закончилось место в директории PDS (Partitioned Data Set).

    Решение: Увеличьте значения в параметре SPACE или добавьте RLSE.

    #### S322 (Time Out) Проблема: Задание работало дольше, чем разрешено. Причина: Либо программа попала в бесконечный цикл, либо вы задали слишком жесткий лимит в параметре TIME.

    #### S222 (Cancelled) Проблема: Задание было принудительно отменено. Причина: Оператор или вы сами (через команду cancel) остановили выполнение задания.

    Алгоритм поиска ошибки

  • Откройте JESMSGLG (системный лог).
  • Идите в самый низ и ищите сообщение, начинающееся с IEF450I (информация о завершении).
  • Найдите код ABEND (например, S806).
  • Если это JCL Error, ищите сообщение с текстом ERROR или стрелочкой, указывающей на конкретную строку кода.
  • !Пример того, как выглядит сообщение об ошибке в системном логе z/OS.

    Заключение курса

    Мы прошли путь от понимания того, что такое JCL, до написания сложных заданий с использованием процедур и утилит. JCL — это язык, который не прощает небрежности, но дает абсолютный контроль над ресурсами мейнфрейма.

    Что делать дальше? Лучший способ выучить JCL — это практика. Попробуйте написать задание, которое:

  • Создает файл с помощью IEFBR14.
  • Копирует в него данные с помощью IEBGENER.
  • Сортирует результат с помощью DFSORT.
  • Удачи в освоении z/OS!