A recent question on the 3000-L mailing list and newsgroup asked for help on scripting. The question aimed at the automation prospects through terminal emulation programs. Does Minisoft/92 script, a manager asked. Of course, and Tracy Johnson replied to give details as well as an example.
Minisoft scripts are plain text files with a file extension of .s92 and can be assigned to function keys f1 through f12. We use the keyboard mapping config menu to map it to Type "Script". Once you choose "Script" a blank box appears below where you put the magic words DO SCRIPT followed by a path including the file name.
Last week, the use of scripts also surfaced while talking to Birket Foster about data migrations. A client of Fosters runs five scripts to clean up phone numbers during a transfer of data. Being able to reach for the scripts improved the quality of data, and the work was automatic. the power of scripting reminded me of a fine column written for us by Ken Robertson. Its subject was an introduction for Unix administrators to the use of shell scripts. But the writing was the kind of operational lore that can make a 3000 look more powerful to an admin new to the 3000. Robertson wrote about it for the Newswire.
The marvels of scripting lie deep in the roots of MPE. When HP expanded the OS to MPE/XL in the 1990s, it added the Posix shell, which extended the 3000's scripting potential. 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 IO on files allows the end-user to perform simple data-processing functions. The Command Interpreter 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.
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 a Posix shell on MPE, most scripts are written for the CI.
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.