OpenVMS User's Manual
14.14.1 Using Automatic Foreign Commands
Note the following:
- The logical name DCL$PATH can be a search-list type logical.
- Only the node, device, and directory portions of each translation
of the logical name are used.
- Normal logical precedence takes place. Users can override a system
definition of DCL$PATH by defining their own. If a system definition
exists and the user does not want the feature, it can be turned off by
overriding the logical with a definition of " ".
- The set of valid characters for DCL verbs and symbol names differs
from the set of valid characters for file names. For example, DCL
symbols cannot contain a hyphen (-) or start with a dollar sign ($). If
the image or procedure you wish to execute is not valid as a DCL symbol
name, it cannot be directly invoked by this new feature.
- DCL has not parsed the command. It is up to the image being invoked
to perform its own command parsing. For C programs, use the "argc" and
"argv" parameters to the main() routine. For programs written in other
languages, call LIB$GET_FOREIGN to obtain the entire command line,
which must then be parsed by the program.
- If a directory contains both a command procedure and an executable
image, whichever file is found first will be invoked. On OpenVMS
systems, directories are in alphabetical order, so a ".COM" file will
be found before a ".EXE" file. A network file specification in the
DCL$PATH logical pointing to a node running some other operating
systems could result in a ".EXE" file being found before a ".COM" file.
Because DCL performs the search with the invalid verb as the file
specification and "DCL$PATH:.*" as the default file specification, it
is possible to define a logical in such a way that a specific file is
found. For example, if you define the logical FOO to be "FOO.EXE", and
type "FOO" at the DCL prompt, you will never invoke FOO.COM, only
If you are a privileged user and set your default device and directory
to other user accounts, you should not place "SYS$DISK:" in the
definition of the DCL$PATH logical name. Doing so will cause DCL to
search the current directory, where a typographical error or poor
placement of the translation within the search list could cause user
images in the current directory to be found and mistakenly invoked with
14.14.2 Automatic Foreign Command Restrictions
Note the following restrictions:
- You cannot use automatic foreign commands on any versions of the
OpenVMS operating system prior to Version 6.2.
- Because new verbs can be added to the DCL command table at any
time, a command that works with automatic foreign commands one day may
not work at a later date.
- The automatic foreign commands feature does not work in all cases.
In the following example, DCL (which looks only at the first four
characters of any verb) finds a match with the SHOW verb (the first
four letters of SHOWME) and executes the SHOW USERS command instead of
the SHOWME.COM procedure. If you defined SHOWME as a DCL symbol, then
the SHOWME command would invoke SHOWME.COM.
$ DEFINE DCL$PATH SYS$SYSTEM,SYS$DISK:FOO
$ TYPE SHOWME.COM
$ SHOW SYMBOL P1
$ SHOWME USERS
OpenVMS User Processes at MARCH 2, 1999 01:40 PM
Total number of users = 1, number of processes = 11
Username Interactive Subprocess Batch
RSMITH 9 2
Programming with DCL: Introduction to Command Procedures
Command procedures are files that contain DCL commands
and data lines used by DCL commands. This chapter is divided into major
sections that include the following:
- Basic information for writing command procedures
- Step-by-step procedure for writing command procedures
- Executing command procedures
- Exiting, interrupting, and error handling command procedures
- Login command procedures
For additional information, refer to the following:
- The OpenVMS DCL Dictionary, for complete information about all the commands
described in this chapter
- The OpenVMS Guide to Extended File Specifications, for information about programming with DCL in
environments with Extended File Specifications
There are two types of DCL command procedures:
Execute a series of DCL commands in the order in which
they are written
Perform program-like functions
15.1 Basic Information for Writing Command Procedures
There are two ways to create command procedures:
- Use a text editor such as EVE or EDT to create a new file
- Use the DCL command CREATE to create a new file
The file that you create can contain command lines, labels, comments,
conditional statements, and variables.
15.1.1 Default File Type
The default file type for command procedures is .COM. If you specify
the .COM file type when you name a command procedure, you can execute
the procedure by specifying the file name only. The SUBMIT and execute
procedure (@) commands assume the file type is .COM unless you specify
15.1.2 Writing Commands
The following are suggestions for including commands in command
- Use complete names for commands and qualifiers. This will help to
ensure that your command procedure is upwardly compatible to future
releases of OpenVMS.
- Use continuation lines to make a procedure easier to read. Note
that continuation lines do not begin with dollar signs. For example:
$ PRINT LAB.DAT -
15.1.3 Writing Command Lines
When writing command lines:
- You must use a dollar sign ($) to begin each line containing a
command, comment, or label.
- If you want to include a line containing data, omit the dollar sign
($) on that line.
- If you need to include a data line that begins with a dollar sign
($), use the DCL commands DECK and EOD. For example:
$ ! Everything between the commands DECK and EOD
$ ! is written to the file WEATHER.COM
$ CREATE WEATHER.COM
$ FORTRAN SUMMER
$ LINK SUMMER
$ RUN SUMMER
$ ! Now execute WEATHER.COM
Note that command lines that do not begin with a dollar sign
might be correctly interpreted by DCL, but Compaq strongly
recommends that any DCL command line start with a dollar sign.
15.2 Using Labels in Command Lines
Labels are used in DCL command procedures to mark the beginning of
loops, sections of code, or subroutines. Note the following rules when
- Put labels on separate lines to make loops, subroutines, and
conditional code more visible.
- Use label names that contain fewer than 255 characters and no blank
- Differentiate labels from commands by placing labels immediately
after the dollar sign ($) and by preceding commands with spaces.
- End each label with a colon.
- You cannot delete labels.
15.2.1 Labels in Local Symbol Tables
As the command interpreter encounters labels, it enters them in a
special section of the local symbol table. The amount of space
available for labels is limited. If a command procedure uses many
symbols and contains many labels, the command interpreter might run out
of symbol table space and issue an error message. If this occurs,
include the DELETE/SYMBOL command in your procedure to delete symbols
as they are no longer needed. (Note, however, that you cannot delete
15.2.2 Duplicate Labels
If a command procedure uses the same label more than once, the new
definition replaces the existing one in the local symbol table.
When duplicate labels exist, the GOTO command transfers control to the
label that DCL has processed most recently. The GOTO command also uses
the following rules when processing duplicate labels:
- If all duplicate labels precede the GOTO command, control transfers
to the label nearest the GOTO command.
- If duplicate labels precede and follow the GOTO command, control
transfers to the preceding label nearest the GOTO command.
- If all duplicate labels follow the GOTO command, control transfers
to the label nearest the GOTO command.
15.3 Using Comments in Command Procedures
It is good programming practice to include comments in command
procedures. Comments can be helpful when updating or troubleshooting
the command procedure. Comments can be used as follows:
- At the beginning of a procedure to describe the procedure and the
parameters passed to it.
- At the beginning of each block of commands to describe that section
of the procedure.
- To separate command sequences with lines containing both a dollar
sign and an exclamation point ($!). This makes it easier to see the
outline of the command procedure. If you insert blank lines, the
command interpreter interprets them as data lines and produces a
message warning you that the data lines were ignored.
The following rules apply when writing comments in command procedures:
- Use an exclamation point (!) to indicate the beginning of a
comment; the command interpreter ignores all text to the right of an
exclamation point when the command procedure executes.
- To include a literal exclamation point in a command line, enclose
the exclamation point in quotation marks (" ").
15.4 How to Write Command Procedures
Before you begin writing a command procedure, perform the tasks
interactively that the command procedure will execute. As you type the
necessary commands, note any variables and conditionals that are used,
and any iterations that occur.
The following sections contain the steps to write a simple command
procedure. The example used throughout these sections is a command
procedure called CLEANUP.COM. This procedure can be used to clean up a
Data that changes each time you perform a task.
Any command or set of commands that can vary and therefore must be
tested each time you perform the task.
Any command or set of commands that are performed repetitively
until a condition is met.
15.5 Steps for Writing Command Procedures
Follow these steps to write a command procedure:
Design the command procedure.
Assign variables and test conditionals.
End the command procedure.
Test and debug the program logic.
Add cleanup tasks.
Finish the procedure.
15.5.1 Step 1: Design the Command Procedure
Follow these steps to design a command procedure:
Decide which tasks your procedure will perform.
Determine any variables your command procedure will use and how they
will be loaded.
Determine what conditionals the command procedure requires and how you
will test them.
Decide how you will exit from the command procedure.
There are certain commands that are usually executed during clean up
operations. The following table lists those commands and the tasks that
Displays the contents of the current directory
Displays a file
Purges a file
Deletes a file
COPY filespec new-filespec
Copies a file
Any data that changes when you perform a task is a variable. If you
create or delete files in your directory, the file names will be
different each time you clean your directory; therefore, the file names
in CLEANUP.COM are variables.
Any command that must be tested each time you execute a command
procedure is considered conditional. Because any or all of the commands
in CLEANUP.COM might be executed, depending on the operation you need
to perform, each command is conditional.
After you have determined what variables and conditionals you will use
in the CLEANUP.COM command procedure, you must decide how to load the
variables, test the conditionals, and exit from the command procedure.
For the CLEANUP.COM command procedure, the following decisions have
The command procedure gets the file names from the terminal.
The command procedure:
- Gets a command name from the terminal and executes the appropriate
statements based on the command name.
- Ensures that the first two characters of each command name are read
to differentiate between the DELETE and DIRECTORY commands.
Exit from loop
You must enter the EXIT command to exit from the loop.
To make command procedures easier to understand and maintain, write
statements so the procedures execute from the first command to the last
15.5.2 Step 2: Assign Variables and Test Conditionals
There are many ways to assign values to variables. In this section, we
will discuss using the INQUIRE command. For additional methods, see
Follow these steps to assign values to variables and test conditionals:
Assign values to variables using the INQUIRE command.
Determine which action should be taken.
Test the conditional using IF and THEN statements.
Write program stubs and insert them into the command procedure as
placeholders for commands.
Write error messages, if necessary.
18.104.22.168 Using the INQUIRE Command
The INQUIRE command prompts for a value, reads the value from the
terminal, and assigns the value to a symbol.
By default, the INQUIRE command:
- Converts responses to uppercase
- Replaces multiple blanks and tabs with a single space
- Removes leading and trailing spaces
- Performs apostrophe substitutions if the response includes symbols
or lexical functions
The following command line is used in CLEANUP.COM to prompt the user
for a command name. The INQUIRE command equates the value entered to
the symbol COMMAND.
$ INQUIRE COMMAND-
"Enter command (DELETE, DIRECTORY, PRINT, PURGE, TYPE)"
22.214.171.124 Preserving Literal Characters
To preserve lowercase characters, multiple spaces and tabs when using
the INQUIRE command, enclose your response in quotation marks (" "). To
include quotation marks in your response, enclose the quoted text in
quotation marks (""text"").
126.96.36.199 Testing Conditionals Using IF and THEN
After the INQUIRE command prompts for a variable, the command procedure
must include a statement that determines what action is to be taken.
For example, to determine which command to execute, you must include
statements in the command procedure that check the command entered by
the user against each possible command.
To test whether a condition is true, use the IF and THEN commands. The
following table shows the possibilities that you must check for in
a match is found,
execute the command.
a match is not found,
go on to the next command.
no match is found after all valid commands have been checked,
output an error message.
188.8.131.52 Writing Program Stubs
A program stub is a temporary section of code that you
use in your procedure while you test the design. Usually, a program
stub outputs a message stating the function that it is replacing. After
the overall design works correctly, replace each stub with the correct
Example: Assigning Variables and Testing Conditionals
The following example shows how to assign variables and test
$ INQUIRE COMMAND-
"Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
$ IF COMMAND .EQS. "EXIT" THEN EXIT
$! Execute if user entered DELETE
$ IF COMMAND .NES "DELETE" THEN GOTO DIRECTORY (1) (2)
$ WRITE SYS$OUTPUT "This is the DELETE section." (3)
$! Execute if user entered DIRECTORY
$ DIRECTORY: (4)
$ IF COMMAND .NES "DIRECTORY" THEN GOTO PRINT
$ WRITE SYS$OUTPUT "This is the DIRECTORY section."
$! Execute if user entered TYPE
$ IF COMMAND .NES "TYPE" THEN GOTO ERROR (5)
$ WRITE SYS$OUTPUT "This is the TYPE section."
$ WRITE SYS$OUTPUT "You have entered an invalid command." (6)
As you examine the example, note the following:
- This IF statement tests to see if the command
that the user entered (COMMAND) is equal to "DELETE". If COMMAND is
equal to DELETE, then the command procedure executes the next command.
- This statement also includes a GOTO command.
A GOTO command is used to change the flow of execution to a label in
the procedure. In this case, the procedure will go to the DIRECTORY
label if COMMAND is not equal to DELETE.
- This statement is a program stub. After the
logic of the command procedure is tested, this line will be replaced
with the actual commands required for a DELETE operation.
- This is the label for the DIRECTORY
subroutine. Note that the labels that identify each command block are
the same as the commands on the option list. This allows you to use the
symbol COMMAND (which is equated to the user's request) in the GOTO
- This IF statement tests to see if the "TYPE"
command was entered. If "TYPE" was entered, the procedure will output
"This is the TYPE section." However, because this is the last command
you will be testing for, if the command entered is not "TYPE," the
program will display an error message.
- If all commands have been tested and no valid
command name is found, then the program will output, "You have entered
an invalid command."
15.5.3 Step 3: Add Loops
A loop is a group of statements that execute repeatedly until a
condition is met. A loop works as follows:
- Obtains a value from user input
- Processes the command
- Repeats the process until the user exits the command procedure
To write a loop, follow this procedure:
Begin the loop with a label.
Test a variable to determine whether you need to execute the commands
in the loop.
If you do not need to execute the loop, go to the end of the loop.
If you need to execute the loop, perform the commands in the body of
the loop, then return to the beginning of the loop.
End the loop.
The following example shows the usage of loops in the CLEANUP.COM
$ INQUIRE COMMAND-
$ "Enter command (DELETE, DIRECTORY. EXIT, PRINT, PURGE, TYPE)"
$ IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
$! Execute if user entered DELETE
$ IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
$ WRITE SYS$OUTPUT "This is the DELETE section."
$ GOTO GET_COM_LOOP
$ WRITE SYS$OUTPUT "Directory ''F$DIRECTORY()' has been cleaned"
Once a command executes, control is passed back to the GET_COM_LOOP
label until a user enters the EXIT command. When an EXIT command is
entered, the procedure outputs a message stating that the directory has