Making CI variables more Unix-like
March 20, 2020
By John Burke
How can you make CI variables behave more Unix-like?
For those of us who grew up on plain old MPE, CI variables were a godsend. We were so caught up in the excitement of what we could do with CI variables and command files, it took most of us a while to realize the inadequacy of the implementation. For those coming to MPE/iX from a Unix perspective, CI variables seem woefully inadequate. There were two separate questions from people with such a Unix perspective that highlighted different “problems” with the implementation of CI variables.
But first, how do CI variables work in MPE/iX? Tom Emerson gave a good, concise explanation.
“SETVAR is the MPE/iX command for setting a job/session (local) variable. I use ‘local’ somewhat loosely here because these variables are ‘global’ to your entire job or session and, by extension, are automatically available to any sub-processes within your process tree. There are some more-or-less ‘global’ variables, better known as SYSTEM variables, such as HPSUSAN, HPCPU, etc.”
The first questioner was looking for something like user-definable system variables that could be used to pass information among separate jobs/sessions. Unfortunately, no such animal exists. At least not yet, and probably not for some time if ever.
There is, however, a workaround in the form of UDCs created by John Krussel that implement system, account and user-level variables. The UDCs make use of the hierarchical file system (HFS) to create and maintain “variables.”
The second questioner was looking for something comparable to shell variables which are not automatically available at all levels. You have to export shell variables for them to be available at lower levels. Thus, there is a certain locality to shell variables.
It was at this point that Jeff Vance, HP’s principal CI Architect at CSY, noted that he had worked on a project to provide both true system-wide and local CI variables (in fact, the design was complete and some coding was done). Jeff offered a suggestion for achieving locality.
Variable names can be created using CI depth, PIN, etc. to try to create uniqueness. E.g.,
setvar foo!hppin value
setvar foo!hpcidepth value1
Mark Bixby noted that CI variables are always job/session in scope, while shell variables are local, but inherited by children if the variables have been exported. He suggested that if, working in the CI, some level of locality could be achieved by “making your CI script use unique variable names. If I’m writing a CI script called FOO, all of my variable references will start with FOO also, i.e.
SETVAR FOO_XX “temp value”
SETVAR FOO_YY “another value”
DELETEVAR [email protected]
“That way FOO’s variables won’t conflict with any variables in any parent scripts.”
HP has a formally documented recommendation for creating “local-ness.”
MPE: How to create CI variables with local (command file) scope
Problem Description: I have separate command files that use the same variable names in them. If one of the command files calls the other, then they both affect the same global variable with undesirable results. Is there the concept of a CI variable with its scope local to the command file?
Solution: No. All user-defined CI variables have global (JOB/SESSION) scope. Some HP Defined CI variables (HPFILE, HPPIN, HPUSERCMDEPTH) return a different value depending on the context within the JOB/SESSION when they are called.
HPFILE returns the fully qualified filename of the command file.
HPPIN returns the PIN of the calling process.
HPUSERCMDEPTH returns the command file call nesting level.
To get the effect of local scope using global variables, you need a naming convention to prevent name collisions. There are several cases to consider.
Command file CMDA calls CMDB, both using varname VAR1.
• Use a hardcode prefix in each command file.
In CMDA use: SETVAR CMDA_VAR1 1
In CMDB use: SETVAR CMDB_VAR1 2
• Use HPFILE.
SETVAR ![FINFO(HPFILE,”FNAME”)]_VAR1 1
• Use HPUSERCMDEPTH.
SETVAR D!”HPUSERCMDEPTH”_VAR1 1 (Note: need a leading non digit)
Command file CMDA calls itself, uses varname VAR1.
• Same answer as case 1, the third solution: use HPUSERCMDEPTH.
There are two son processes. Each one calls CMDA which calls CMDB at the same nesting level.
• Same answer as case 1, the third solution: use HPUSERCMDEPTH. Not sure if this will work since not sure if HPUSERCMDEPTH is reset at JSMAIN, CI, or user process level.
• Use HPPIN and HPUSERCMDEPTH.
SETVAR P!”HPPIN”_!”HPUSERCMDEPTH”_VAR1 1
•Use HPPIN, HPUSERCMDEPTH and HPFILE (guaranteed unique, hard to read)
SETVAR P!”HPPIN”_!”HPUSERCMDEPTH”_![FINFO(HPFILE,”FN AME”)]_![FINFO(HPFILE,
“GROUP “)]_![FINFO(HPFILE,”ACCT”)]_VAR1 1
Again, there is no true local scope, only global scope for CI variables within any one session/job. The techniques presented above do provide at least a reasonable workaround for both system-wide and process-local variables.