65.9K
CodeProject 正在变化。 阅读更多。
Home

CMS/TSO 管道(PipeLines)Windows版 - 第一部分 语法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (4投票s)

2008年7月23日

CPOL

19分钟阅读

viewsIcon

29942

IBM 管道(Windows 版)和 PowerShell 的实现。

下载 PC-Pipes 应用程序库

引言

CMS/TSO PipeLines 是一个运行在IBM大型机上的产品。在z/VM系统上,它在CMS下运行;在z/OS系统上,它在TSO下运行。顾名思义,数据通过一系列内置或用户定义的阶段进行传递。在此过程中,数据可以被修改或从管道中删除。你可能会说,这没什么新颖的。不同之处在于,PipeLines支持并发并行管道,并且数据可以被路由进出管道。

系统要求

虽然PipeLib类库可以从.Net程序访问,但我认为在PowerShell下运行它会更有用。我所有的测试都是通过PowerShell进行的,任何我提供的管道最有可能都是PowerShell脚本。因此,我建议的最低系统要求如下。
PowerShell V1.0
.Net Framework V2

语法

首先,我想描述一下在IBM手册和本产品中使用的语法图。语法图的基础是命令行。命令行的元素是

>>—————><命令行以>>开头,以><结尾。
—————>这表示语法在下方继续。
>—————这表示这是从上方继续的。
直接出现在命令上的选项是必需的。它必须被提供。

    >>——Command——required option———————————><
如果项目堆叠在一个必需选项的下方,这表示必须选择其中一个项目。
>>——Command——┬option1───┬———————><
             ├option2───┤
             └option3───┘
如果一个项目出现在命令行下方,那么它是可选的,可以不提供。
>>——Command——┬—————————─┬———————><
             ├option1───┤
             └option2───┘
如果一个项目出现在命令行上方,那么如果没有提供选项,它就是默认值。
             ┌default—──┐
>>——Command——┼─────————─┼———————><
             ├option1───┤
             └option2───┘
一个选项上方的弧线表示它可以被输入多次,或者可以选择组中的多个选项。下方的弧线表示你可以输入option1和/或option2,如果两者都没有提供,则假定为默认值。如果选项之间需要分隔符,则在弧线上的<之后指定。
            ┌─<────────┐
            │┌default—┐│
>>——Command—┴┼────————┼┴——————><
             ├option1─┤
             └option2─┘
语法片段或组用于当语法的某一部分重复或递归时。它也可以用来简化命令的主行,并将其分解为单独的命令。
>>——Command—┤segment├———><

Group segment
├───segment options────┤
完全用小写字母表示的选项表示用户提供的变量。如果选项完全用大写字母表示或以大写字母开头,那么它就是一个关键字。大写字母表示关键字的最小缩写。
>>——Command——KEYword——variable——————><
在上例中,关键字可以只输入"KEY",而"variable"则是用户提供的数据。

让我们来看一个实际的例子。下面是SQL内置阶段的语法图。

       ┌─<───────────────┐
       │┌NOPAD COLSEP ~─┐│
>>─Sql─┴┼───────────────┼┴┬─────────┬─><
        ├┬PAD───┬───────┤ └┤connect├┘
        │└NOPAD─┘       │
        └COLSEP xorc────┘

Group Connect

         (1)        ┌─<─;──────┐
├─CONNect──┬SQL────┬┴key=value─┴─┤
           ├ODBC───┤
           ├OLE────┤
           └ORACLE─┘

Group Request

├─┬────────────────────┬┬┬─────────┬SELECT─select statement─┬─┤
  │  ┌─<────────────┐  ││└DESCribe─┘                        │
  └(─┴┬────────────┬┴)─┘└DESCribe─tablename─────────────────┘
      ├┬PAD───────┬┤
      │└NOPAD─────┘│
      └COLSEP xorc─┘

Notes
1. When a Connect statement is specified on a Sql stage specification, 
   omit the "Connect" keyword.
关注点
  1. 出现在命令行或下方以及选项行上的规则也适用。请注意"PAD"、"NOPAD"选项,两者只能选择其一,不能同时选择。如果你省略这些选项,则假定默认值为"NOPAD COLSEP ~"。
  2. 你可以选择在阶段规范中提供一个“Connect”语句。如果这样做,根据注释,你将省略“CONNECT”关键字。
  3. “Connect”语句中,你选择连接类型,并指定由分号分隔的定义连接的“key=value”对。
  4. “Group Request”不是SQL阶段语法的一部分。它描述了阶段读取的输入记录。在Request中,你可以覆盖阶段规范中指定的选项,并且选项必须用括号括起来。你可以指定一个SQL select语句,可以选择在前面加上“DESCRIBE”关键字。或者,你可以指定“DESCRIBE”关键字后跟一个表名。

管道定义语法

下面是管道定义的语法图。通过后面的示例进一步解释了语法。

                                          ┌─<─endchar┐
>>──┬─────────────────────────┬┬─────────┬┴┤PipeLine├┴─><
    │  ┌─<─────────────────┐  │├stagesep─┤
    └(─┴┬┬STAGESEP──┬xorc─┬┴)─┘└endchar──┘
        │└SEPerator─┘     │
        ├ENDchar xorc─────┤
        ├ESCape xorc──────┤
        ├NAME─pipename────┤
        └TRACE────────────┘

Group PipeLine

  ┌─<─stagesep───────────────────────────────────────────────┐
├─┴┬────────────────────────────────────────────────────────┬┴─┤
   ├┬────────────┬┬───────────────┬stagename─┬─────────────┬┤
   │└┤LabelGroup├┘└(─┬───┬TRACE─)─┘          └stageoptions─┘│
   │                 └NO─┘                                  │
   └┤LabelGroup├────────────────────────────────────────────┘

Group LabelGroup

├─┬────────────────┬─┤
  ├label:──────────┤
  └label.streamid:─┘
  • 选项
  • STAGESEP xorc
    分隔符
    指定用于分隔管道阶段的字符。它可以指定为单个字符或字符的十六进制数字。默认分隔符是竖线“|”。
    ENDchar xorc
    指定分隔管道中各个管道的字符。它可以指定为单个字符或字符的十六进制数字。没有默认值。
    ESCape xorc
    定义一个转义字符,用于覆盖PipeLine解析器具有特殊含义的字符的处理。任何跟在转义字符后面的字符都将被视为普通字符。没有默认值。
    NAME pipename
    指定与此管道关联的名称。
    TRACE
    开启管道的跟踪。
  • 管道
  • stagesep
    管道的阶段由STAGESEP字符分隔。默认值为“|”。
    endchar
    如果管道中有多个管道,则用ENDCHAR分隔它们。
    如果管道已开启跟踪,则“NO TRACE”将关闭此管道阶段的跟踪。
    TRACE
    为此管道的阶段开启跟踪。如果以“NO”关键字为前缀,则关闭此阶段的跟踪。
    stagename
    要执行的阶段的名称。
    stageoptions
    提供指定阶段所需的任何选项。
    label
    label.streamid
    一个标签,用于标识阶段的其他输入和/或输出数据流。标签的第一次出现称为标签定义。它建立了一个连接点,其他管道中的阶段可以从中接收数据或向其发送数据。每次后续使用相同的标签称为标签引用。使用标签引用来定义阶段的其他输入和输出流。要使用标签引用,请指定一个只包含标签而没有阶段名称的阶段。

    streamid为流分配一个符号名称。通过向标签添加标识符来命名流。将标签紧跟一个点(.)和一个最多4个字母数字字符的组合(该组合必须至少包含一个字母字符),或者一个字母数字字符的组合(该组合必须至少包含一个字母字符)。流标识符必须紧跟一个冒号,中间没有空格。

示例管道

最简单的管道形式包括一系列由STAGESEP字符分隔的阶段定义。

    stage1
   |stage2
   |...
   |stagen
下一个复杂级别是定义一个管道中的多个管道。
        (end ?) stage1-p1
           |...
           |stagen-p1
         ?  stage1-p2
           |stage2-p2
           |...
           |stagen-p2
这里我们指定一个“ENDCHAR”来分隔管道定义中的各个管道。
但是,只有在使用流标签时,管道的全部功能才能实现。

关于数据流的说明。每个管道中的每个阶段默认有两个流:主输入输出流。主输入从管道中的前一个阶段读取数据,主输出写入到管道中的下一个阶段。仅仅定义一个流并不意味着它已连接到任何东西。例如,管道中的第一个阶段有一个主输入,但它未连接,因为没有前一个阶段可以连接。同样,管道中的最后一个阶段有一个主输出,但它未连接。

定义流标签的阶段建立了一个用于额外输入或输出流的连接点。流标签可以在管道中的三个位置之一被引用。

  1. 管道的第一个阶段。
    管道第一个阶段引用的流标签表示在定义阶段创建了一个输出流。定义该标签的阶段将数据写入引用标签后面的阶段。
  2. 在管道中间。
    管道中间引用的流标签在定义阶段创建输入和输出流。来自引用标签前一个阶段的数据被写入定义流标签的阶段。然后,定义阶段将数据写入引用标签后面的阶段。
  3. 管道的最后一个阶段。
    最后一个阶段引用的流标签表示在定义阶段创建了一个输入数据流。来自引用标签前一个阶段的数据被写入定义阶段。
另外请注意,流标签可以被引用多次。每次引用都会创建一个新的输入或输出数据流。数据流被命名和编号如下:
名称数字
主(Primary)0
次级1
第三级2
第四级3
第五级4
第六级5

考虑以下管道段

  1. '(end ?) < file.txt'
  2. '|l:find abc'
  3. '|...'
  4. '|f:faninany'
  5. '|console'
  6. '? l:'
  7. '|...'
  8. '|f:'
这个管道的作用是:
  1. 定义ENDCHAR并读取文件“file.txt”的内容。
  2. 定义流标签l:并执行find阶段。
    此阶段查找字符串abc,从记录的第1列开始。如果找到字符串,则将记录传递给管道中的下一阶段。如果未找到字符串,则记录将被写入由l:定义的數據流,如果已连接。
  3. 处理包含字符串abc(从第1列开始)的记录。
  4. 定义流标签f:并执行faninany阶段。此阶段读取管道中前一个阶段和任何已连接数据流的记录。
  5. 执行console阶段。顾名思义,它将数据写入终端屏幕。
  6. 我们启动一个新的管道并引用流标签l:。由于流标签出现在管道定义的开头,它为第2行中的find阶段创建了次级输出流。未被find阶段选中的记录将进入这里。
    如果稍后在管道中再次引用l:标签,则会为find阶段创建第三级输出流。或者,根据引用发生的位置,可以为find阶段创建一个次级输入数据流。但是,find阶段只支持次级输出流。
  7. 处理记录。
  8. 我们引用流标签f:。由于它位于管道定义的末尾,因此它在定义阶段创建了一个次级输入数据流。它将来自前一个阶段的数据发送到定义了流标签的阶段。在本例中是第4行中的faninany阶段。与find阶段不同,faninany阶段支持多个输入流。如果稍后在管道中再次引用f:标签,我们将创建第三级输入流。

实际案例

此阶段会创建一个内置阶段的HTML表,如果该阶段有文档,则会创建一个链接。请注意,下面的定义看起来就像它在PowerShell脚本中一样。

  1. '(end ?) shell ls ..\..\runtime\* -include *.cs -name '+
  2. '-exclude util.cs,stageprocessor.cs,dispatcher.cs,addcallstream.cs,spec*,codepages.cs,'+
  3. 'old*,parsercntrl.cs,structCntrl.cs'+
  4. '|nlocate /File.cs/'+
  5. '|chop .'+
  6. '|m:faninany'+
  7. '|sort'+
  8. '|l:lookup detail'+
  9. '|spec $<a href="Doc/$ 1 1-* n $.html">$ n 1-* n $</a>$ n'+
  10. '|f:faninany'+
  11. '|literal <a href="Doc/AppendFile.html">>></a>'+
  12. '|literal <a href="Doc/CreateFile.html">></a>'+
  13. '|literal <a href="Doc/ReadFile.html"><</a>'+
  14. '|spec $<td>$ 1 1-* n $</td>$ n'+
  15. '|join 7'+
  16. '|spec $<tr>$ 1 1-* n $</tr>$ n'+
  17. '|literal <table cellspacing="5" cellpadding="5">'+
  18. '|literal append +</table>+'+
  19. '|> StageTable.html'+
  20. '? literal Hostbyaddr Hostbyname NFind StrFind StrFrLabel StrLiteral StrNFind Spec StrToLabel StrWhileLabel'+
  21. '|split'+
  22. '|m:'+
  23. '? shell ls ..\..\rrt\* -include *.html -name '+
  24. '|c:fanout'+
  25. '|chop .'+
  26. '|l:'+
  27. '|hby:nfind Hostby'+
  28. '|str:nfind any /str/'+
  29. '|nf:nfind NFind'+
  30. '|f:'+
  31. '? hby:'+
  32. '|spec $<a href="Doc/GetHost.html">$ 1 1-* n $</a>$ n'+
  33. '|f:'+
  34. '? str:'+
  35. '|if1:if all ^/Stru/ & ^/Strip/'+
  36. '|if2:if find any /strnfind/'+
  37. '|spec $<a href="Doc/Find.html">$ 1 1-* n $</a>$ n'+
  38. '|if2:'+
  39. '|spec $<a href="Doc/$ 1 4-* n $.html">$ n 1-* n $</a>$ n'+
  40. '|if2:'+
  41. '|if1:'+
  42. '|f:'+
  43. '? nf:'+
  44. '|spec $<a href="Doc/Find.html">$ 1 1-* n $</a>$ n'+
  45. '|f:'+
  46. '? c:'+
  47. '|spec $copy ..\..\rrt\$ 1 1-* n $Doc\$ nw'+
  48. '|shell'+
  49. '|cons'
它的作用
  1. shell阶段执行PowerShell命令,本例中是ls。它将列出所有内置阶段的名称,排除那些不是阶段的名称。
  2. 第1行上方的一部分。
  3. 第1行上方的一部分。
  4. nlocate阶段查找字符串File.cs。如果找到字符串,它将丢弃该记录。所有其他记录将被传递到下一阶段。
  5. chop查找记录中的句点。如果找到,它将在该处分割记录。记录中句点之前的部分将被写入下一阶段。句点之后的部分将被丢弃。
  6. 在这里,我们合并了阶段名称的别名和其他阶段名称,以保持与IBM的源兼容性。faninany阶段将在数据可用时从任何已连接的流读取数据。
  7. 按字母顺序对阶段名称进行排序。由于我们没有提供任何键范围,整个记录被用作排序键。
  8. lookup阶段将详细记录与一组主记录进行比较。详细记录从Primary输入流读取。主记录从Secondary输入流读取,该流在第26行创建。与主记录匹配的详细记录被写入Primary输出流。没有匹配主记录的记录被写入Secondary输出流,该流也在第26行创建。写入Primary输出流的任何记录都有一个文档网页。
  9. spec阶段用于修改现有记录和/或将新记录插入数据流。在本例中,我们正在创建指向当前输入记录中的阶段名称的文档页面的链接。我们首先在输出记录的第1列插入<a href="Doc/GetHost.html">。然后,我们将当前记录在Primary输入流中的内容插入到输出记录的下一列,后面跟着字符串</a>。然后将此新记录写入Primary输出。
  10. 请记住第8行的lookup阶段。它写入的记录是Secondary输出,那些没有匹配主记录的记录将在此处的Secondary输入流中结束。faninany阶段将从任何有数据准备读取的输入流中读取一条记录。
  11. 在第4行,我们丢弃了任何包含字符串“File.cs”的记录。在这里,我们将它们添加回来,并链接到已知存在的文档。
  12. 参见第11行。
  13. 参见第11行。
  14. spec阶段创建一个HTML表单元格。
  15. join阶段读取一条记录,并将其与接下来的7条记录连接起来。然后它写入一条包含8个单元格定义的记录。
  16. spec阶段从8个单元格定义创建一个表行。
  17. 默认情况下,literal阶段在读取和写入其Primary输入流中的记录之前,将其文字字符串写入其主输出。因此,表标签将是输出文件中的第一条记录。
  18. 这个literal阶段被指示在读取并写入其Primary输入流中的所有数据之后,写入其文字字符串。因此,结束的表标签将是输出文件中的最后一条记录。
  19. >阶段,它是“CreateFile”的别名,打开指定的ファイル并将其Primary输入流中的数据写入该文件。如果文件已存在,则会被覆盖,否则会创建一个新文件。这是管道中第一个管道的最后一个阶段。
  20. 这是第二个管道的第一个阶段。这个literal阶段插入了一个包含上面省略的别名和其他阶段名称的字符串。
  21. split阶段将记录分解为段,并将每个段写入其Primary输出。在这种情况下,断点是任何空格字符。
  22. 这个引用标签m:将要合并的阶段名称发送到第6行的主要数据流。
  23. 这是第三个管道的第一个阶段,它提取所有文档网页的名称。
  24. fanout阶段将每个输入记录的副本写入所有连接的输出流。在本例中是PrimarySecondary流。
  25. 此阶段将删除文件名中的文件扩展名。参见第5行。
  26. 请记住第8行的lookup阶段。这个标签引用为lookup阶段创建了Secondary输入和输出流。网页列表进入lookup阶段的Secondary输入。lookupSecondary流读取主记录。如果详细记录没有匹配的主记录,则将其写入lookup阶段的Secondary输出。Secondary输出流到下一个阶段。
  27. 此阶段查找以字符串Hostby开头的记录。如果找到,则将其写入Secondary输出流。
  28. 此阶段查找以字符串str开头的记录。比较时不区分大小写。如果找到记录,则将其写入Secondary输出。
  29. 此阶段查找以NFind开头的记录。如果找到,则将其写入Secondary输出。
  30. 此标签引用为第10行的faninany阶段创建了Secondary输入。这是第三个管道的最后一个阶段。
  31. 这是第四个管道的第一个阶段。这个标签引用定义了第27行nfind阶段的Secondary输出。
  32. 此阶段将链接标签设置为GetHost页面,该页面是已知的。
  33. 此标签引用为第10行的faninany阶段定义了Tertiary输入。
  34. 这是第五个管道的第一个阶段。这个标签引用str:定义了第28行nfind阶段的Secondary输出。
  35. if阶段在管道内创建一个If, Else, 和/或 Endif结构。在本例中,由标签if1:定义的ifIf, Endif,由标签if2:定义的ifIf, Else, Endifif1:阶段将加载一个all阶段,该阶段查找不包含指示字符串的记录。如果记录满足all阶段指定的条件,则if阶段将其传递到其Primary输出。如果记录不满足all阶段设置的条件,则将其写入Secondary输出。Primary输出是“true”路径,Secondary输出是“false”路径(通过If, Else, Endif)。所有位于if阶段之后、直到流标签if1:下一次出现的所有阶段构成了true路径。所有位于第二个流标签之后、直到标签下一次出现的所有阶段构成了false路径。当true路径上的记录到达流标签时,它们被写入if阶段的Secondary输入。然后,if阶段将其Secondary输入写入其Tertiary输出流(如果已连接)。如果Tertiary输出未连接,则它们被写入Secondary输出。Tertiary输出实际上是“Endif”。当false路径上的记录到达流标签时,它们被写入if阶段的Tertiary输入。然后,if阶段将其Tertiary输入写入其Tertiary输出。
  36. 这是为if1:标签定义的if的true路径的第一个阶段。
  37. 这是为if2:标签定义的if的true路径的第一个阶段。
  38. 标签引用是内部ifElse
  39. 这是为if2:标签定义的if的false路径的第一个阶段。
  40. 此标签引用是内部ifEndif
  41. 此标签引用是外部ifif1:Endif
  42. 此标签引用为第10行的faninany阶段定义了Quartinary输入。
  43. 这是第六个管道的第一个阶段。这个标签引用nf:定义了第29行nfind阶段的Secondary输出。
  44. 创建NFind阶段的文档页面链接。
  45. 此标签引用为第10行的faninany阶段定义了Quinary输入。
  46. 这是第七个管道的第一个阶段。它接收来自第24行fanout阶段的数据。
  47. 对于每个输入文件名,此spec阶段会创建一个命令,将该文件复制到文档目录。
  48. shell阶段执行由前一个阶段创建的命令。
  49. console阶段将任何输入写入终端屏幕。这让用户知道哪些文件被复制了。

要查看此管道产生的输出,请在此处 转到
此管道的运行时间为1.328125秒。

我将上面生成的表复制到一个网页中。下面的管道将该表转换为“Doc”目录的“index.html”网页。

  1. 'literal <HTML><Head>'+
  2. '|literal append \<Title>Stage Documentation</Title>\'+
  3. '|literal append \<META http-equiv="Content-Type" content="text/html; charset=UTF-8" />\'+
  4. '|literal append \<META http-equiv="Content-Style-Type" content="text/css" />\'+
  5. '|literal append \</Head><Body>\'+
  6. '|append < stagetable.html'+
  7. '|change \Doc/\\'+
  8. '|literal append \</Body></HTML>\'+
  9. '|> Doc\index.html'
  1. 第1至5行生成网页的标题。关于literal阶段的说明。如果未指定选项,它将写入其文字字符串,然后读取并写入其Primary输入。因此,如果没有append选项,标题行将与它们出现的顺序相反。append选项表示读取并写入任何输入数据,然后写入文字字符串。
  2. 参见第1行。
  3. 参见第1行。
  4. 参见第1行。
  5. 参见第1行。
  6. append阶段首先读取并写入任何输入数据。然后它加载指定的阶段并执行它。在本例中,它读取生成的表。
  7. 生成的表引用了“Doc”目录。但页面将位于“Doc”目录中。因此,我们需要从表中删除“Doc”引用。change阶段完成此操作。
  8. 这个literal阶段为网页添加了结束标签。
  9. 最后,我们写入“index.html”文件。

在PowerShell下运行

要从PowerShell脚本调用管道,你需要执行以下操作:
1. 将管道定义为字符串。例如:

$pipe = '(end ?) stem data'+
   '|f:find abc'+
   '|cons'+
 '? f:'+
   '|> notabc.txt'
2. 要运行管道,请使用应用程序提供的Run-Pipe cmdlet。
run-pipe $pipe

有关在PowerShell中创建和使用管道的更多信息,请参阅HowTo

摘要

本文档作为介绍,用于解释下面引用的IBM手册以及我将提供的任何文档中使用的语法。此外,我希望它能展示PipeLines的潜力。第二部分将讨论管道中的数据流。

参考文献

z/VM V5R3.0 Pipelines Reference
z/VM V5R2.0 CMS Pipelines User's Guide
CMS/TSO Pipelines Runtime Library Distribution
作者帮助文件

历史

CMS/TSO PipeLines Windows版 - 第一部分 语法 - CodeProject - 代码之家
© . All rights reserved.