|
The online home of
the company bringing you quality HP hardware and software support |
| CI Scripting Techniques |
| Writing
Command Interpreter (CI) Scripts often involves manipulating the output
of other commands. Command I/O Redirection (CIOR) is utilized to direct
the output of commands and programs into files for processing. There
are no direct file processing commands built into the CI. Therefore
CIOR is again utilized to read the contents of files into CI variables.
Stepping through each record of a file is another challenge altogether. When a program processes a file it first FOPENs the file and then FREADs records one at a time until it reaches EOF. The file system automatically places the record pointer at the first record of the file when it is opened, and moves the pointer forward for each subsequent FREAD. But when redirecting an MPE command to input data from a file, the the first record is always read because each command causes a separate FOPEN. There are several
common techniques for working around this behavior. I have written
three different versions of the same command file to illustrate
these approaches. Each one of them functions and provides the same
output; a list of files with a specific file code. Each one captures
the output of a LISTF command into a file then reads and processes
the contents of the file searching for and displaying lines that
contain the file code. It is the manner in which the files are handled
that distinguishes each style. The first method uses the PRINT command to step through each record of the file. The number of records in the file is determined (NumRecs) and a loop is performed incrementing a counter (RecCount) until the counter reaches the number of records indicating the end of file has been reached. The Message File Option The second method is to use message files (sometimes called FIFO files) to control the input of data. What differentiates message files from standard flat files is that records are deleted from the file after they are read. This is handled for you automatically by the MPE file system. So while each FOPEN will put the record pointer at the first record of the file, the previous first record has been removed and the next record in the file has bubbled up to the top. As each record is read and deleted the end of file counter changes. The loop is performed until the end of file reaches zero. Multiple Entry Points While both of the previous approaches are easy to write and follow they are terribly inefficient - especially if you are processing a large file. Each record read or written to a file using CIOR requires an FOPEN, FREAD or FWRITE, and an FCLOSE. FOPEN's are expensive operations to perform. Larger input files require more FOPENs. Here is the same command script written in a much different fashion. By using I/O redirection for the entire command script instead of the individual MPE commands within the script, we can cause MPE to only FOPEN the input file one time. Why? Because the $STDIN for the entire script is redirected much like when you redirect the keyboard input to a file for a compiled program. I have created a single command file with multiple entry points or subroutines. This allows me to create a single command file to maintain instead of two separate files. There are actually several techniques within this script that are worth discussing. The key to understanding this scripting approach is to understand the following line, which invokes the command file for a second time.
xeq !hpfile Notice the use of the !HPFILE variable. HPFILE always contains the name of the currently running command file. By running the variable instead of a hardcoded command file name I can rename the file or move it to another location without having to modify the name of the file contained inside. FileCode="!FileCode",sub="_sub1" <infile This component of the command has three important pieces. First, it is passing the FileCode parameter for processing. FileCode is not actually used by _main section but must be passed on to the _sub1. Second, it is invoking the command file telling it to use the "_sub1" subroutine. Third, it is redirecting the $STDIN for the command file to INFILE. The INPUT command which would normally obtain all input from $STDIN will now get it from INFILE. Furthermore, since the file is not closed and reopened the record pointer is not reset to the beginning of the file.
This command is both simple and complicated at the same time. It is simply the beginning of a WHILE loop. The interesting part is that it uses SETVAR as both a command and a function simultaneously. The value of NumRecs decrements by one for each iteration of the while loop and the result is not only stored in NumRecs but also evaluated. This is a shortcut for the following code
Posix Anyone? Posix aficionados, here is a solution for you too! This script will use GREP and Regular Expressions as a replacement for the entire loop above. If you are not familiar with GREP it is a utility that searches for strings within files.
Summary Command Interpreter scripting can be a convenient method for quickly writing programs. But inefficiently written command scripts can be a drain on system resources. If you need help incorporating any of the techniques here and applying them in your environment please feel free to call. |
Send mail to
webmaster@beechglen.com with
questions or comments about this web site.
Copyright © 2006
Beechglen Development Inc.
Last modified:
01/20/06