The command sequences in a subshell are executed in a subprocess environment. DCL waits for the subshell to complete before executing the next command sequence. The ( ) separator is similar to the SPAWN/WAIT command.
Command sequences can be executed in a subprocess environment by using the following form:
PIPE command-sequence [ separator command-sequence]... &
DCL does not wait for the command sequences to finish. Control passes back to DCL once the background subprocess is created.
A command sequence can redirect its SYS$INPUT, SYS$OUTPUT, or SYS$ERROR to a file during execution of the command as follows:
PIPE command-sequence < redirected-input-file
PIPE command-sequence > redirected-output-file
PIPE command-sequence 2> redirected-error-file
A pipeline-segment command can also redirect its SYS$INPUT, SYS$OUTPUT or SYS$ERROR. However, SYS$OUTPUT redirection is allowed only for the last pipeline-segment command, and SYS$INPUT redirection is allowed only for the first pipeline-segment command.
Note that a PIPE command redirection is different from that created using the DEFINE or ASSIGN command. The differences are as follows:
When SYS$OUTPUT is redirected, the redirected output file is always created, whether or not the command sequence actually writes to SYS$OUTPUT. If a version of a file with the same name as the redirected output file already exists, a new version of that file is created. (This behavior is the same as using the DEFINE or ASSIGN command to redefine SYS$OUTPUT in supervisor mode.) Note that the redirected file is created before the command sequence is executed. If the redirected file is also used in the command sequence, the operation may fail, as in the following example:
$ PIPE SEARCH TRANS.LOG "alpha" > TRANS.LOG %SEARCH-W-OPENIN, error opening TRANS.LOG;2 as input -RMS-E-FLK, file currently locked by another userIn this example, a new version of TRANS.LOG is created and opened for write access; the SEARCH command then tries to get read access to the most recent version of TRANS.LOG instead of the expected previous version.
When SYS$ERROR is redirected, the redirected error file is only created when the command sequence actually writes to the SYS$ERROR during execution, and there is no existing file with the same name as the redirected error file. If a file with the same name as the redirected error file already exists, that file is opened as the redirected error file. The error output generated by this command sequence is then appended to the end of the redirected error file. (This behavior is the same as using the DEFINE or ASSIGN command to redefine SYS$ERROR in supervisor mode.)
You can interrupt a PIPE command by pressing Ctrl/Y. If the PIPE command is executing in a pipeline or a subshell command sequence, the command sequence and the PIPE command are deleted. In this case, a CONTINUE command entered immediately after the interrupt will not resume the execution of the PIPE command.
If the PIPE command is executing a command sequence other than a subshell or a pipeline command sequence, DCL behaves as if the command sequence were entered as a DCL command without the PIPE command verb and interrupted by Ctrl/Y. See Section 3.12.2 and Section 15.25 for more information on the Ctrl/Y interrupt.
A PIPE command can generate a number of subprocesses during execution. Often, the applications invoked by command sequences do not depend on the process logical names and symbol names. In this case, the spawning of subprocesses can be accelerated by using the /NOLOGICAL_NAMES and /NOSYMBOLS qualifiers, which suppress the passing of process logical names and symbols to the subprocesses created by the PIPE command.
Following are examples of using the PIPE command.
$ CD_WORK :== PIPE SAVE_DIR=F$DIRECTORY() ; SET DEFAULT FOO:[WORK] $ BACK :== SET DEF 'SAVE_DIR' $ $ CD_WORK ! Switch to working directory $ : $ : $ BACK ! Switch back to home directory $ GET_RECORD :== PIPE READ/END_OF_FILE=CLEANUP IN RECORD ; - F$EDIT(RECORD, "COMPRESS, TRIM") $ $ OPEN IN EMPLOYEE.DAT $ LOOP: $ GET_RECORD $ : $ : $ GOTO LOOP $ $ CLEAN_UP: $ :
$ PIPE cc foo.c && link foo, sys$library:vaxcrtl.olb/lib
$ PIPE RUN COLLECT_DATA.EXE || GOTO CLEAN_UP $ : $ : $ EXIT $ $ CLEAN_UP: $ : $ :
$ PIPE COPY LARGE_FILE.DAT REMOTE"user password"::[DESTINATION]*.* &
$ PIPE (SET DEF [.DATA_DIR] ; BACKUP DATA.SAV/SAV [...]) ; RUN FOO
$ PIPE SHOW SYSTEM | SEARCH SYS$INPUT HIB
$ PIPE RUN TEST | SORT/SPECIFICATION=TEST.SRT SYS$INPUT SYS$OUTPUT - | DIFF SYS$INPUT TEST.BENCHMARK
$ PIPE ( SET DEF WRK$:[WORK] ; RUN REPORT ) | MAIL SYS$INPUT SMITH
$ more :== TYPE/PAGE=SAVE SYS$INPUT $ PIPE ANA/RMS PAGE.TXT | more Check RMS File Integrity 26-JAN-1996 16:12:00.06 Page 1 SYS$SYSDEVICE:[TEST]PAGE.TXT;2 FILE HEADER File Spec: SYS$SYSDEVICE:[TEST]PAGE.TXT;2 File ID: (4135,58220,0) Owner UIC: [PIPE] Protection: System: RWED, Owner: RWED, Group: RE, World: Creation Date: 26-NOV-1996 16:08:50.05 Revision Date: 26-NOV-1996 16:09:09.06, Number: 1 Expiration Date: none specified Backup Date: none posted Contiguity Options: none Performance Options: none Reliability Options: none Journaling Enabled: none RMS FILE ATTRIBUTES RETURN/SPACE=More, PREV/NEXT=Scroll, INS/REM=Pan, SELECT=80/132, Q=Quit
Lexical functions are command language constructs that the DCL interpreter evaluates and substitutes before it interprets a command string. This chapter includes information on:
For additional information on lexical functions, refer to online Help. For additional information on the commands discussed in this chapter, refer to the OpenVMS DCL Dictionary.
Lexical functions can be used to obtain information about:
Many lexical functions return information that you can also get from DCL commands.
You can manipulate information in a command procedure more easily if you obtain it from a lexical function rather than from a command. For example, you can use either the F$ENVIRONMENT function or the SHOW DEFAULT command to obtain the name of your current default directory. The differences are as follows:
$ DIR_NAME = F$ENVIRONMENT("DEFAULT") $ SET DEFAULT DISK4:[TEST] . . . $ SET DEFAULT 'DIR_NAME'
$! Redirect the output of the SHOW DEFAULT command to a file. $ DEFINE/SUPERVISOR_MODE SYS$OUTPUT DISK4:[TEST]TEMPFILE.DAT $ SHOW DEFAULT $ DEASSIGN SYS$OUTPUT $! $ OPEN/READ DIR_FILE DISK4:[TEST]TEMPFILE.DAT ! Open the file. $ READ DIR_FILE DIR_NAME, ! Read the file. $ SET DEFAULT 'DIR_NAME' ! Reset the directory. $ CLOSE DIR_FILE ! Close the file. $ DELETE DISK4:[TEST]TEMPFILE.DAT;* ! Delete the file.
The following sections describe how to obtain information about your process.
You often change process characteristics for the duration of a command procedure and then restore them. You can use the following lexical functions to obtain information about your process:
F$DIRECTORY | Returns the current default directory string. |
F$ENVIRONMENT | Returns information about the command environment for your process. |
F$GETJPI | Returns accounting, status, and identification information about your process or about other processes on the system. |
F$MODE | Shows the mode in which your process is executing. |
F$PRIVILEGE | Indicates whether your process has the specified privileges. |
F$PROCESS | Returns the name of your process. |
F$SETPRV | Sets the specified privileges. This function also indicates whether the specified privileges were previously enabled before you used the F$SETPRV function. |
F$USER | Returns your user identification code (UIC). |
F$VERIFY | Indicates whether verification is on or off. |
The following table shows process characteristics that are commonly changed in command procedures; it also gives the lexical functions that save these characteristics and the DCL commands that restore the original settings.
Characteristic | Operation | Command or Lexical Function |
---|---|---|
Control characters | Save | F$ENVIRONMENT("CONTROL") |
Restore | SET CONTROL | |
DCL prompt | Save | F$ENVIRONMENT("PROMPT") |
Restore | SET PROMPT | |
Default protection | Save | F$ENVIRONMENT("PROTECTION") |
Restore | SET PROTECTION/DEFAULT | |
Key state | Save | F$ENVIRONMENT("KEY_STATE") |
Restore | SET KEY | |
Message format | Save | F$ENVIRONMENT("MESSAGE") |
Restore | SET MESSAGE | |
Privileges | Save | F$PRIVILEGE or F$SETPRV |
Restore | F$SETPRV or SET PROCESS/PRIVILEGES | |
Verification | Save | F$VERIFY or F$ENVIRONMENT |
Restore | F$VERIFY or SET VERIFY |
If you save process characteristics, you must ensure that an error or Ctrl/Y interruption does not cause the procedure to exit before you restore the original characteristics. (See Chapter 15 for more information on handling errors and Ctrl/Y interruptions.)
You can use the F$VERIFY lexical function to disable verification for the duration of a command procedure. This prevents users from displaying a procedure's contents while executing the procedure.
There are two types of verification:
By default, the SET [NO]VERIFY command and the F$VERIFY function turn both types of verification on or off. In general, the procedure and image verification settings in a procedure are the same (both on or both off). However, if you decide to change the settings, save each verification setting separately.
$ ! Enable verification $ ! $ TEMP = F$VERIFY(1) $ LOOP: $ INQUIRE FILE "File name" $ IF FILE .EQS."" THEN EXIT $ PRINT 'FILE' $ GOTO LOOP $ ! Disable verification $ ! $ TEMP = F$VERIFY(0) $ EXIT
$ ! Save each verification state $ ! Turn both states off $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE") $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0) . . . $ ! Restore original verification states $ SAVE_VERIFY_IMAGE = F$VERIFY(SAVE_VERIFY_PROCEDURE,- SAVE_VERIFY_IMAGE)
If you are using time-stamping, remember that it applies only if verification is enabled. For more information on time-stamping and the SET PREFIX command, see the OpenVMS DCL Dictionary or refer to DCL help.
You may want to change the default file protection within a command procedure. The following command procedure changes the default protection associated with files created while the procedure is executing. The procedure restores the original default file protection before terminating.
$ SAVE_PROT = F$ENVIRONMENT("PROTECTION") $ SET PROTECTION = (SYSTEM:RWED, OWNER:RWED, GROUP, WORLD)/DEFAULT . . . $ SET PROTECTION=('SAVE_PROT')/DEFAULT $ EXIT
Note that the F$ENVIRONMENT function returns the default protection code using the syntax required by the SET PROTECTION command. This lets you use the symbol SAVE_PROT with the SET PROTECTION command to restore the original default file protection.
The following sections describe how to obtain information about the system.
You can use the following lexical functions to obtain information about the system:
F$CONTEXT | Specifies selection criteria to use with the F$PID function. The F$CONTEXT function enables the F$PID function to obtain information about processes from any node in a VMScluster. |
F$CSID | Returns a VMScluster identification number and updates the context symbol to point to the current position in the system's VMScluster node list. |
F$GETQUI | Returns information about queues, batch and print jobs currently in those queues, form definitions, and characteristic definitions kept in the system job queue file. |
F$GETSYI | Returns information about your local system or about a node in your VMScluster (if your system is part of a VMScluster). |
F$IDENTIFIER | Converts identifiers from named to numeric format or from numeric to named format. |
F$MESSAGE | Returns the message text associated with a status code. |
F$PID | Returns the process identification (PID) number for processes that you are allowed to examine. |
F$TIME | Returns the current date and time. |
If your system is part of a VMScluster environment where you can log in to many different nodes, you can set the DCL prompt to indicate which node you are currently using. To do this, include the F$GETSYI function in your login command procedure to determine the node name. Then use the SET PROMPT command to set a unique prompt for the node.
If you want to use only a portion of the node name in your prompt string, use the F$EXTRACT function to extract the appropriate characters. See Section 17.7.3 for more information on extracting characters.
In the following example, the symbol NODE is defined as FF$GETSYI("NODENAME") and then the node name is used as the prompt:
$ NODE = F$GETSYI("NODENAME") $ SET PROMPT = "''NODE'$ " . . .
You can use the F$GETQUI function to get many types of information about batch and print queues. You must have read access to the job, SYSPRV privilege, or OPER privilege to obtain information about jobs and files in queues.
The following example shows how to determine if the batch queue VAX1_BATCH is in a stopped state. The value returned is either true or false. If the queue is not stopped, the command procedure submits a job to the queue:
$ QSTOPPED = F$GETQUI("DISPLAY_QUEUE", "QUEUE_STOPPED", "VAX1_BATCH") $ IF QSTOPPED THEN GOTO NOBATCH $ SUBMIT/QUEUE=VAX1_BATCH TEST.COM $ NOBATCH: . . .
You can use the F$PID function to get the process identification (PID) number for all processes that you are allowed to examine. You can obtain PID numbers:
After you obtain a PID number, you can use the F$GETJPI function to obtain specific information about the process.
$ ! Display the time when this procedure $ ! begins executing $ WRITE SYS$OUTPUT F$TIME() $ ! $ CONTEXT = "" $ START: $ ! Obtain and display PID numbers until $ ! F$PID returns a null string $ ! $ PID = F$PID(CONTEXT) $ IF PID .EQS. "" THEN EXIT $ WRITE SYS$OUTPUT "Pid --- ''PID'" $ GOTO START
$ CONTEXT = "" $ START: $ ! Obtain and display PID numbers and UICs $ ! $ PID = F$PID(CONTEXT) $ IF PID .EQS. "" THEN EXIT $ UIC = F$GETJPI(PID,"UIC") $ WRITE SYS$OUTPUT "Pid --- ''PID' Uic--- ''UIC' " $ GOTO START
$ CONTEXT = "" $ START: $ PID = F$PID(CONTEXT) $ IF PID .EQS. "" THEN EXIT $ WRITE SYS$OUTPUT "Pid --- ''PID' Uic --- ''F$GETJPI(PID,"UIC")'" $ GOTO START
To obtain information about processes from any node in a VMScluster, use the F$CONTEXT function.
In the following example, F$CONTEXT is called three times to set up selection criteria:
$!Establish an error and Ctrl/Y handler $! $ ON ERROR THEN GOTO error $ ON CONTROL_Y THEN GOTO error $! $ ctx = "" $ temp = F$CONTEXT ("PROCESS", ctx, "NODENAME", "*","EQL") (1) $ temp = F$CONTEXT ("PROCESS", ctx, "USERNAME", "M*,SYSTEM","EQL") (2) $ temp = F$CONTEXT ("PROCESS", ctx, "CURPRIV", "SYSPRV,OPER", "ALL") (3) $! $!Loop over all processes that meet the selection criteria. $!Print the PID number and the name of the image for each process. $! $loop: (4) $ pid = F$PID(ctx) $ IF pid .EQS. "" $ THEN $ GOTO endloop $ ELSE $ image = F$GETJPI(pid,"IMAGNAME") (5) $ SHOW SYMBOL pid $ WRITE SYS$OUTPUT image (6) $ GOTO loop $ ENDIF $!The loop over the processes has ended. $! $endloop: $! $ EXIT $! $!Error handler. Clean up the context's memory with $!the CANCEL selection item keyword. $! $error: $ IF F$TYPE(ctx) .eqs. "PROCESS_CONTEXT" THEN - (7) -$ temp = F$CONTEXT ("PROCESS", ctx, "CANCEL") (8) $! $ EXIT
As you examine the example, note the following:
You can use the following lexical functions to obtain information about files and devices:
F$DEVICE | Returns the device names of all devices on a system that meet the specified selection criteria |
F$FILE_ATTRIBUTES | Returns information about file attributes |
F$GETDVI | Returns information about a specified device |
F$PARSE | Parses a file specification and returns the requested field or fields |
F$SEARCH | Searches a directory for a file |
To get information on a particular device by using the system service $GETDVI, you must provide the device name to the service. If you do not know the device name, you can find it by using the lexical function F$DEVICE.
6489P033.HTM OSSG Documentation 22-NOV-1996 13:17:26.41
Copyright © Digital Equipment Corporation 1996. All Rights Reserved.