MPE/iX Command Interpreter Script
The command language of Hewlett-Packard's HP 3000: UDCs, command files, variables, and an expression evaluator that turned the MPE XL and MPE/iX Command Interpreter into a scripting language for business minicomputers.
Created by Hewlett-Packard (Commercial Systems Division / Information Technology Group)
The MPE/iX Command Interpreter (CI) is the command language of Hewlett-Packard’s HP 3000 business computers. Its scripts take two forms: user-defined commands (UDCs) kept in cataloged UDC files, and command files, which are plain files run by name. HP 3000 programmers and system managers used them for logon procedures, batch job streams, and system utilities. The CI started out as a simple command processor on the original 16-bit HP 3000. When HP moved the line to PA-RISC in 1987 as MPE XL (renamed MPE/iX in 1992), HP’s engineers deliberately turned it into what they called “an interpretive command language”, with typed variables, an expression evaluator, loops, and parameterized scripts.
History & Origins
The MPE V starting point
MPE (Multi-Programming Executive) was the operating system of the HP 3000 from the early 1970s. By the time of MPE V, the CI already had UDCs, job control words (JCWs) (small integer variables used mainly for status codes), and an IF / ELSE / ENDIF construct that tested JCWs. That was enough to write simple procedures. It was not enough to write real programs in the CI.
In 1983 Eugene Volokh of VESOFT presented a paper called “MPE Programming” at the INTEREX conference in Montreal. It showed how far you could push MPE V’s CI without writing a compiled program. Looking back on it in 1988, he admitted that many of the tricks “bordered, I must admit, on the perverse”. To find out whether a UDC was running in a batch job or an interactive session, for example, you ran the :RESUME command purely for its side effect and then checked which error number ended up in the CIERROR JCW. To test whether a file existed, you ran :LISTF on it with output sent to $NULL and checked for error 907.
MPE XL: “an interpretive command language”
HP’s first PA-RISC HP 3000, the Series 930, arrived in 1987 with a new operating system, MPE XL. The HP Computer Museum dates MPE XL Release 1.0 to April 1988. Alongside the move to the new architecture, HP rebuilt the user interface. Jeff Vance and John Korondy of HP’s Information Technology Group described it in the Communicator for the A.01.10 production release (printed January 1988):
“This can be viewed as the evolution of the CI from a command interpreter to an interpretive command language… Like most programming languages, the CI supports variables, expression evaluation, and logic flow control via recursion, iteration (while), and conditional constructs (if, else, endif).”
Their article set out four goals: compatibility with MPE V/E, groundwork for localizing the user interface, a productive environment for both new and experienced users, and access to the advantages of HP Precision Architecture. Most MPE V commands were carried over unchanged in Compatibility Mode. New and enhanced commands ran in Native Mode, where a central parser gave them consistent syntax.
The new scripting features were:
- Variables set with
SETVAR, holding integers, strings, or Booleans, plus a large set of predefined variables (HPUSER,HPACCOUNT,HPGROUP,HPINTERACTIVE,HPJOBNUM,HPPATH,HPPROMPT, and many more) - Substitution of variables and of whole expressions into any command line with
!nameand![expression] - An expression evaluator shared by
SETVAR,IF,ELSEIF,WHILE, andCALC, with string functions and the file-inquiry functionFINFO WHILE/ENDWHILEloops- Command files, scripts that need no cataloging and are found through the
HPPATHsearch path - Implied RUN: typing a program’s name runs it
ECHO,INPUT(with an optional timeout),RETURN, andCALC
Volokh’s follow-up paper, “MPE XL Programming” (INTEREX Orlando, 1988), said that HP had “to a large extent” succeeded in making CI programming “a straightforward proposition”. The job-versus-session test that once needed the :RESUME hack became a single IF HPINTERACTIVE THEN.
From MPE XL to MPE/iX
Later releases kept adding to the language:
- XL Release 3.0 (1991) added Command I/O Redirection, credited in HP’s Communicator to Scott Cressler, Jeff Vance, and Rich Webber. With it,
<,>, and>>work on CI commands, UDCs, command files, and programs. - Release 4.0 (October 1992, per the HP Computer Museum) renamed the operating system MPE/iX “to indicate Unix interoperability with the addition of POSIX compatibility”. Release 4.5 added the hierarchical file system.
- Release 5.0 (1994), as described in HP’s Communicator, raised the command-line limit from 279 to 511 bytes and added the
HPCWD,HPFILE, andHPPINvariables. It also extendedFINFOwith POSIX-aware items 38 through 53 and bundled the POSIX MPE/iX Shell and Utilities with the operating system. - Release 5.5 (1996): its Commands Reference documents
XEQ,ESCAPE, andERRCLEAR, along with evaluator functions such asWORD,PMATCH,REPL, andEDIT. They do not appear to be covered in the 1994 Command Interpreter Access and Variables Programmer’s Guide. - MPE/iX 7.5 (August 2002) was the last release of the operating system.
Design Philosophy
The CI’s design comes from three constraints:
- Never break MPE V. Old commands kept their syntax and their error numbers. JCWs kept working, and CI variables were designed as “a powerful extension of JCWs” rather than a replacement. The expression evaluator explicitly kept compatibility with MPE V/E JCW evaluation.
- The CI is the scripting language. HP did not ship a separate scripting tool. The commands an operator types at the colon prompt are the same commands a script runs, and any command can be wrapped in a UDC or a command file and then called like a built-in.
- Information should be asked for, not inferred. The predefined variables and functions such as
FINFOreplaced the old habit of running a command just to read its error code.
Key Features
Hello, World
At the CI’s colon prompt, or as the only line of a command file:
:ECHO Hello, World!
Hello, World!
UDCs
A UDC file holds one or more commands. Each starts with a header line giving its name and parameters, may have OPTION lines, and ends at a line of asterisks starting in column 1. This example is from HP’s Command Interpreter Access and Variables Programmer’s Guide:
SJ
OPTION LOGON
SHOWJOB
*****
LF
LISTFILE
*****
ABXYZ A,B=B
OPTION LIST
RUN !A.PUB.SYS
RUN !B.PUB.SYS
RUN XYZ
*****
A UDC file must be cataloged with SETCATALOG before its commands exist. UDCs can be cataloged at the user, account, or system level, and the CI searches them before its built-in commands, so a UDC can replace a standard MPE command. OPTION LOGON runs a UDC automatically when the user logs on. Other options control listing (LIST/NOLIST), help visibility (HELP/NOHELP), breakability (BREAK/NOBREAK), and recursion.
Command files
A command file is an ordinary file of commands. If it takes parameters, its first line is a PARM declaration, and required and optional parameters are declared the same way as in UDCs:
PARM p1, p2=10, p3=""
Command files do not need cataloging. The CI looks for them only after built-in commands, in the groups listed in the HPPATH variable (by default !HPGROUP,PUB,PUB.SYS). If a command file’s name clashes with a built-in command, XEQ runs the file anyway. The same search path finds program files, so you can run a program by typing its name (implied RUN).
The following illustrative example (not taken from HP’s manuals) uses the file-size items Volokh describes for FINFO (19 is the end-of-file record count and 12 is the file limit) to warn when a file is almost full:
PARM fname, minfree=10
IF NOT FINFO("!fname",0) THEN
ECHO File !fname does not exist.
RETURN
ENDIF
SETVAR pctused FINFO("!fname",19) * 100 / FINFO("!fname",12)
IF 100 - pctused < !minfree THEN
ECHO WARNING: !fname is ![pctused]% full
ENDIF
Variables and dereferencing
SETVAR infers the type from what you give it: a quoted value makes a string, an unquoted number makes an integer, and TRUE or FALSE makes a Boolean. An unquoted name copies the value of another variable. Variables last for the whole job or session, so HP’s guide recommends giving each command file’s variables a common prefix and cleaning them up with a wildcard (DELETEVAR CM_@).
The CI has three kinds of dereferencing. Implicit dereferencing happens inside expressions, where a bare variable name stands for its value. Explicit dereferencing uses !name to substitute a value into any command line. Recursive dereferencing uses !!name to delay substitution until the outer variable is itself used. HP’s documentation uses recursive dereferencing to explain why the default search path keeps working when you change groups:
:SHOWVAR HPPATH
HPPATH = !HPGROUP,PUB,PUB.SYS
:SETVAR HPPATH "!!HPGROUP,SCRIPTS.SYS,PUB.SYS"
:SHOWVAR HPPATH
HPPATH = !HPGROUP,SCRIPTS.SYS,PUB.SYS
Expressions and functions
The expression evaluator does integer arithmetic (including MOD and ^), compares strings and numbers, and provides logical and bitwise operators (AND, OR, XOR, NOT, BAND, BOR, LSL, CSR, and others). Its library of functions includes:
| Group | Functions (as documented for MPE/iX 5.5) |
|---|---|
| Strings | LEN, STR, LFT, RHT, POS, UPS, DWNS, LTRIM, RTRIM, RPT, REPL, EDIT, WORD, DELIMPOS, PMATCH |
| Conversion | CHR, ORD, HEX, OCTAL |
| Tests | ALPHA, ALPHANUM, NUMERIC, ODD, BOUND, TYPEOF |
| Numeric | ABS, MAX, MIN |
| System | FINFO, INPUT, SETVAR |
Two of these are unusual. SETVAR() as a function assigns a variable and returns the value, so a loop counter can be increased inside the loop’s own test. INPUT() as a function prompts the user from within an expression. The + and - operators also work on strings: "abc" + "de" concatenates, and "abc" - "b" deletes the first occurrence of "b".
Control flow
The CI has IF / ELSEIF / ELSE / ENDIF, WHILE / ENDWHILE, and recursion. It has no GOTO. RETURN leaves the current UDC or command file. Volokh’s 1988 paper loops over a range of job numbers like this:
SETJCW I = 295
WHILE I < 314
ABORTJOB #J!I
SETJCW I = I+1
ENDWHILE
Error handling
A CI error normally stops a batch job, or clears the user command stack and returns a session to the prompt. CONTINUE lets the next command fail without that happening. After a command runs, CIERROR and HPCIERR hold its result, with a negative HPCIERR meaning a warning. ESCAPE lets a script raise an error of its own. This example is from HP’s command reference:
errclear
continue
run database
if hpcierr < 0 then
echo database warning ![abs(hpcierr)] detected, proceeding...
elseif hpcierr > 0 then
echo FATAL database error !hpcierr detected, halting...
escape
endif
Input, output, and redirection
ECHO writes text, and INPUT reads into a variable with an optional prompt and timeout:
ECHO Enter 0 to exit.
ECHO 1 to review database.
ECHO 2 to update database.
INPUT CHOICE,"Which number do you select?",15
Since Release 3.0 most commands can redirect their input and output:
LISTFILE @[email protected],2 > FILELIST
ECHO find "patt1" >> EDINPUT
INPUT RECORD <INFILE
IF, WHILE, CALC, SETVAR, REMOTE, and COMMENT cannot be redirected, because < would be ambiguous in their expressions. One catch is easy to miss: each redirected INPUT RECORD <INFILE opens the file again and reads only its first record. The CI has no file-reading command of its own, so reading a whole file line by line meant keeping it open across the loop.
The CI and the POSIX Shell
From MPE/iX 4.5 and 5.0, the HP 3000 had a second command language: the MPE/iX Shell and Utilities, a POSIX.2 shell with more than 100 utilities. HP pointed users familiar with the Korn shell to it. The shell has a callci built-in for running CI commands, and HP’s SH UDC in HPPXUDC.PUB.SYS started the shell with its environment files. HP’s 5.0 Communicator lined up the two languages command by command: CHDIR against cd, LISTFILE against ls, PRINT against more, LISTREDO against history, and “UDCs, Command Files” against shell functions. The CI remained the native language for jobs, logon procedures, and system management.
Current Relevance
HP announced the end of the HP 3000 line on November 14, 2001. MPE/iX 7.5 (2002) was the final release, sales stopped on October 31, 2003, and HP’s own support ran until the end of 2010. Third-party support firms kept working with MPE/iX after that. Stromasys CHARON-HPA emulates HP 3000 hardware and runs an unmodified copy of MPE/iX. It entered beta on September 7, 2011, and its first product emulated an HP e3000 A400 server; Stromasys reportedly supports MPE/iX 7.5 on later versions. Through emulation, sites that still depend on HP 3000 applications keep their decades-old UDCs, command files, and job streams in use.
No official or community Docker image runs MPE/iX, and the operating system remains proprietary.
Why It Matters
The MPE/iX CI is a clear example of a vendor command interpreter growing into a real scripting language without breaking what came before. Its features follow from the needs its designers wrote down. Variables are a superset of the existing JCWs. Command files make UDC-style scripts possible without cataloging. A search path and implied RUN make scripts, programs, and built-ins look the same to the user. Introspection variables and FINFO replaced “programming by side effect”. The language also kept a well-documented record of its own design. HP’s Communicator articles credit named engineers and explain their trade-offs: UDCs for stable, frequently used commands and for overriding built-ins, and command files for scripts that change often. In many HP 3000 shops, whose business logic typically lived in COBOL programs and IMAGE databases, CI scripts handled much of the day-to-day operation of the system.
Timeline
Notable Uses & Legacy
HP 3000 System Administration and Batch Job Streams
HP 3000 job streams (the :JOB ... :EOJ files submitted with STREAM) and logon UDCs are written in CI commands. System managers used IF, WHILE, and CI variables to drive nightly batch runs, backups (STORE), spooler management, and account maintenance
HP's own POSIX transition UDCs
From MPE/iX 4.5, HP shipped HPPXUDC.PUB.SYS, a UDC file of helper commands written in the CI language. According to HP's 5.0 Communicator, in Release 5.0 it held FINDFILE, FINDDIR, LISTDIR, PLISTF (renamed from a LISTF override that had caused problems for HPCICOMMAND callers), and an SH command that starts the POSIX shell with the right options
VESOFT MPEX/3000 and SECURITY/3000
Eugene Volokh wrote that while porting these VESOFT utilities to MPE XL, the company also built most of the new MPE XL user-interface features into the MPE V version of MPEX and into SECURITY/3000's STREAMX module, so users of older 'classic' HP 3000s could use them too
Perl on MPE/iX (MPE::CIvar)
Ken Hirsch's CPAN module MPE::CIvar (version 1.11, November 2001) let Perl programs on MPE/iX read and set CI variables and JCWs. Perl code could then share state with the CI scripts and job streams around it
Emulated HP 3000 environments
Organizations that kept MPE/iX applications after HP's exit can run them on Stromasys CHARON-HPA, which runs an unmodified copy of MPE/iX. Their existing UDCs, command files, and job streams come along without change