By Ken Robertson
[Ed. Note: Bob Green of Robelle reminds us that both MPE and Unix have scripts, but there are a number of differences. To explain, he offers this article written when Ken Robertson was at Robelle.]
Before MPE/iX, there was a run-time environment for the MPE/V class of HP computers called the Command Interpreter (CI). This MPE/V CI had limited programming capability, with If/Else constructs and numeric variables limited to values between 0 and 65535. The basic interface of the MPE/V CI (Command Interpreter) was ported to MPE/iX machines, and beefed up so it would be usable as a run-time shell.
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 filename, length=”80”
2. Option lines:
3. The body (i.e., the actual commands)”
In MPE scripts, there is no inline data, unlike Unix ‘hereis’ files.
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:
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”
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 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
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.