Est. 1987 Intermediate

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)

Paradigm Imperative, Procedural, Scripting
Typing Dynamic; variables hold 32-bit integers, strings, or Booleans
First Appeared 1987
Latest Version MPE/iX 7.5 (August 2002), the final MPE/iX release

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 !name and ![expression]
  • An expression evaluator shared by SETVAR, IF, ELSEIF, WHILE, and CALC, with string functions and the file-inquiry function FINFO
  • WHILE / ENDWHILE loops
  • Command files, scripts that need no cataloging and are found through the HPPATH search path
  • Implied RUN: typing a program’s name runs it
  • ECHO, INPUT (with an optional timeout), RETURN, and CALC

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, and HPPIN variables. It also extended FINFO with 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, and ERRCLEAR, along with evaluator functions such as WORD, PMATCH, REPL, and EDIT. 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:

  1. 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.
  2. 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.
  3. Information should be asked for, not inferred. The predefined variables and functions such as FINFO replaced 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:

GroupFunctions (as documented for MPE/iX 5.5)
StringsLEN, STR, LFT, RHT, POS, UPS, DWNS, LTRIM, RTRIM, RPT, REPL, EDIT, WORD, DELIMPOS, PMATCH
ConversionCHR, ORD, HEX, OCTAL
TestsALPHA, ALPHANUM, NUMERIC, ODD, BOUND, TYPEOF
NumericABS, MAX, MIN
SystemFINFO, 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

1983
Eugene Volokh of VESOFT presents "MPE Programming" at the INTEREX conference in Montreal, showing how much could be done with MPE V commands, UDCs, and job control words alone. He later admitted that many of the tricks "bordered on the perverse"
1987
HP introduces the HP 3000 Series 930, its first PA-RISC HP 3000, with the new MPE XL operating system. MPE XL's Command Interpreter adds variables, expressions, WHILE loops, command files, the HPPATH search path, and implied RUN
1988
The Communicator for the MPE XL A.01.10 production release (printed January 1988) carries Jeff Vance and John Korondy's article "The New MPE XL User Interface". It describes the CI's evolution "from a command interpreter to an interpretive command language". MPE XL Release 1.0 (A.02.00) follows in April 1988
1991
MPE XL Release 3.0 (Communicator printed May 1991) adds Command I/O Redirection, so CI commands, UDCs, command files, and programs can read from and write to files with <, >, and >>
1992
The operating system is renamed MPE/iX with Release 4.0 (dated October 1992 by the HP Computer Museum) to signal POSIX and Unix interoperability. Release 4.5 adds the hierarchical file system and ships the HPPXUDC.PUB.SYS file of POSIX helper UDCs
1994
According to HP's Communicator, MPE/iX 5.0 raises the maximum command line from 279 to 511 bytes, adds the HPCWD, HPFILE, and HPPIN variables and new POSIX-aware FINFO items, and makes the POSIX MPE/iX Shell and Utilities part of the base operating system
1996
The MPE/iX 5.5 Commands Reference (ninth edition) documents XEQ, ESCAPE, and ERRCLEAR and evaluator functions such as WORD, PMATCH, and REPL, which do not appear to be covered in the 1994 CI programmer's guide
2001
On November 14, 2001, HP announces it will end the HP e3000 product line and MPE/iX
2002
MPE/iX 7.5, the final release of the operating system and its Command Interpreter, ships in August 2002
2003
HP stops selling new e3000 systems on October 31, 2003
2010
HP support for MPE/iX ends at the close of 2010, after the original end-of-support date of December 31, 2006 was pushed back. Third-party firms continue to support the platform
2011
Stromasys puts CHARON-HPA/3000 into beta on September 7, 2011. It is a virtual HP 3000 that runs an unmodified MPE/iX, so CI scripts can keep running on commodity hardware

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

Language Influence

Influenced By

MPE V Command Interpreter (UDCs and JCWs)

Running Today

Run examples using the official Docker image:

docker pull
Last updated: