By Ken Robertson
The MPE/iX command interpreter has a generous command set, pushing the shell into the realm of a true programming tool. Its ability to evaluate expressions and to perform I/O on files allows the end-user to perform simple data-processing functions. The CI can be used to solve complex problems. Its code, however, is interpreted, which may cause a CI solution to execute too slowly for practical purposes.
Command files are a collection of commands in flat files, of either variable or fixed length record structure, that reside in the MPE or POSIX file space. Basically, command files are what you could call MPE Macros. Anything that you can do in the CI interactively, you can do with command files, and then some. You can use command files in situations that call for repetitive functions, such as re-compiling source code, special spooler commands, etc. Command files are also great when you want to hide details from the end-user.
A command file is executed when its name is typed in the CI, or invoked from a command file or programming shell. Just as in program execution, the user’s HPPATH variable is searched to determine the location of the command file.
MPE Scripts Versus Unix Scripts
For the average task, the MPE scripting language is easier to read and understand than most Unix scripts. For example, command line parameters in MPE have names, just like in regular programming languages.
Of course, there are several script languages on Unix and only one on MPE! On Unix you can write shell scripts for any of the many shells provided (C shell, Bourne shell, ksh, bash, etc). Although there is also now a Posix shell on MPE, most scripts are written for the CI. Several third-party tools, such as Qedit and MPEX, emulate HP scripting and integrate it with their own commands.
A command file can be as simple as a single command, such as a Showjob command with the option to only show interactive sessions (and ignore batch jobs):
:qedit
/add
1 showjob job=@s
2 //
/keep ss
/e
:
You have created a command file called SS — when you type SS you will execute showjob job=@s
On MPE, the user needs read (r) or execute access (x) to SS. On Unix you normally must have x access, not just r access, so you do a chmod +x on the script. This is not necessary in MPE, although, if don’t want users to be see the script, you may remove read access and enable execute access.
Structure of a Command File (aka CI script)
A script is an ASCII file with maximum 511 byte records. Unlike Unix, the records may contain an ASCII sequence number in the last 8 columns of each line. The command file consists of 3 optional parts:
1. Parameter line with a maximum of 255 arguments:
parm sessionnumber
parm filename, length=”80”
2. Option lines:
option nohelp,nobreak
option list
3. The body (i.e., the actual commands)”
showjob job=!sessionnumber
build !filename;rec=-!length,,ascii
In MPE scripts, there is no inline data, unlike Unix ‘hereis’ files.
Parameters
Notice in the example above that parameters are used with an exclamation (!), as opposed to the $ in Unix. The same is true for variables. Parameters are separated by a space, comma or semicolon. All parameter values are un-typed, regardless of quoting.
In a typical Unix script, the parameters are referenced by position only ($1, $2, $3, …). In an MPE script, the parameters have names, as in the function of a regular programming language, and can also have default values. In Unix you use $@ for all of the parameters as a single string; in MPE you use an ANYPARM parameter to reference the remainder of the command line (it must be the last parameter).
Here is a script to translate “subsys” and “err” numbers from MPE intrinsics into error messages. The subsys and error numbers are passed in as parameters:
parm p_subsys=108,p_error=63
setvar subsys hex(!p_subsys)
setvar error hex(!p_error)
comment the hex conversion allows for negative numbers
comment the #32765 is magic according to Stan!
setvar cmd “wl errmsg(#32765,!subsys);wl errmsg(!error,!subsys);exit”
debug !cmd
As you can see above, the Setvar command assigns a value to parameter or to a new variable. But there are also system pre-defined variables. To see them all do Showvar @;hp. To get information on variables, do help variable and to get help on a specific variable, say hpcmdtrace, do help hpcmdtrace (set TRUE for some debugging help).
In most MPE commands, you must use an explicit exclam ! to identify a variable: build !filename
However, some MPE commands expect variables, and thus do not require the explicit !. For example, Setvar, If, ElseIf, Calc, While, and for all function arguments, and inside ![expressions].
Warning: variables are “session global” in MPE. This means that if a child process, or scripts, changes a variable, it remains changed when that child process terminates. In Unix you are used to the idea that the child can do whatever it likes with its copy of the variables and not worry about any external consequences.
Of course having global variables also means that it is much easier to pass back results from a script! And this is quite common in MPE scripts.
Options
Options allow you to list the commands as they are execute (option list), disable the Break key (option nobreak), enable recursion (option recursion), and disable help about the script (option nohelp).
The script body below shows active process information. This example shows many of the commands commonly used in scripts: If, While, Pause, Setvar, Input and Run. Other commands you will see are Echo, Deletevar, Showvar, Errclear.
WHILE HPCONNSECS > 0
IF FINFO("SQMSG",0)
PURGE SQMSG,TEMP
ENDIF
BUILD SQMSG;REC=-79,,F,ASCII;TEMP;MSG
FILE SQMSG=SQMSG,OLDTEMP
SHOWQ;ACTIVE >*SQMSG
SETVAR PINLIST ""
WHILE FINFO("SQMSG",19) <> 0
INPUT SQLINE < SQMSG
IF POS("#",SQLINE) <> 0 THEN
SETVAR PIN RTRIM(STR(SQLINE,47,5))
SETVAR PINLIST "!PINLIST" + "," + "!PIN"
ENDIF
ENDWHILE
IF FINFO("SPMSG",0)
PURGE SPMSG,TEMP
ENDIF
BUILD SPMSG;REC=-79,,F,ASCII;TEMP;MSG
FILE SPMSG=SPMSG,OLDTEMP
SETVAR PROC "SHOWPROC PIN="+"!PINLIST"+";SYSTEM >*SPMSG"
!PROC
WHILE FINFO("SPMSG",19) <> 0
INPUT SPLINE < SPMSG
IF POS(":",SPLINE) <> 0 THEN
ECHO !SPLINE
ENDIF
ENDWHILE
PAUSE 30
ENDWHILE
Handling Errors
In most Unix scripts, if a step fails, you check for an error with an If-conditional and then take some action, one of which is ending the script. Without an If, the script continues on, ignoring the error.
In MPE, the default action when a step fails is to abort the script and pass back an error. To override this default, you insert a Continue command before the step that may fail. You then add If logic after the step to print an error message and perhaps Return (back 1 level) or Escape (all the way back to the CI).
continue
build newdata
if cierror<>100 then
print "unable to build newdata file"
print !hpcierrmsg
return
else
comment - duplicate file, okay
endif
You can set HPAUTOCONT to TRUE to continue automatically in case of errors, but this can be dangerous. The default behavior at least lets you know if an unexpected problem occurs.
User Defined Commands (UDC)
UDCs are like Command File scripts, except that several are combined in a single “catalog” file. They are an older feature of MPE, so you may see them in older applications even when scripts seem like a better solution. The primary reason that they are still useful is that they support Option Logon, which invokes the command when a user logs onto the system.
More Information
Tim Ericson’s collection of UDCs and Command files has recently been resurrected and re-published in the public domain at www.3kassociates.com/index_cmd.html
Image by fancycrave1 from Pixabay