[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS 用户手册


前页 目录 索引

B.9 LISTER.COM 命令过程

提示输入数据,按列格式化数据,并把它排序到输出文件。这个过程说明如何使用 READ 和 WRITE 命令,以及赋值语句的字符子串覆盖格式。

例子: LISTER.COM


$ ! Procedure to accumulate programmer names and document file names.
$ ! After all programmer names and file names are entered, they are
$ ! sorted in alphabetic order by programmer name and printed on
$ ! the system printer.
$ !
$ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")        (1)
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
$ !
$ OPEN/WRITE OUTFILE DATA.TMP         ! Create output file (2)
$ !
$ ! Loop to obtain programmers' last names and file names,
$ ! and write this data to DATA.TMP.
$ !
$ LOOP:                                                    (3)
$        INQUIRE NAME "Programmer (press Return to quit)"
$        IF NAME .EQS. "" THEN GOTO FINISHED
$        INQUIRE FILE "Document file name"
$        RECORD[0,20]:='NAME'                              (4)
$        RECORD[21,20]:='FILE'
$        WRITE OUTFILE RECORD
$        GOTO LOOP
$ FINISHED:
$        CLOSE OUTFILE
$ !
$ DEFINE/USER_MODE SYS$OUTPUT: NL:   ! Suppress sort output
$ SORT/KEY=(POSITION:1,SIZE=20) DATA.TMP DOC.SRT           (5)
$ !
$ OPEN/WRITE OUTFILE DOCUMENT.DAT                          (6)
$ WRITE OUTFILE "Programmer Files as of ",F$TIME()
$ WRITE OUTFILE ""
$ RECORD[0,20]:="Programmer Name"
$ RECORD[21,20]:="File Name"
$ WRITE OUTFILE RECORD
$ WRITE OUTFILE ""
$ !
$ CLOSE OUTFILE                                            (7)
$ APPEND DOC.SRT DOCUMENT.DAT
$ PRINT DOCUMENT.DAT
$ !
$ INQUIRE CLEAN_UP "Delete temporary files [Y,N]"          (8)
$ IF CLEAN_UP THEN DELETE DATA.TMP;*,DOC.SRT;*
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
$ EXIT

LISTER.COM 命令过程注解

  1. LISTER.COM 保存当前校验设置并停掉校验。
  2. OPEN 命令为写入建立临时文件。
  3. INQUIRE 命令提示输入程序员名和文件名。如果通过按下 Return 输入一个空行来响应 INQUIRE 命令的提示,那么过程假定没有其他数据输入,并且转移到标号 FINISHED。
  4. 在赋值给符号 NAME 和 FILE 之后,过程使用赋值语句的字符串覆盖格式来构造符号 RECORD 的值。在 RECORD 的列 1 至 21,写入 NAME 的当前值。命令解释程序用空格填充 NAME 的值使其长度为指定的 20 个字符。
    同样,RECORD 的后 20 列填充为 FILE 的值。然后,把 RECORD 的值写入输出文件。
  5. 在文件关闭之后,过程排序输出文件 DATA.TMP。DEFINE 命令指示 SORT 命令输出到空文件 NL。否则,这些统计将显示在终端上:
    排序执行在前 20 列;即,按程序员名排序。
    排序的输出文件有名称 DOC.SRT。
  6. 过程使用 OPEN 命令建立最终的输出文件 DOCUMENT.DAT。写入文件的第一行是标题行,给出标题、当天的日期和时间和列标题。
  7. 过程关闭文件 DOCUMENT.DAT,并把排序的输出文件 DOC.SRT 附加到这个文件。然后,输出文件排队到系统打印机。
  8. 过程提示确定是否删除中间文件。如果在 INQUIRE 命令提示中输入真回答 (T、t、Y 或 y),那么就删除文件 DATA.TMP 和 DOC.SRT。否则,保留它们。

执行 LISTER.COM 命令过程的样例


$ @LISTER
Programmer: WATERS
Document file name: CRYSTAL.CAV
Programmer: JENKINS
Document file name: MARIGOLD.DAT
Programmer: MASON
Document file name: SYSTEM.SRC
Programmer: ANDERSON
Document file name: JUNK.J
Programmer: [Return]
Delete temporary files [Y,N]:y

这个过程执行的输出文件结果包含以下内容:


Programmer Files as of 31-DEC-1999 16:18:58.79

Programmer Name      File Name

ANDERSON             JUNK.J
JENKINS              MARIGOLD.DAT
MASON                SYSTEM.SRC
WATERS               CRYSTAL.CAV

B.10 CALC.COM 命令过程

执行算术计算,并把结果值转换为十六进制和十进制值。

例子: CALC.COM


$ ! Procedure to calculate expressions.  If you enter an
$ ! assignment statement, then CALC.COM evaluates the expression
$ ! and assigns the result to the symbol you specify.  In the next
$ ! iteration, you can use either your symbol or the symbol Q to
$ ! represent the current result.
$ !
$ ! If you enter an expression, then CALC.COM evaluates the
$ ! expression and assigns the result to the symbol Q.  In
$ ! the next iteration, you can use the symbol Q to represent
$ ! the current result.
$ !
$ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
$ START:
$     ON WARNING THEN GOTO START                           (1)
$     INQUIRE STRING "Calc"                                (2)
$     IF STRING .EQS. "" THEN GOTO CLEAN_UP
$     IF F$LOCATE("=",STRING) .EQ. F$LENGTH(STRING) THEN GOTO EXPRESSION
$ !
$ ! Execute if string is in the form symbol = expression
$ STATEMENT:                                               (3)
$     'STRING' ! Execute assignment statements
$     SYMBOL = F$EXTRACT(0,F$LOCATE("=",STRING)-1,STRING) ! get symbol name
$     Q = 'SYMBOL'        ! Set up q for future iterations
$     LINE = F$FAO("Decimal = !SL       Hex = !-!XL      Octal = !-!OL",Q)
$     WRITE SYS$OUTPUT LINE
$     GOTO START
$ !
$ !
$ ! Execute if string is an expression
$ EXPRESSION:                                              (4)
$     Q = F$INTEGER('STRING')         ! Can use Q in next iteration
$     LINE = F$FAO("Decimal = !SL       Hex = !-!XL      Octal = !-!OL",Q)
$     WRITE SYS$OUTPUT LINE
$     GOTO START
$ !
$ CLEAN_UP:
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
$ EXIT

CALC.COM 命令过程注解

  1. 过程建立一个重新启动过程的出错处理条件。如果发生一个警告或更严重的出错,那么过程转移到重新设置 ON 条件的开始点。
    如果用户输入一个错误的表达式,那么这个技术确保过程将不会退出。
  2. INQUIRE 命令提示输入算术表达式。过程接受的表达式格式如下:

    name = expression


    expression


    如果按下 Return,那么过程假定结束 CALC 对话期并退出。
    如果按格式 "name = expression" 输入,那么过程将在标号 STATEMENT 继续执行。否则,过程转移到标号 EXPRESSION。

  3. 过程执行赋值语句,并把表达式的结果赋值给符号。然后过程抽取符号名,并把符号的值赋值给 Q。这允许您在过程的下一个循环中使用 Q 或您的符号。然后,过程显示结果并转移回标号 START。
  4. 过程求表达式的值,并把结果赋值给符号 Q。这允许您在过程的下一个循环中使用 Q。然后,过程显示结果并转移回标号 START。

执行 CALC.COM 命令过程的样例


$ @CALC
Calc: 2 * 30
Decimal = 60        Hex = 0000003C  Octal = 00000000074
Calc: Q + 3
Decimal = 63        Hex = 0000003F  Octal = 00000000077
Calc: TOTAL = Q + 4
Decimal = 67        Hex = 00000043  Octal = 00000000103
Calc: 5 + 7
Decimal = 12    Hex = 0000000C  Octal = 00000000014
Calc:[Return]
$

在过程的每个提示之后,用户输入一个算术表达式。过程按十进制、十六进制和八进制格式显示结果。通过按下 Return 输入一行不带数据的空行,结束 CALC 对话期。

B.11 BATCH.COM 命令过程

接受一个命令字符串、命令过程或一列命令,然后以批量作业模式执行这些命令。

例子: BATCH.COM


$ VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
$ VERIFY_PROCEDURE = F$VERIFY(0)
$!
$! Turn off verification and save current settings.
$! (This comment must appear after you turn verification
$! off; otherwise it will appear in the batch job log file.)
$!
$!
$! If this is being executed as a batch job,
$! (from the SUBMIT section below) go to the EXECUTE_BATCH_JOB section
$! Otherwise, get the information you need to prepare to execute the
$! batch job.
$!
$ IF F$MODE() .EQS. "BATCH" THEN GOTO EXECUTE_BATCH_JOB    (1)
$!
$!
$! Prepare to submit a command (or a command procedure) as a batch job.
$! First, determine a mnemonic process name for the batch job.  Use the
$! following rules:
$!
$! 1) If the user is executing a single command, then use the verb name.
$!    Strip off any qualifiers that were included with the command.
$! 2) If the user is executing a command procedure, then use the file name.
$! 3) Otherwise, use BATCH.
$!
$ JOB_NAME = P1         (2)
$ IF JOB_NAME .EQS. "" THEN JOB_NAME = "BATCH"
$ IF F$EXTRACT(0,1,JOB_NAME) .EQS. "@" THEN JOB_NAME = F$EXTRACT(1,999,JOB_NAME)
$ JOB_NAME = F$EXTRACT(0,F$LOCATE("/",JOB_NAME),JOB_NAME)
$ JOB_NAME = F$PARSE(JOB_NAME,,,"NAME","SYNTAX_ONLY")
$ IF JOB_NAME .EQS. "" THEN JOB_NAME = "BATCH"
$!
$!
$! Get the current default device and directory.
$!
$ ORIGDIR = F$ENVIRONMENT("DEFAULT")
$!
$!
$! Concatenate the parameters to form the command string to be executed.
$! If the user did not enter a command string, the symbol COMMAND will have
$! a null value.
$!
$ COMMAND = P1 + " " + P2 + " " + P3 + " " + P4 + " " + -  (3)
            P5 + " " + P6 + " " + P7 + " " + P8
$!
$!
$! If the user is executing a single command and if both the command and the
$! original directory specification are small enough to be passed as
$! parameters to the SUBMIT command, then submit the batch job now.
$!
$ IF (P1 .NES. "") .AND. (F$LENGTH(COMMAND) .LE. 255) .AND. -    (4)
        (F$LENGTH(ORIGDIR) .LE. 255) THEN GOTO SUBMIT
$!
$!
$! If the single command to be executed in the batch job is very large, or
$! if you have to prompt for commands to execute in the batch job, then
$! create a temporary command procedure to hold those commands and get the
$! fully expanded name of the command procedure.
$!
$ CREATE_TEMP_FILE:
$   ON CONTROL_Y THEN GOTO CONTROL_Y_HANDLER               (5)
$   OPEN/WRITE/ERROR=FILE_OPEN_ERROR TEMPFILE SYS$SCRATCH:'JOB_NAME'.TMP (6)
$   FILESPEC = F$SEARCH("SYS$SCRATCH:" + JOB_NAME + ".TMP")
$!
$!  By default, have the batch job continue if it encounters any errors.
$!
$   WRITE TEMPFILE "$ SET NOON"
$!
$!  Either write the single large command to the file, or prompt for
$!  multiple commands and write them to the file.
$!
$   IF COMMAND .NES. "       " THEN GOTO WRITE_LARGE_COMMAND
$
$   LOOP:
$       READ /END_OF_FILE=CLOSE_FILE /PROMPT="Command: " SYS$COMMAND COMMAND
$       IF COMMAND .EQS. "" THEN GOTO CLOSE_FILE
$       WRITE TEMPFILE "$ ",COMMAND
$       GOTO LOOP
$
$ WRITE_LARGE_COMMAND:
$   WRITE TEMPFILE "$ ",COMMAND
$
$!
$! Finish the temporary file by defining a symbol so that you will know
$! the name of the command procedure to delete and then close the file.
$! Define the symbol COMMAND to mean "execute the command procedure
$! you have just created."  Then submit the batch job and execute
$! this command procedure in the batch job.
$!
$ CLOSE_FILE:                                              (7)
$   WRITE TEMPFILE "$ BATCH$DELETE_FILESPEC == """,FILESPEC,""""
$   CLOSE TEMPFILE
$   ON CONTROL_Y THEN EXIT
$   COMMAND = "@" + FILESPEC
$!
$!
$! Submit BATCH.COM as a batch job, and pass it two parameters.
$! P1 is the command (or name of the command procedure) to execute.
$! P2 is the directory from which to execute the command.
$!
$ SUBMIT:                                                  (8)
$   SUBMIT/NOTIFY/NOPRINT 'F$ENVIRONMENT("PROCEDURE")' /NAME='JOB_NAME' -
          /PARAMETERS=("''COMMAND'","''ORIGDIR'")
$   GOTO EXIT
$!
$!
$! The user pressed Ctrl/Y while the temporary command procedure was open.
$! Close the command procedure, delete it if it exists, and exit.
$!
$ CONTROL_Y_HANDLER:                                       (9)
$   CLOSE TEMPFILE
$   IF F$TYPE(FILESPEC) .NES. "" THEN DELETE/NOLOG 'FILESPEC'
$   WRITE SYS$OUTPUT "Ctrl/Y caused the command procedure to abort."
$   GOTO EXIT
$!
$!
$! The temporary command procedure could not be created.
$! Notify the user and exit.
$!
$ FILE_OPEN_ERROR:                                         (10)
$   WRITE SYS$OUTPUT "Could not create sys$scratch:",job_name,".tmp"
$   WRITE SYS$OUTPUT "Please correct the situation and try again."
$!
$!
$! Restore the verification states and exit.
$!
$ EXIT:                                                    (11)
$  VERIFY_PROCEDURE = F$VERIFY(VERIFY_PROCEDURE,VERIFY_IMAGE)
$  EXIT
$!
$!
$! BATCH.COM was invoked as a batch job.  P1 contains the command
$! to execute and P2 the default directory specification.
$! Return a status code that indicates the termination status of P1.
$!
$ EXECUTE_BATCH_JOB:                                      (12)
$    SET NOON
$    VERIFY_PROCEDURE = F$VERIFY(VERIFY_PROCEDURE,VERIFY_IMAGE)
$    SET DEFAULT 'P2'
$    'P1'
$    IF F$TYPE(BATCH$DELETE_FILESPEC) .EQS. "" THEN EXIT $STATUS
$    STATUS = $STATUS
$    DELETE /NOLOG 'BATCH$DELETE_FILESPEC'
$    EXIT STATUS

BATCH.COM 命令过程注解

  1. 这个 IF 语句测试 BATCH.COM 是否执行在批量模式下。当交互地调用 BATCH.COM 时,您提供 (作为参数) 一个要执行为一个批量作业的命令字符串或命令过程。如果不提供任何参数,那么 BATCH.COM 提示输入命令,把这些命令写入一个文件,然后把这个命令过程执行为一个批量作业。在 BATCH.COM 准备执行批量作业的命令之后,它使用 SUBMIT 命令把本身提交为一个批量作业,并执行这个作业中的命令。(请参阅注释 8。) 当把 BATCH.COM 调用为一个批量作业时,过程转移到标号 EXECUTE_BATCH_JOB。注意,如果以批量模式执行 BATCH.COM,必须把要执行的命令或命令过程指定为 P1,把默认目录指定为 P2。
  2. 这些命令准备 要执行的批量作业。首先,过程构造批量作业名。如果传递一个命令字符串,那么 BATCH.COM 使用其动词名称作为作业名。如果传递一个命令过程,那么 BATCH.COM 使用其文件名。如果没有传递的输入,那么 BATCH.COM 把这个作业命名为 BATCH。
  3. 连接这些参数,以形成要执行的命令字符串。这个命令字符串被赋予符号 COMMAND。
  4. SUBMIT 命令不能传递大于 255 个字符的参数。因此,过程测试命令字符串和目录名长度是小于 255 个字符的。如果两个字符串都小于 255 个字符 (并且如果用户确实传递了一个命令字符串),那么过程转移到标号 SUBMIT。
  5. 过程建立一个 Ctrl/Y 处理程序,因而在这段命令过程中如果用户按下 Ctrl/Y,就执行清除操作。
  6. 过程建立一个临时文件包含要执行的命令。如果用户提供一个长的命令字符串,那么过程转移到 WRITE_LARGE_COMMAND,并把这个命令写入临时文件。否则,过程提示输入要执行的命令。每个命令被写入临时文件。
  7. 在关闭临时文件之前,把符号赋值语句写入这个文件。这个语句把临时文件的文件名赋值到符号 BATCH$DELETE_FILESPEC。在关闭这个临时文件之后,过程重新设置默认的 Ctrl/Y 处理程序。然后过程定义符号 COMMAND,以便执行时,符号 COMMAND 调用临时的命令文件。
  8. 过程把本身提交为一个批量作业,使用定义的作业名。(请参阅注释 2。) 过程也传递两个参数: 要执行的命令或命令过程,和命令应该从此执行的目录。然后过程转移到标号 EXIT。(请参阅注释 11。)
  9. 当临时文件建立时,如果用户输入 Ctrl/Y,本段就执行清除操作。
  10. 如果不能建立临时文件,本段就写入出错消息。
  11. 过程重新设置原始的校验设置,然后退出。
  12. 当 BATCH.COM 以批量模式运行时,就执行这些命令。首先,撤消 ON 出错处理,并且设置用户的默认校验设置。然后,其默认设置为 P2 指出的目录,并且执行 P1 指出的命令或命令过程。如果建立一个临时文件,那么就删除这个文件。在删除 BATCH$DELETE_FILESPEC 之前,保存 P1 的完成状态。这个完成状态通过 EXIT 命令返回。

执行 BATCH.COM 命令过程的样例


$ @BATCH RUN MYPROG
Job RUN (queue SYS$BATCH, entry 1715) started on SYS$BATCH

这个例子使用 BATCH.COM 运行批量作业中的程序。

B.12 COMPILE_FILE.COM 命令过程

编译、链接和运行用 Pascal 或 FORTRAN 编写的文件。它提示输入要处理的文件,确定文件类型是 .PAS 还是 .FOR。如果文件类型不是 .PAS 或 .FOR,或者如果在当前默认目录中不存在这个文件,那么命令过程输出适当的出错消息。这个过程说明如何使用 IF-THEN-ELSE 语言构造。

例子: COMPILE_FILE.COM


$! This command procedure compiles, links, and runs a file written in Pascal
$! or FORTRAN.
$!
$ ON CONTROL_Y THEN EXIT
$!
$ TOP:
$   INQUIRE FILE "File to process"
$   IF F$SEARCH(FILE) .NES. ""                             (1)
$ THEN
$   FILE_TYPE = F$PARSE(FILE,,,"TYPE") (2)             ! determine file type
$   FILE_TYPE = F$EXTRACT(1,F$LENGTH('FILE_TYPE'),FILE_TYPE) ! remove period
$! Remove type from file specification
$   PERIOD_LOC = F$LOCATE(".",FILE)
$   FILE = F$EXTRACT(0,PERIOD_LOC,FILE)
$   ON WARNING THEN GOTO OTHER
$   GOTO 'FILE_TYPE'
$ ELSE                                                     (3)
$   WRITE SYS$OUTPUT FILE, "does not exist"
$ ENDIF                                                    (4)
$!
$ GOTO END
$!
$!
$!
$ FOR:                                                      (5)
$ ON ERROR THEN GOTO PRINT
$ FORTRAN/LIST 'FILE'
$ GOTO LINK

$!
$ PAS:
$   ON ERROR THEN GOTO PRINT
$   PASCAL/LIST 'FILE'
$   GOTO LINK
$!
$ OTHER:
$   WRITE SYS$OUTPUT "Can't handle files of type .''FILE_TYPE'"
$   GOTO END
$!
$ LINK:                                                    (6)
$   ON ERROR THEN GOTO END
$   WRITE SYS$OUTPUT "Successful compilation ...."
$   LINK 'FILE'
$   DEFINE/USER_MODE SYS$INPUT SYS$COMMAND
$   RUN 'FILE'
$   GOTO CLEANUP
$!
$ PRINT:                                                   (7)
$   WRITE SYS$OUTPUT "Unsuccessful compilation, printing listing file ...."
$   PRINT 'FILE'
$!
$ CLEANUP:
$   DELETE 'FILE'.OBJ;
$   DELETE 'FILE'.LIS;
$!
$ END:
$   INQUIRE/NOPUNCTUATION ANS "Process another file (Y or N)?  "
$   IF ANS THEN GOTO TOP
$ EXIT

COMPILE_FILE.COM 命令过程注解

  1. IF 命令使用 F$SEARCH 词法函数搜索目录,并且确定这个文件是否存在。
  2. 跟随 THEN 命令的命令块:
    • 使用 F$LENGTH 词法函数确定文件类型的长度
    • 确定文件类型
    • 除去文件类型中的句点 
    • 除去文件说明中的文件类型来确定文件名
    • 除去文件名中的句点 
    • 定义如果出错发生则执行的动作 
    • 转移到符号 FILE_TYPE 定义的标号
  3. 如果在 "File to process:" 提示中输入的文件在目录中不存在,那么执行跟随 ELSE 命令的命令。
  4. ENDIF 命令结束 IF-THEN-ELSE 命令语言构造。
  5. 过程编译这个 FORTRAN 程序,并转移到 LINK 标号。如果在编译期间出错发生,那么过程转移到 PRINT 标号。
  6. 过程显示程序正确编译,链接和运行程序,并转移到 CLEANUP 标号。如果出错发生,程序就转移到 END 标号。
  7. 过程把程序的列出文件加入默认打印队列。

执行 COMPILE_FILE.COM 命令过程的样例


$ @COMPILE_FILE
File to process: RAND.PAS
Successful compilation
%DELETE-I-FILDEL,WORK:[DESCH]RAND.OBJ;1 deleted (3 blocks)
%DELETE-I-FILDEL,WORK:[DESCH]RAND.LIS;1 deleted (9 blocks)
Process another file (Y or N)? N [Return]


前页 后页 目录 索引