COBOL考古(六)
实验 - 使用 Zowe CLI 和自动化
在这个实验中,您将使用 Zowe CLI 自动提交 JCL 以编译、链接和运行 COBOL 程序,并下载输出。如果您还没有安装 Zowe CLI,请参考“安装 Zowe CLI 和插件”部分进行安装。在开发自动化之前,我们将首先以交互方式使用 Zowe CLI。
Zowe CLI - 交互式使用
在本节中,我们将使用 Zowe CLI 以交互方式查看数据集成员、提交作业和查看输出汇总。
在 VS Code 中,打开集成终端(终端 -> 新建终端)。在终端中,输入
zowe --version
以确认 Zowe CLI 已安装,如下图所示。如果尚未安装,请参考“安装 Zowe CLI 和插件”部分。还请注意,默认选择的 shell 是cmd
。建议为此实验选择默认 shell 为bash
或cmd
。为了使 Zowe CLI 能够与 z/OSMF 交互,CLI 必须知道连接详细信息,如主机、端口、用户名、密码等。虽然您可以在每个命令中输入这些信息,但 Zowe 提供了在配置文件中存储这些信息的功能。
如果您在第一个实验中进行了配置,那么您将拥有一个包含您的团队配置文件的文件夹。请确保您的终端位于该位置,并执行以下命令。
1
zowe config list --locations
请执行以下命令,确认您可以连接到 z/OSMF:
1
zowe zosmf check status
通过执行类似以下命令的命令列出您的 ID 下的数据集(请参考下图中的示例输出):
1
zowe files list ds "Z99998.*"
您还可以通过执行类似以下命令的命令列出分区数据集中的所有成员(请参考下图中的示例输出):
1 |
|
Figure 28. zowe files list ds 和 am 命令
接下来,我们将下载我们的 COBOL 和 JCL 数据集成员到本地计算机。在终端中,执行类似以下命令的命令:
1
2zowe files download am "Z99998.CBL" -e ".cbl"
zowe files download am "Z99998.JCL" -e ".jcl"下图显示了一个已完成的示例:
图 29. 使用 CLI 下载和查看数据集成员
接下来,我们将提交位于成员
Z99998.JCL(HELLO)
中的作业。要提交作业、等待其完成并查看所有输出,请执行以下命令:1
zowe jobs submit ds "Z99998.JCL(HELLO)" --vasc
我们也可以分步执行这一步骤,以获取特定输出。请参考接下来的示例,其中包含即将使用的命令。要提交作业并等待其进入 OUTPUT 状态,请执行以下命令:
1
zowe jobs submit ds "Z99998.JCL(HELLO)" --wfo
要列出与此作业 ID 相关的输出,请执行以下命令:
1
zowe jobs list sfbj JOB04064
其中,
JOB04064
是从前一个命令中返回的值。要查看特定的输出文件(COBRUN:SYSOUT),请执行以下命令:
1
zowe jobs view sfbi JOB04064 105
其中,
JOB04064
和105
是从前面的命令中获取的值。图 30. 提交作业,等待完成,然后列出作业的输出,查看特定输出文件
如果需要,您还可以使用以下命令轻松提交作业、等待其完成并下载输出内容(请参考下图中的已完成状态):
1
zowe jobs submit ds "Z99998.JCL(HELLO)" -d .
图 31. 提交作业,等待完成,下载并查看输出
Zowe CLI 考虑了脚本编写。例如,您可以使用
--rfj
标志以 JSON 格式接收输出,以便轻松解析。请参考下图的示例。图 32.
--rfj
标志允许轻松进行编程式使用
Zowe CLI - 编程式使用
在本节中,我们将以编程方式利用 Zowe CLI 来自动化提交用于编译、链接和运行 COBOL 程序的 JCL,并下载输出。一旦您将内容保存到本地,您就可以使用任意数量的分布式脚本和测试工具来消除手动查看输出内容本身的需要。在 Mainframe 中,我们通常使用 REXX Exec、CLIST 等进行自动化,但今天我们将使用 CLI 和分布式工具。
由于我们已经安装了 Node 和 npm,请让我们为自动化创建一个 Node 项目。要在项目的文件夹中初始化项目,请在项目的文件夹中运行
npm init
命令并按照提示操作。您可以通过按回车键接受默认值。只需更改描述和作者字段。请参考下图。请注意,要使用前面部分提到的团队配置文件,此项目必须是 LearnCOBOL 文件夹的子目录。图 33. 使用
npm init
创建项目的package.json
现在我们有了
package.json
,只需用一个clg
脚本替换test
脚本,该脚本运行以下 zowe 命令(请将Z99998
替换为您的高级限定符):1
zowe jobs submit ds 'Z99998.JCL(HELLO)' -d .
您可以随意命名脚本。我之所以建议
clg
,是因为IGYWCLG
过程中的CLG
(这是 JCL 利用的内容)代表编译、链接和运行。现在,只需在终端中输入npm run clg
,即可利用自动化来编译、链接和运行 COBOL 程序,并下载输出进行审查。完成的package.json
和命令执行示例如下图所示。图 34. 最终的
package.json
和npm run clg
执行如果您更喜欢图形触发器,可以像下图所示使用 VS Code。基本上,CLI 使您能够快速构建自己的 z/OS 自定义任务按钮。您还可以调用脚本而不是单个命令,以适应更复杂的情况。
图 35. 通过按钮触发的
clg
任务
数据分区
了解 COBOL 变量以及变量的程序处理对于有效学习 COBOL 语言至关重要。一位经验丰富的 COBOL 程序员必须掌握 COBOL 变量的特性以及使用本章介绍的变量进行的程序处理。其目标是向读者介绍 COBOL 变量的基础知识,同时让读者了解许多高级 COBOL 变量选项。
在本章之后,有一个实验室可以用来编译和执行本章后面提供的 COBOL 源代码。成功编译和执行一个提供的程序后,可以编译第二个提供的 COBOL 程序,该程序有一个小改动。第二个程序中嵌入了一个错误,在编译时会失败。编译失败是一个机会,可以识别与 COMPUTE 语句的操作相关的 PICTURE 子句数据类型的重要性以及如何解决错误。
变量/数据项
- 变量/数据项名称限制和数据类型
PICTURE 子句
PIC 子句符号和数据类型
编写 COBOL 变量/数据项名称
PICTURE 子句字符串表示
文字
比喻常数
数据关系
数据级别
MOVE 和 COMPUTE
实验室
变量/数据项
COBOL 变量,也称为数据项,是一个名称,由 COBOL 程序员选择。所选名称被编码为保存数据的变量,其中数据值可以变化,因此使用通用术语“变量”。COBOL 变量名称也称为“数据名称”。COBOL 变量名称具有限制。
变量/数据项名称限制和数据类型
COBOL 变量名称的限制或规则列表如下:
不能是 COBOL 保留字。
不能包含空格作为名称的一部分。
名称包含字母(A-Z)、数字(0-9)、下划线(_)和连字符(-)。
最大长度为 30 个字符。
连字符不能出现在第一个或最后一个字符。
下划线不能出现在第一个字符。
注意:COBOL 保留字的完整列表可以在 Enterprise COBOL 语言参考的附录 E 中找到。
当将 COBOL 源代码编译为可执行程序时,COBOL 编译器会期望具有属性的命名 COBOL 变量,例如长度和数据类型。在程序执行期间,该变量表示处理内存的定义区域,其中内存位置具有最大长度和指定的数据类型。
以下是最常见的 COBOL 数据类型列表:
数字(0-9)
字母(A-Z)、(a-z)或空格
字母数字混合类型
PICTURE 子句
COBOL 保留字 PICTURE(PIC)确定了由程序员选择的变量名称的长度和数据类型。由 PIC 描述的数据类型通常称为图片子句或 pic 子句。一些简单的图片子句如下:
PIC 9 - 单个数字值,长度为一
PIC 9(4) - 四个数字值,长度为四
PIC X - 单个字母数字(字符)值,长度为一
PIC X(4) - 四个字母数字值,长度为四
PIC 子句符号和数据类型
图片子句的最大长度取决于数据类型和编译器选项。PIC 保留字除了数字型(PIC 9)和字母数字型(PIC X)之外,还有许多其他数据类型。例如,仅包含字母的数据类型被定义为 PIC A。其他 PIC 子句符号包括:
B E G N P S U V Z 0 / + - , . * CR DB cs
其中 cs 是任何有效的货币符号,例如美元符号($)。
所有 PIC 子句符号的详细信息可以在Enterprise COBOL for z/OS 语言参考手册中找到。
编写 COBOL 变量/数据项名称
PIC 子句描述了变量/数据项名称的数据类型。编写变量/数据项名称是在 DATA DIVISION 中完成的。用于描述变量/数据项名称的 COBOL 代码使用层次编号和图片子句。
层次编号 - 记录中字段的层次结构。
变量名称/数据项名称 - 为要在程序中引用的每个字段分配一个名称,并且在程序内必须是唯一的。
图片子句 - 用于数据类型检查。
下面的图 1 是 COBOL 层次编号示例,带有相应的变量/数据项名称和图片子句。
PICTURE 子句字符串表示
某些 PIC 子句符号只能在图片子句字符串中出现一次,而其他符号可以出现多次。例如:
用于保存值 1123.45 的 PIC 子句编码如下,其中 V 代表小数点位置。
PIC 9(4)V99
用于值如 $1,123.45 的 PIC 子句编码如下:
PIC $9,999V99
文字
COBOL 文字是常量数据值,意味着其值不会像变量一样更改。COBOL 语句 DISPLAY "HELLO WORLD!",
是 COBOL 保留字 DISPLAY
后跟文字 HELLO WORLD!
。
比喻常数
比喻常数是指定特定常数值的保留字。比喻常数的示例包括:
ZERO, ZEROS, ZEROES
SPACE, SPACES
HIGH-VALUE, HIGH-VALUES
LOW-VALUE, LOW-VALUES
QUOTE, QUOTES
NULL, NULLS
数据关系
在程序中使用的所有数据之间的关系在数据部分(DATA DIVISION)中定义,通过一种层次编号和层次数的系统。层次指示符和其描述性条目标识程序中的每个文件。层次指示符表示与其关联的任何数据层次结构的最高级别。层次编号和其描述性条目指示特定数据的属性。层次编号可用于描述数据层次结构;它们可以指示此数据具有特殊目的。
层次编号
结构化的层次编号层次关系适用于所有 DATA DIVISION 部分。图 1 显示了程序员选择的层次编号、变量名称和 PIC 子句在文件部分中的层次关系,其中 “01 PRINT-REC” 引用以下 “05” 级变量组,”01 ACCT-FIELDS” 引用以下 “05” 级变量组。请注意,05 级 CLIENT-ADDR 进一步细分为几个 10 级名称。引用名称 CLIENT-ADDR 的 COBOL 代码包括 10 级名称。
图 1. 层次编号层次关系
数据层次
在定义记录之后,可以将其细分以提供更详细的数据引用,如图 1 所示。层次编号是一个 01 到 49 之间的一位或两位整数,或者是三个特殊层次编号之一:66、77 或 88,其中变量名称被分配了与 01-49 层次编号不同的属性。组项内部层次编号之间的关系定义了该组内数据的层次结构。组项包括从其后跟随的所有组和基本项,直到遇到小于或等于该组层次编号的层次编号。基本项是不能进一步细分的项。这些项具有 PIC 子句,因为它们为该项保留存储空间。
MOVE 和 COMPUTE
MOVE 和 COMPUTE 保留字语句改变变量名称的值。图 2 中显示的每个 MOVE 都导致字面值存储在 77 级变量名称中。在图 2 中还显示了 COMPUTE 语句,它将 HOURS * RATE
的值存储在 GROSS-PAY
中。所有三个变量名称都使用 PIC 9 赋予了数值值数据类型,这是 COMPUTE 语句操作所必需的。
图 2. MOVE 和 COMPUTE 示例
实验
注意:加载此实验的所有部分可能需要几秒钟的时间。如果文件未加载,请在悬停在部分栏上时点击刷新按钮。
查看 ‘id’.CBL 数据集中 PAYROL00 COBOL 源代码成员。
从 id.JCL 下拉列表中提交 JCL 成员 PAYROL00。这是 id.JCL(PAYROL00) 编译并成功执行 PAYROL00 程序的地方。
图 3. 提交 PAYROL00 作业
注意: 如果在提交作业后收到此错误消息:
那是因为您是从 .CBL 数据集提交的作业,而不是 .JCL 数据集。
- 查看 PAYROL00 作业输出的编译和执行,参见图 4。
图 4. PAYROL00 输出
接下来,查看 id.CBL 数据集中 PAYROL0X COBOL 源代码成员。
查看并提交 id.JCL 下拉列表中的 JCL 成员 PAYROL0X。这是 id.JCL(PAYROL0X) 编译并执行 PAYROL0X 程序的地方。
查看 PAYROLL0X 作业输出的编译,注意没有执行输出。
您是否注意到此编译与图 5 中显示的先前作业编译之间的差异?
图 5. 比较作业编译
它们之间的不同之处在于与每个作业输出关联的返回/完成代码,如上所示,位于 JOBS 部分中的作业输出名称旁边,或者位于编译输出的末尾,格式为 0Return code ##。返回代码为 12 意味着存在错误,但我们如何知道错误是什么呢?继续了解吧!
在作业输出中找到编译错误 IGYPA3146-S,如图 6 所示。
图 6. IGYPA3146-S 错误信息
请注意,此行告诉您要关注 GROSS-PAY 图片子句,以识别问题。使用这些信息,修改 PAYROL0X COBOL 源代码以修复错误。确保您正在编辑正确的代码。
在修改后,重新提交 PAYROL0X JCL 以验证问题是否已被识别和修正,结果是成功的编译和执行,返回代码为零,如图 7 所示。
图 7. 比较返回代码