HP OpenVMS Systems Documentation

Content starts here

OpenVMS User's Manual


Previous Contents Index


Chapter 14
Advanced Programming with DCL

Advanced DCL programming includes the use of complex command procedures and the DCL command PIPE. You should read this chapter if you have read Chapter 13 and have basic knowledge of programming in DCL and want to learn more advanced methods.

Complex command procedures can perform programlike functions. You can use variable input in a command procedure, execute sections of the procedure only if certain conditions are true, execute subroutines, or invoke other command procedures.

You can also use the DCL command PIPE to perform programlike functions. For example, using the PIPE command, you can execute one or more of the following operations from the same DCL command line:

  • Pipelining (a sequence of commands)
  • Input/output redirection
  • Multiple and conditional command execution
  • Background processing

This chapter includes information about the following:

  • Performing command procedure input
  • Using parameters to pass data to nested command procedures
  • Performing command procedure output
  • Reading and writing files (file I/O)
  • Handling file I/O errors
  • Techniques for controlling execution flow
  • Creating new command levels
  • Writing Case statements
  • Using the PIPE command

14.1 Performing Command Procedure Input

Command procedures frequently require data provided by a user. This data, or input, can be obtained either interactively (as described in Chapter 13) or noninteractively. This chapter discusses noninteractive input methods, and different interactive methods than those described in Chapter 13.

You can use the same data each time a command procedure executes. To do this, place the data in the command procedure on data lines following the command that requires the data.

This command procedure executes the command procedure CENSUS.EXE. CENSUS.EXE reads the data 1993, 1994, and 1995 each time the procedure executes:


$ ! CENSUS.COM
$ !
$ RUN CENSUS
1993
1994
1995
$ EXIT

14.1.1 Restrictions to Including Data in Command Procedures

DCL passes the text on a data line directly to the command procedure. Therefore, it will not process data that must be translated such as:

  • Symbols
  • Logical names
  • Arithmetic expressions

14.1.2 Other Methods of Inputting Data

Other methods of obtaining input data for command procedures that are described in the following sections include:

  • Using parameters to pass data
  • Using parameters to pass data to batch jobs
  • Using parameters to pass data to nested command procedures
  • Using the INQUIRE and READ commands to prompt for data
  • Using the SYS$INPUT logical name to obtain data

14.2 Using Parameters to Pass Data

The following list contains guidelines for passing parameters as data to command procedures:

  • Place the parameters after the file specification of the command procedure.
  • You can pass up to eight parameters to a command procedure.
  • If you pass fewer than eight parameter values, the extra symbols are assigned null values. A null value is a string with no characters and is represented by quotation marks (" ").
  • Separate the parameters with one or more spaces or tabs.

DCL places parameters passed to command procedures in the local symbols P1 to P8. P1 is assigned to the first parameter value, P2 the second, P3 the third, and so on. For example, the following command invokes the command procedure SUM.COM and passes eight parameters to the procedure:


$ @SUM 34 52 664 89 2 72 87 3

14.2.1 Specifying Parameters as Integers

When you specify an integer as a parameter, it is converted to a string. In the following example, P1 is the string value 24; P2 is the string value 25:


$ @ADDER 24 25

You can use the symbols P1 to P8 in both integer and character string expressions; DCL performs the necessary conversions automatically.

14.2.2 Specifying Parameters as Character Strings

To preserve spaces, tabs, or lowercase characters in a character string, place quotation marks (" ") before and after the string. For example:


$ @DATA "Paul Cramer"

In the following example, P1 is Paul Cramer and P2 is null. If you omit the quotation marks, each character string is passed as a separate parameter. For example:


$ @DATA Paul Cramer

In this example, the strings Paul and Cramer are converted to uppercase letters; P1 is PAUL and P2 is CRAMER.

As another example, if you invoke DATA.COM with the following command:


$ @DATA  "Paul Cramer" 24 "(555) 111-1111")

P1 to P8 are defined in DATA.COM as follows:

P1 = Paul Cramer
P2 = 24
P3 = (555) 111-1111
P4--P8 = null

14.2.3 Specifying Parameters as Symbols

To pass the value of a symbol, place an apostrophe before and after the symbol. To preserve spaces, tabs, and lowercase characters in the symbol value, enclose the value in three sets of quotation marks. You must also use three sets of quotation marks to include a quotation mark as part of a string.

An alternative is to enclose the text in quotation marks and where a symbol appears, precede the symbol with two apostrophes and follow it with one apostrophe.

In the following example, P1 is Paul and P2 is Cramer because DCL removes quotation marks when you pass a symbol to a command procedure:


$ NAME = "Paul Cramer"
$ @DATA 'NAME'

In the following example, P1 is "Paul Cramer" and P2 is null:


$ NEW_NAME = """Paul Cramer"""
$ @DATA 'NEW_NAME'

In the following example, P1 is translated to Paul Cramer:


$ ! DATA.COM
$ @NAME "''P1'"

14.2.4 Specifying Parameters as Null Values

To pass a null parameter, use one set of quotation marks as a placeholder in the command string. In the following example, the first parameter passed to DATA.COM is a null parameter:


$ @DATA "" "Paul Cramer"

In this example, P1 is null and P2 is Paul Cramer.

14.3 Using Parameters to Pass Data to Batch Jobs

To pass parameters to a command procedure executed in batch mode, use the SUBMIT command qualifier /PARAMETERS.

If you execute more than one command procedure using a single SUBMIT command, the specified parameters are used for each command procedure in the batch job.

In the following example, the command passes three parameters to the command procedures ASK.COM and GO.COM, which are executed as batch jobs:


$ SUBMIT/PARAMETERS=(TODAY,TOMORROW,YESTERDAY) ASK.COM, GO.COM)

In the following example, the SUBMIT command passes two parameters to the command procedures: LIBRARY.COM and SORT.COM:


$ SUBMIT-
_$ /PARAMETERS=(DISK:[ACCOUNT.BILLS]DATA.DAT,DISK:[ACCOUNT]NAME.DAT) -
_$ LIBRARY.COM, SORT.COM

The batch job executes as if you had logged in and executed each of the command procedures. This SUBMIT command executes a batch job that logs in under your account, executes your login command procedure, and then executes the following commands:


$ @LIBRARY DISK:[ACCOUNT.BILLS]DATA.DAT DISK:[ACCOUNT]NAME.DAT)
$ @SORT DISK:[ACCOUNT.BILLS]DATA.DAT DISK:[ACCOUNT]NAME.DAT)

You can also pass data to a batch job by including the data in a command procedure or by defining SYS$INPUT to be a file. The specified parameters are used for each command procedure in the batch job.

14.4 Using Parameters to Pass Data to Nested Command Procedures

You can pass up to eight parameters to nested command procedures. The local symbols P1 to P8 in the nested procedure are not related to the local symbols P1 to P8 in the invoking procedure.

In the following example, DATA.COM invokes the nested command procedure NAME.COM:


$ ! DATA.COM
$ @NAME 'P1' Joe Cooper

If P1 in DATA.COM is the string Paul Cramer, which contains no quotation marks, it is passed to NAME.COM as two parameters. In NAME.COM, P1 to P8 are defined as follows:

P1 = PAUL
P2 = CRAMER
P3 = JOE
P4 = COOPER
P5--P8 = null

If P1 in DATA.COM is "Paul Cramer" (quotation marks included), you can pass the value to NAME.COM as one parameter by enclosing P1 in three sets of quotation marks, as follows:


$ ! DATA.COM
$ QUOTE = """
$ P1 = QUOTE + P1 + QUOTE
$ @NAME 'P1' "Joe Cooper"

In this example, P1 is Paul Cramer and P2 is Joe Cooper in the command procedure NAME.COM.

14.5 Prompting for Data

You can use the INQUIRE command (as described in Chapter 13) or the READ command to obtain data for command procedures interactively. Both commands prompt for input and assign the response to a symbol.

The READ command is different from the INQUIRE command in the following ways:

The INQUIRE command... The READ command...
Prompts for a value Prompts for a value
Reads the value from the terminal Reads the value from the source specified by the first parameter
Assigns the value to a symbol Assigns the value to the symbol named as the second parameter

The READ command accepts all characters typed on the terminal in response to the prompt, as an exact character string value (case, spaces, and tabs are preserved). If you omit the /PROMPT qualifier, the READ command displays Data: as the default prompt.

You can also write command procedures that can either accept parameters or prompt for user input if the required parameters are not specified.

In the following example, the command issues the prompt Filename: to the terminal, reads the response from the source specified by the logical name SYS$COMMAND (by default, the terminal), and assigns the response to the symbol FILE:


$ READ/PROMPT="Filename: "  SYS$COMMAND  FILE

In the following example, if a file name is not specified when the procedure is invoked, the user is prompted for a file name:


$ ! Prompt for a file name if name
$ ! is not passed as a parameter
$ IF P1 .EQS. "" THEN INQUIRE P1 "Filename"
$ COPY 'P1' DISK5:[RESERVED]*.*
$ EXIT

Note

If you submit a command procedure for execution as a batch job, DCL reads the value for a symbol specified in an INQUIRE command from the data line following the INQUIRE command. If you do not include a data line, the symbol is assigned a null value.

14.6 Using the SYS$INPUT Logical Name to Obtain Data

Commands, utilities, and other system images get their input from the source specified by the logical name SYS$INPUT, which is the default input stream. In a command procedure, SYS$INPUT is defined as the command procedure file; commands or images that require data look for data lines in the file. However, by redefining SYS$INPUT, you can provide data from your terminal or from a separate input file.

14.6.1 Redefining SYS$INPUT as Your Terminal

You can redefine SYS$INPUT to be your terminal. This enables images called from command procedures to obtain input interactively, rather than from data lines in command procedures.

Note that you must redefine SYS$INPUT to be your terminal if you want to use a DCL command or utility that requires interactive input in command procedures.

In the following example, the command procedure allows you to provide input interactively to the image CENSUS.EXE:


$ ! Execute CENSUS getting data from the terminal
$ DEFINE/USER_MODE SYS$INPUT SYS$COMMAND
$ RUN CENSUS
$ EXIT

The DEFINE/USER_MODE command temporarily redefines SYS$INPUT while CENSUS.EXE is running, so CENSUS.EXE obtains its input from the terminal. After CENSUS.EXE completes, SYS$INPUT reverts to its original definition (the command procedure file).

In the following example, the command procedure uses EVE as the text editor:


$ ! Obtain a list of your files
$ DIRECTORY
$ !
$ ! Get file name and invoke the EVE editor
$ EDIT_LOOP:
$      INQUIRE FILE "File to edit (Press Return to end)"
$      IF FILE .EQS. "" THEN EXIT
$      DEFINE/USER_MODE SYS$INPUT SYS$COMMAND
$      EDIT/TPU 'FILE'
$      GOTO EDIT_LOOP

The command procedure prompts for file names until you terminate the loop by pressing the Return key. When you enter a file name, the procedure automatically invokes EVE to edit the file. While the editor is running, SYS$INPUT is defined as the terminal so you can enter your edits interactively.

14.6.2 Defining SYS$INPUT as a Separate File

A command procedure can also get input from a file by defining SYS$INPUT as a file. Note that DCL does not process data lines; command procedures pass text on data lines directly to commands or images. If you include DCL symbols or expressions on data lines, DCL will not substitute values for the symbols or evaluate the expressions. If you use an exclamation point (!) in a data line, the image to which you pass the data processes the exclamation point.

You can also place programs in the command procedure file by specifying the name of the data file as SYS$INPUT. This causes the compiler to read the program from the command procedure rather than from another file.

The following example shows a command procedure that contains a FORTRAN command followed by the program's statements:


$ FORTRAN/OBJECT=TESTER/LIST=TESTER SYS$INPUT
C  THIS IS A TEST PROGRAM
   A = 1
   B = 2
   STOP
   END
$ PRINT TESTER.LIS
$ EXIT

The FORTRAN command uses the logical name SYS$INPUT to identify the file to be compiled. Because SYS$INPUT equates to the command procedure, the FORTRAN compiler compiles the statements following the FORTRAN command (up to the next line that begins with a dollar sign). When the compilation completes, two output files are created: TESTER.OBJ and TESTER.LIS. The PRINT command then prints the file.

14.7 Performing Command Procedure Output

Output from command procedures such as data, error messages, and verification of command lines can be directed to either terminals or other files. The following methods of directing output are covered in this section:

  • Displaying data
  • Redirecting output from commands and images
  • Returning data from command procedures
  • Redirecting error messages

14.7.1 Displaying Data

Use the TYPE command to display text that is several lines long and does not require symbol substitution. The TYPE command writes data from the file you specify to SYS$OUTPUT.

In the following example, SYS$INPUT is specified as the data file. The TYPE command reads data from the data lines that follow and displays the lines on the terminal.


$ ! Using TYPE to display lines
$ TYPE SYS$INPUT
REPORT BY MARY JONES
PREPARED APRIL 15, 2002
SUBJECT: Analysis of Tax Deductions for 2002
   .
   .
   .
$ EXIT

Use the WRITE command to write data that contains symbols or lexical functions. Unless you enclose the data in quotation marks (" "), the WRITE command performs symbol substitution automatically.

To use the WRITE command to display a character string as literal text, enclose the string in quotation marks (" "). For example:


$ WRITE SYS$OUTPUT "Two files are written."
Two files are written.

To include quotation marks in character strings, use two sets of quotation marks ("" ""). For example:


$ WRITE SYS$OUTPUT "Summary of ""Q & A"" Session"
Summary of "Q & A" Session

To continue a line of text on more than one line, concatenate the two strings with a plus sign (+) and a hyphen (-). For example:


$ WRITE SYS$OUTPUT "Report by Mary Jones" + -
" Prepared April 15, 2002"
Report by Mary Jones Prepared April 15, 2002

The WRITE command performs symbol substitutions automatically and displays the values of symbols. To force symbol substitutions within character strings, enclose the symbol in apostrophes. For example:


$ AFILE = "STAT1.DAT"
$ BFILE = "STAT2.DAT"
$ WRITE SYS$OUTPUT "''AFILE' and ''BFILE' ready."
STAT1.DAT and STAT2.DAT ready.

In this example, STAT1.DAT is the translation of the symbol AFILE; STAT2.DAT is the translation of the symbol BFILE.

14.7.2 Redirecting Output from Commands and Images

Commands, utilities, and other system images write their output to the source specified by the logical name SYS$OUTPUT. By default, SYS$OUTPUT equates to the terminal. However, you can redirect the output in one of the following ways:

  • Use the /OUTPUT qualifier when you invoke the command. DCL commands that accept the /OUTPUT qualifier include: ACCOUNTING, CALL, DIRECTORY, HELP, LIBRARY, RUN (process), SPAWN, and TYPE.
  • Temporarily redefine SYS$OUTPUT as a file by using the DEFINE/USER_MODE command.
  • Temporarily define SYS$OUTPUT as a null device (using the DEFINE/USER_MODE command) to suppress output from a command.

In the following example, the command procedure redirects the output from the SHOW USERS command to a file. The new definition for SYS$OUTPUT is in effect only for the execution of the SHOW USERS command.


$ DEFINE/USER_MODE SYS$OUTPUT SHOW_USER.DAT
$ SHOW USERS
$ !
$ ! Process the information in SHOW_USER.DAT
$ OPEN/READ INFILE SHOW_USER.DAT
$ READ INFILE RECORD
   .
   .
   .
$ CLOSE INFILE
$ EXIT

In the following example, SYS$OUTPUT is defined as a null device (NL:).


$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ APPEND NEW_DATA.DAT STATS.DAT
   .
   .
   .

The /USER_MODE qualifier is used to create a temporary logical name assignment that is in effect only until the next image completes. After the command executes, SYS$OUTPUT reverts to the default definition (usually the terminal).

You cannot use the DEFINE/USER_MODE command to redirect output from DCL commands that are executed within the command interpreter. Instead, use the DEFINE command to redefine SYS$OUTPUT and use the DEASSIGN command to delete the definition when you are through with it.

The following is a complete list of DCL commands that are performed within the command interpreter:

= ALLOCATE ASSIGN
ATTACH CALL CANCEL
CLOSE CONNECT CONTINUE
CREATE/LOGICAL_NAME_TABLE DEALLOCATE DEASSIGN
DEBUG DECK DEFINE
DEFINE/KEY DELETE/SYMBOL DISCONNECT
ELSE ENDIF ENDSUBROUTINE
EOD EXAMINE EXIT
GOSUB GOTO IF
INQUIRE ON OPEN
READ RECALL RETURN
SET CONTROL SET DEFAULT SET KEY
SET ON SET OUTPUT_RATE SET PROMPT
SET PROTECTION/DEFAULT SET SYMBOL/SCOPE SET UIC
SET VERIFY SHOW DEFAULT SHOW KEY
SHOW PROTECTION SHOW QUOTA SHOW STATUS
SHOW SYMBOL SHOW TIME SHOW TRANSLATION
SPAWN STOP SUBROUTINE
THEN WAIT WRITE

The following example shows the commands that would be used to redirect output from the SHOW TIME command to the file TIME.DAT. After you deassign SYS$OUTPUT, it reverts to the default definition (the terminal).


$ DEFINE SYS$OUTPUT TIME.DAT
$ SHOW TIME
$ DEASSIGN SYS$OUTPUT


Previous Next Contents Index