[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS 用户手册


前页 目录 索引

  1. 符号 CONTEXT 初始化为一个空值。这个符号将用于 F$PID 函数获得一个进程标识数的列表。
  2. 过程写入显示的标题。
  3. 过程取得第一个进程标识 (PID) 数。如果当前进程缺乏组或全体用户特权,那么就返回当前进程的 PID 数。如果当前进程有组特权,那么就返回组列表中的第一个 PID 数。如果当前进程有全体用户特权,就返回系统列表中的第一个 PID 数。这个函数按顺序继续返回下一个 PID 数,直到返回最后一个 PID 数。在这一点上,返回一个空串,然后过程分支到末端。
  4. 过程使用 F$GETJPI 词法函数获得每个 PID 数的映象文件说明。F$PARSE 函数从 F$GETJPI 函数返回的说明中抽取文件名。
  5. 过程使用 F$GETJPI 函数获得每个 PID 数的终端名。F$EXTRACT 函数抽取 F$GETJPI(PID,"MODE") 返回的 MODE 说明的前 3 个字符确定进程的类型。再次使用 F$GETJPI 函数确定进程是否是子进程。
  6. 过程为返回的每个 PID 数使用 F$GETJPI 词法函数获得用户名 、进程名、进程状态、进程优先级和进程基优先级。F$FAO 词法函数格式化这个信息用于屏幕显示。

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


$ @SYS


   PID    Username    Term    Process name   State   Pri Image
00050011  NETNONPRIV   -NET-   MAIL_14411      LEF    9/4 MAIL
00040013  STOVE        RTA6:   STOVE           LEF    9/4
00140015  MAROT        -DET-   DMFB0ACP        HIB    9/8 F11BAC
00080016  THOMPSON     -DET-   MTA0ACP         HIB   12/8 MTAAACP
00070017  JUHLES       TTF1:   JUHLES          LEF    9/4
   .
   .
   .
00040018  MARCO        TTA2:   MARCO           HIB    9/4 RTPAD
0018001A  VERN         RTA3:   VERN            LEF    9/4
0033001B  YISHA        RTA7:   YISHA           CUR    4/4
0002004A  SYSTEM       -DET-   ERRFMT          HIB   12/7 ERRFMT

这个过程返回系统上所有进程的信息。当前进程有全体用户特权。

B.5 GETPARMS.COM 命令过程

这个命令过程返回传递给过程的参数数目。可以从另一个过程调用 GETPARMS.COM 确定有多少参数传递给调用过程。

例子: GETPARMS.COM


$ ! Procedure to count the number of parameters passed to a command
$ ! procedure.  This number is returned as the global symbol PARMCOUNT.
$ !
$ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")        (1)
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
$ !
$ IF P1 .EQS. "?" THEN GOTO TELL                           (2)
$ !
$ ! Loop to count the number of parameters passed.  Null parameters are
$ ! counted until the last non-null parameter is passed.
$ !
$       COUNT = 0                                          (3)
$       LASTNONNULL = 0
$ LOOP:
$       IF COUNT .EQ. 8 THEN GOTO END_COUNT
$       COUNT = COUNT + 1
$       IF P'COUNT' .NES. "" THEN LASTNONNULL = COUNT
$ GOTO LOOP
$ !
$ END_COUNT:                                               (4)
$ !
$ ! Place the number of non-null parameters passed into PARMCOUNT.
$ !
$ PARMCOUNT == LASTNONNULL
$ !
$ ! Restore verification setting, if it was on, before exiting
$ !                                                             (5)
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
$ EXIT
$ !
$ TELL:                                                    (6)
$ TYPE SYS$INPUT
        This procedure counts the number of parameters passed to
        another procedure.  This procedure can be called by entering
        the following string in any procedure:

             @GETPARMS 'P1 'P2 'P3 'P4 'P5 'P6 'P7 'P8

        On  return,  the  global  symbol  PARMCOUNT
        contains the number of parameters passed to the procedure.
$ !
$ EXIT

GETPARMS.COM 命令过程注解

  1. 在停掉校验之前,过程保存当前的映象和过程校验设置。
  2. 如果一个问号字符作为参数传递到过程,那么过程分支到标号 TELL (注释 6)。
  3. 建立循环,计数传递给过程的参数数目。在进入循环之前,计数器 COUNT 和 LASTNONNULL 初始化为 0。在循环内,COUNT 递增并且与值 8 进行比较测试。如果 COUNT 等于 8,那么已输入参数的最大数目。每次传递非空参数时,LASTNONNULL 等于参数的数目。
    IF 命令每次执行时,符号 COUNT 有不同的值。第一次,COUNT 值是 1 而 IF 命令检查 P1。第二次,它检查 P2,以此类推。
  4. 当参数计数达到 8,过程分支到 END_COUNT。符号 LASTNONNULL 包含最后传递的非空参数的计数。这个值放置在全局符号 PARMCOUNT。PARMCOUNT 必须已定义为一个全局符号,以便它的值可以在调用命令级测试。
  5. 恢复原始的校验设置。
  6. 在标号 TELL,TYPE 命令显示输入流包括的数据。(在这个命令过程中,输入流就是这个命令过程文件。) TYPE 命令显示如何使用 GETPARMS.COM 的指令。

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

过程 SORTFILES.COM 需要用户传递三个非空参数。SORTFILES.COM 过程可以包含以下行:


$ @GETPARMS 'P1' 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8'
$ IF PARMCOUNT .NE. 3 THEN GOTO NOT_ENOUGH
   .
   .
   .
$NOT_ENOUGH:
$ WRITE SYS$OUTPUT -
"Three non-null parameters required.  Type SORTFILES HELP for info."
$ EXIT T

过程 SORTFILES.COM 可以调用如下:


$ @SORTFILES DEF 4
Three non-null parameters required. Type SORTFILE HELP for info.

要恰当地调用这个过程 --- 即传递给 SORTFILES 的参数要原样传递给 GETPARMS 处理 --- 符号 P1 至 P8 必须括入单引号内。

如果 GETPARMS 的返回值不是 3,那么 SORTFILES 输出一个出错消息并退出。

B.6 EDITALL.COM 命令过程

这个命令过程调用 EDT 编辑程序重复地编辑一组带同样文件类型的文件。这个过程说明如何使用词法函数从按列输出中抽取文件名。它也说明在命令过程中为被调用的程序重新定义输入流的方法。

例子: EDITALL.COM


$ ! Procedure to edit all files in a directory with a
$ ! specified file type. Use P1 to indicate the file type.
$ !
$ ON CONTROL_Y THEN GOTO DONE           ! Ctrl/Y action    (1)
$ ON ERROR THEN GOTO DONE
$ !
$ ! Check for file type parameter.  If one was entered, continue;
$ ! otherwise, prompt for a parameter.
$ !
$ IF P1 .NES. "" THEN GOTO OKAY                            (2)
$ INQUIRE P1 "Enter file type of files to edit"
$ !
$ ! List all files with the specified file type and write the DIRECTORY
$ ! output to a file named DIRECT.OUT
$ !
$ OKAY:
$ DIRECTORY/VERSIONS=1/COLUMNS=1 -                         (3)
         /NODATE/NOSIZE -
         /NOHEADING/NOTRAILING -
         /OUTPUT=DIRECT.OUT *.'P1'
$ IF .NOT. $STATUS THEN GOTO ERROR_SEC                     (4)
$ !
$ OPEN/READ/ERROR=ERROR_SEC DIRFILE DIRECT.OUT             (5)
$ !
$ ! Loop to read directory file
$ !
$ NEWLINE:                                                 (6)
$        READ/END=DONE DIRFILE NAME
$        DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:   ! Redefine SYS$INPUT
$        EDIT 'NAME'                               ! Edit the file
$        GOTO NEWLINE
$ !
$ DONE:                                                    (7)
$        CLOSE DIRFILE/ERROR=NOTOPEN               ! Close the file
$ NOTOPEN:
$        DELETE DIRECT.OUT;*                       ! Delete temp file
$ EXIT
$ !
$ ERROR_SEC:
$        WRITE SYS$OUTPUT "Error:  ",F$MESSAGE($STATUS)
$        DELETE DIRECT.OUT;*
$ EXIT

EDITALL.COM 命令过程注解

  1. ON 命令建立处理这个过程的条件。如果在执行这个过程期间的任何时候按下 Ctrl/Y,过程就分支到标号 DONE。同样,如果发生任何出错或严重出错,那么过程就分支到标号 DONE。
  2. 过程检查参数是否被输入。如果没有,过程就提示输入文件类型。
  3. DIRECTORY 命令列出带 P1 指定的文件类型的所有文件。命令输出写入到文件 DIRECT.OUT。/VERSIONS=1 限定词请求只列出每个文件的最高版本。/NOHEADING 和 /NOTRAILING 限定词请求输出不包括标题行或目录概要。/COLUMNS=1 限定词确保每个记录给出一个文件名。
  4. 通过测试 $STATUS 的值,IF 命令检查 DIRECTORY 命令的返回值。如果 DIRECTORY 命令没有成功完成,那么 $STATUS 有偶数值,并且过程分支到标号 ERROR_SEC。
  5. OPEN 命令打开目录输出文件,并为它分配逻辑名 DIRFILE。
  6. READ 命令从 DIRECTORY 命令输出读取一行,并写入符号 NAME。在它读取每行之后,过程使用 DEFINE 命令把编辑对话期的输入流 (SYS$INPUT) 重新定义到终端。然后,它调用编辑程序,指定符号名为文件说明。当编辑对话期完成时,命令解释程序读取命令过程的下一行,并且分支到标号 NEWLINE。当过程编辑了目录中指定文件类型的所有文件之后,它分支到标号 DONE。
  7. 标号 DONE 是 READ 命令的 /END 限定词的目标标号,并且 ON CONTROL_Y 和 ON ERROR 条件的目标标号在过程的开始设置。在这个标号上,过程执行必要的清除操作。
    CLOSE 命令关闭 DIRECTORY 命令的输出文件;/ERROR 限定词 把标号指定在文件的下一行。/ERROR 的这个使用将取消如果目录文件没有打开而显示的任何出错消息。例如,如果在目录文件打开之前按下 Ctrl/Y,那么将发生这种情形。
    清除的第二步是删除临时目录文件。

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


$  @EDITALL DAT
*  .
   .
   .
%DELETE-I-FILDEL, device:[directory]DIRECT.OUT;1 deleted (x blocks)

过程 EDITALL 调用时,P1 指定为 .DAT。过程建立一个目录,列出在默认目录中其文件类型是 .DAT 的所有文件,并且调用编辑程序编辑每一个。在完成编辑最后 一个带文件类型 .DAT 的文件之后,过程删除临时文件 DIRECT.OUT,并在终端上显示通知消息。

B.7 MAILEDIT.COM 命令过程

这个命令过程在 Mail 公用程序中调用文本编辑程序。

例子: MAILEDIT.COM


$ ! Command procedure to invoke an editor for Mail.
$ !
$ ! Inputs:
$ !
$ ! P1 = Input file name.
$ ! P2 = Output file name.
$ !
$ ! If MAIL$EDIT is undefined, Mail will invoke the user's selected
$ ! callable editor set by the mail SET EDITOR command.
$ !
$ ! If MAIL$EDIT is defined to be a command procedure, Mail will create
$ ! a subprocess to edit the mail, but any SET EDITOR command in Mail
$ ! will override the definition of MAIL$EDIT for the remainder of that
$ ! Mail session.
$ !
$ ! Note that this procedure is run in the context of a subprocess.
$ ! LOGIN.COM is not executed.  However, all process logical names
$ ! and DCL global symbols are copied.  In particular, note that the
$ ! user's individual definition of the symbol EDIT is used if there
$ ! is one. Otherwise, the system default editor is used.
$ !
$ ! The default directory is the same as the parent process
$ !
$ DEFINE /USER SYS$INPUT 'F$TRNLNM("SYS$OUTPUT")'     (1)
$ IF P1 .EQS. "" THEN GOTO NOINPUT       (2)
$ EDIT /OUTPUT='P2' 'P1'       (3)
$ EXIT
$NOINPUT:
$ EDIT 'P2'         (4)
$ EXIT

MAILEDIT.COM 命令过程注解

  1. DEFINE 命令允许编辑程序的输入来自终端,代替命令文件。
  2. IF 语句区别编辑不同名文件和编辑同名文件。
  3. 这个 EDIT 命令带输入和输出文件名调用编辑程序。您可以编辑这行以调用您自己的编辑程序。例如:


          $ RUN XYZ_EDITOR.EXE /INPUT= 'P1' /OUTPUT='P2'
    
  4. 这个 EDIT 命令带单个文件名调用编辑程序。您可以编辑这行以调用您自己的编辑程序。例如:


          $ RUN XYZ_EDITOR.EXE /INPUT= 'P2' /OUTPUT='P2'
    

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


$DEFINE MAIL$EDIT MAILEDIT.COM
$MAIL
MAIL> SHOW EDITOR
Your editor is defined by the file MAILEDIT.COM.

B.8 FORTUSER.COM 命令过程

提供一个系统定义的注册命令过程的样例,它为建立、编译和执行 FORTRAN 程序的交互用户控制终端环境。如果用户注册到一个受约束帐户,在此 FORTUSER.COM 被列为注册命令过程,那么这个用户只可以执行 FORTUSER.COM 接受的命令。这个过程也说明如何使用词法函数遍历选项表,用一列有效命令比较用户输入的命令。

例子: FORTUSER.COM


$ ! Procedure to create, compile, link, execute, and debug
$ ! FORTRAN programs.  Users can enter only the commands listed
$ ! in the symbol OPTION_TABLE.
$ SET NOCONTROL=Y                                          (1)
$ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
$ OPTION_TABLE = "EDIT/COMPILE/LINK/RUN/EXECUTE/DEBUG/PRINT/HELP/FILE/DONE/"  (2)
$ TYPE SYS$INPUT                                           (3)

        VMS FORTRAN Command Interpreter

        Enter name of file with which you would like to work.
$ !
$ ! Set up for initial prompt
$ !
$ PROMPT = "INIT"                                          (4)
$ GOTO HELP                      ! Print the initial help message
$ !
$ ! after the first prompting message, use the prompt: Command
$ !
$ INIT:
$ PROMPT = "GET_COMMAND"
$ GOTO FILE                      ! Get initial file name
$ !
$ ! Main command parsing routine.  The routine compares the current
$ ! command against the options in the option table.  When it finds
$ ! a match, it branches to the appropriate label.
$ !
$ GET_COMMAND:
$       ON CONTROL_Y THEN GOTO GET_COMMAND     ! Ctrl/Y resets prompt  (5)
$       SET CONTROL=Y
$       ON WARNING THEN GOTO GET_COMMAND       ! If any, reset prompt
$       INQUIRE COMMAND "Command"
$       IF COMMAND .EQS. "" THEN GOTO GET_COMMAND
$       IF F$LOCATE(COMMAND + "/", OPTION_TABLE) .EQ. F$LENGTH(OPTION_TABLE) - (6)
               THEN GOTO INVALID_COMMAND
$       GOTO 'COMMAND'
$ !
$ INVALID_COMMAND:                                         (7)
$       WRITE SYS$OUTPUT " Invalid command"
$ !
$ HELP:                                                    (8)
$       TYPE SYS$INPUT
        The commands you can enter are:
        FILE      Name of FORTRAN program in your current
                  default directory.  Subsequent commands
                  process this file.
        EDIT      Edit the program.
        COMPILE   Compile the program with FORTRAN.
        LINK      Link the program to produce an executable image.
        RUN       Run the program's executable image.
        EXECUTE   Same function as COMPILE, LINK, and RUN.
        DEBUG     Run the program under control of the debugger.
        PRINT     Queue the most recent listing file for printing.
        DONE      Return to interactive command level.
        HELP      Print this help message.

        Enter Ctrl/Y to restart this session
$ GOTO 'PROMPT'                                            (9)
$ EDIT:                                                    (10)
$       DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
$       EDIT 'FILE_NAME'.FOR
$       GOTO GET_COMMAND
$ COMPILE:
$       FORTRAN 'FILE_NAME'/LIST/OBJECT/DEBUG
$       GOTO GET_COMMAND
$ LINK:
$       LINK 'FILE_NAME'/DEBUG
$       PURGE 'FILE_NAME'.*/KEEP=2
$       GOTO GET_COMMAND
$ RUN:
$       DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
$       RUN/NODEBUG 'FILE_NAME'
$       GOTO GET_COMMAND
$ DEBUG:
$       DEFINE/USER_MODE SYS$INPUT SYS$COMMAND:
$       RUN 'FILE_NAME'
$       GOTO GET_COMMAND
$ EXECUTE:
$       FORTRAN 'FILE_NAME'/LIST/OBJECT
$       LINK/DEBUG 'FILE_NAME'
$       PURGE 'FILE_NAME'.*/KEEP=2
$       RUN/NODEBUG 'FILE_NAME'
$       GOTO GET_COMMAND
$ PRINT:
$       PRINT 'FILE_NAME'
$       GOTO GET_COMMAND
$ BADFILE:                                                 (11)
$       WRITE SYS$OUTPUT "File must be in current default directory."
$ FILE:
$       INQUIRE FILE_NAME "File name"
$       IF FILE_NAME .EQS. "" THEN GOTO FILE
$       IF F$PARSE(FILE_NAME,,,"DIRECTORY") .NES. F$DIRECTORY() -  (12)
        THEN GOTO BADFILE
$       FILE_NAME = F$PARSE(FILE_NAME,,,"NAME")
$       GOTO GET_COMMAND
$ DONE:
$ EXIT

FORTUSER.COM 命令过程注解

  1. SET NOCONTROL=Y 命令确保在这个过程控制下的注册用户不能中断这个过程或其中的任何命令或程序 。
  2. 任选项表列出允许用户执行的命令。每个命令用斜杠分隔。
  3. 过程引入本身。
  4. 在过程中符号名 PROMPT 被赋予标号的值。当过程最初被调用时,这个符号有值 INIT。HELP 命令文本终止于指定标号 PROMPT 的 GOTO 命令。当这个文本第一次显示时,GOTO 命令导致控制流转移到标号 HELP。它显示 HELP 消息,解释可以输入的命令。然后,过程转移回标号 INIT,在此 PROMPT 的值更改为 "GET_COMMAND"。最后,过程转移到标号 FILE 获得文件名。其后,当显示求助文本时,过程转移到标号 GET_COMMAND 去获得下一个命令。
  5. Ctrl/Y 条件动作设置为返回到标号 GET_COMMAND, 好象是警告条件动作。过程提示输入命令并且继续提示,即使没有输入任何字符。要终止对话期并返回到交互命令级,输入命令 DONE。
  6. 过程使用 F$LOCATE 和 F$LENGTH 词法函数确定命令是否包括在任选项列表中。F$LOCATE 函数搜索用户输入的命令,后面跟随一个斜杠。(例如,如果输入 EDIT,过程就搜索 EDIT/。) 如果命令没有包括在任选项列表中,那么过程转移到标号 INVALID_COMMAND。如果命令是有效的,过程就转移到适当的标号。
  7. 在标号 INVALID_COMMAND,过程写入出错消息并显示求助文本,列出有效的命令。
  8. 求助文本列出有效 的命令。最初就显示这个文本。无论何时用户输入 HELP 命令或任何无效命令,也显示它。
  9. 在求助文本结束处,GOTO 命令指定符号名 PROMPT。当这个过程第一次调用时,该符号有值 INIT。其后,它有值 GET_COMMAND。
  10. 列表中的每个有效命令在任选项表中有相应的条目,并且在命令过程中有相应的标号。对于从终端读取输入的命令,例如 EDIT,过程包含一个把输入流定义为 SYS$COMMAND 的 DEFINE 命令。
  11. 在标号 BADFILE 处,过程显示一条消息,指出文件必须在当前目录中。然后过程提示输入另一个文件名。
  12. 在获得文件名之后,过程检查您没有指定一个不同于当前默认目录的目录。然后,过程使用 F$PARSE 函数抽取文件名。(每个命令提供适当的默认文件类型。) 其次,过程转移回标号 GET_COMMAND 去获得一个处理这个文件的命令。

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

以下例子说明如何把这个命令过程用作受约束命令过程:


Username: CLASS30
Password:

            OpenVMS Version 7.1

    OpenVMS FORTRAN Command Interpreter

    Enter name of file with which you would like to work.

    The commands you can enter are:

    FILE       Name of FORTRAN program in your current
               default directory.  Subsequent commands
               process this file.
    EDIT       Edit the program.
    COMPILE    Compile the program with VAX FORTRAN.
    LINK       Link the program to produce an executable image.
    RUN        Run the program's executable image.
    EXECUTE    Same function as COMPILE, LINK and RUN.
    DEBUG      Run the program under control of the debugger.
    PRINT      Queue the most recent listing file for printing.
    DONE       Return to interactive command level.
    HELP       Print this help message.

    Enter Ctrl/Y to restart this session
File name: AVERAGE
Command: COMPILE
Command: LINK
Command: RUN
Command: FILE
File name: READFILE
Command: EDIT

这个执行样例说明一个对话期,其中用户 CLASS30 注册到被 FORTUSER 命令过程控制的帐户。FORTUSER 命令过程显示允许用户执行的命令,以及一条重新启动对话期的指令。然后,用户指定文件 AVERAGE、编译 、链接和运行它。然后,用户输入 FILE 命令开始处理另一个文件。


前页 后页 目录 索引