hp e3000 strategy MPE CI Programming for 7.0 … and other tidbits presented by Jeff Vance, HP-CSY jeff_vance@hp.
hp e3000 outline (read the notes too!) strategy • redo - old features and new • common CI programming commands • error handling techniques • expressions • evaluator functions -- general • JINFO, JOBCNT and PINFO functions • CI variables • alternate entry points in scripts and UDCs • I/O redirection techniques • lots of examples • appendix July 22, 2008 Page 2
hp e3000 redo • delete a word • dw, >dw, dwddw, dwiXYZ strategy • delete up to a special character • d., d/, d*, d/iXYZ, d.
hp e3000 strategy common CI “programming” commands • IF, ELSEIF, ELSE, ENDIF ESCAPE, RETURN branching • WHILE, ENDWHILElooping • ECHO, INPUT terminal, console, file I/O • SETVAR, DELETEVAR SHOWVAR create/modify/delete/display a variable • ERRCLEAR sets CI error variables to 0 • RUN XEQ invoke a program invoke a program or script • PAUSE sleep; job synchronization • OPTION recursion only way to get recursion in UDCs July 22, 2008 Page 4
hp e3000 error handling • use HPAUTOCONT variable judiciously strategy • better -continue command if hpcierr <> 0 then ... • if error-condition then echo something… return -- or -- escape endif … • RETURN vs.
hp e3000 strategy CI expressions • what is an expression? • any variable, constant or function with or without an operator, e.
hp e3000 strategy CI functions • functions are invoked by their name, accept zero or more parms and return a value in place of their name and arguments • file oriented functions: • BASENAME, DIRNAME, FINFO, FSYNTAX, FQUALIFY • string parsing functions: • ALPHA, ALPHANUM, DELIMPOS, DWNS, EDIT, LEN, LFT, LTRIM, NUMERIC, PMATCH, POS, REPL, RHT, RPT, RTRIM, STR, UPS, WORD, WORDCNT, XWORD • conversion functions: • CHR, DECIMAL, HEX, OCTAL, ORD • arithmetic functions • ABS, MAX, MIN, MOD, ODD • job/process f
hp e3000 JINFO function syntax: JINFO (“[#]S|Jnnnn”, “item” [,status] ) strategy where jobID can be “[#]J|Snnn” or “0”, meaning “me” • 63 unique items: Exists, CPUSec, IPAddr, JobQ, Command, JobUserAcctGroup, JobState, StreamedBy, Waiting ... • status parm is a variable name. If passed, CI sets status to JINFO error return -- normal CI error handling bypassed • can see non-sensitive data for any job on system • can see sensitive data on: “you”; on other jobs w/ same user.
hp e3000 strategy JOBCNT function syntax: JOBCNT (“job_spec” [,joblist_var] ) • “Job_Spec” can be: • “user.account” • “jobname,user.account” • “@J”, “@S”, “@” • “@J:[jobname,]user.acct” or “@S:[jobname,]user.
hp e3000 PINFO function syntax: PINFO (pin, “item” [,status] ) strategy where PIN can be a string, “[#P]nnn[.tin]”, or a simple integer, “0” is “me” • 66 unique items: Alive, IPAddr, Parent, Child, Children, Proctype, WorkGroup, SecondaryThreads, NumOpenFiles, ProgramName, etc. • status parm is a variable name.
hp e3000 variable scoping • all CI variables are job/session global, except the following: strategy HPAUTOCONT, HPCMDTRACE, HPERRDUMP, HPERRSTOLIST, HPMSGFENCE • easy to set “persistent” variables via logon UDC • need care in name of UDC and script “local” variables to not collide with existing job/session variables • _scriptName_varname -- for all script variable names.
hp e3000 strategy variable referencing • two ways to reference a variable: • explicit -- !varName • implicit -- varName • some CI commands expect variables as their arguments, e.g. • :CALC, :IF, :ELSEIF, :SETVAR, :WHILE • use implicit referencing here, e.g. :if (HPUSER = “MANAGER”) then • most CI commands don’t expect variable names (e.g. BUILD, ECHO, LISTF) • use explicit referencing here, e.g. :echo You are logged on as: !HPUSER.
hp e3000 explicit referencing !varname strategy • processed by the CI early, before command name is known • can cause hard-to-detect bugs in scripts - array example • loose variable type -- strings need to be quoted, e.g.. “!varName” • !! (two exclamation marks) used to “escape” the meaning of “!”, multiple “!’s” are folded 2 into 1 • even number of “!” --> don’t reference variable’s value • odd number of “!” --> reference the variable’s value • useful to convert an ASCII number to an integer, e.g.
hp e3000 implicit referencing just varname strategy • evaluated during the execution of the command -- later than explicit referencing • makes for more readable scripts • variable type is preserved -- no need for quotes, like: “!varname” • only 5 commands accept implicit referencing: CALC, ELSEIF, IF, SETVAR, WHILE -- all others require explicit referencing • all CI function parameters accept implicit referencing • variables inside ![expression] may be implicitly referenced • performance differences: • “
hp e3000 strategy entry points • simple convention for executing same UDC/script starting in different “sections” (or subroutines) • a UDC/script invokes itself recursively passing in the name of an entry (subroutine) to execute • the script detects that it should execute an alternate entry and skips all the code not relevant to that entry.
hp e3000 strategy entry points (cont) • two approaches for alternate entries: • define a parm to be the entry point name, defaulting to the main part of the code (“main”) • the UDC/script invokes itself recursively in the main code, and may use I/O redirection here too • each entry point returns when done (via :RETURN command) --------------------------- or --------------------------------• test HPSTDIN or HPINTERACTIVE variable to detect if script/UDC has I/O redirected.
hp e3000 strategy entry points (cont) • generic approach: PARM p1 … entry=main if “!entry” = “main” then … initialize etc… xeq !HPFILE !p1, … entry=go … cleanup etc… return elseif “!entry” = “go” then... # execute the GO subroutine ... return elseif “!entry” = … ...
hp e3000 strategy entry points (cont) • i/o redirection specific approach: PARM p1 … # no “entry” parm defined if HPSTDIN = “$STDIN” then … (“main” entry -- initialize etc…) xeq !HPFILE !p1, …
hp e3000 strategy file i/o • three main alternatives: • write to (create) and read from a MSG file via I/O redirection • use :PRINT and I/O redirection to read file 1 record at a time • use entry points and I/O redirection • why not use INPUT in WHILE to read a flat file, e.g.
hp e3000 strategy file i/o - MSG file • PARM fileset=./@ # This script reads a file produced by LISTFILE,6 and measures CPU millisecs # using a MSG file setvar savecpu hpcpumsecs :readmsg errclear 259 msecs to read 22 records file msg=/tmp/LISTFILE.msg; MSG continue :readmsg @.pub.
hp e3000 strategy file i/o - :print • PARM fileset=./@ # This script reads a file produced by LISTFILE,6 and measures CPU msecs # using PRINT as an intermediate step setvar savecpu hpcpumsecs errclear :readprnt continue 735 msecs to read 22 records listfile !fileset,6 > lftemp 3 times slower than MSG files if hpcierr = 0 then # read listfile names into a variable :readprnt @.pub.
hp e3000 strategy file i/o - entry points • PARM fileset=./@, entry="main” # This script reads a file produced by LISTFILE,6 and measures CPU msecs # using entry points and script redirection if "!entry" = "main" then setvar savecpu hpcpumsecs errclear continue listfile !fileset,6 > lftemp if hpcierr = 0 then xeq !hpfile !fileset entry=read
hp e3000 file i/o - entry points (cont) strategy else # read listfile names into a variable setvar cntr setvar(eof, finfo(hpstdin, "eof")) while setvar(cntr,cntr-1) >= 0 and setvar(rec, input()) <> chr(1) do endwhile return endif :readntry 90 msecs to read 24 records. ---> Almost 3 times faster than MSG files ---> 8 times faster than the PRINT method! :readntry @.pub.sys 2400 msecs to read 1,515 records.
hp e3000 examples • a few simple examples strategy • what version of MPE will run this script? • easy way to print $STDLIST spoolfile for a job • flexible way to change directories (CWD) • job synchronization example • INFO= string examples • create a “random” name or value • tying many concepts together with the WHERE script • STREAM UDC - abbreviated July 22, 2008 Page 24
hp e3000 simple examples • turn on/off UDC and script command tracing: strategy • setvar HPCMDTRACE not(hpcmdtrace) # toggle • display last N records of a file (no process creation) • PARM file, last=12 print !file; start= -!last “Tail” script • display CI error text for a CI error number • PARM cierr= !cierror setvar save_err cierror setvar cierror !cierr showvar HPCIERRMSG setvar cierror save_err deletevar save_err “Cierr” script July 22, 2008 Page 25
hp e3000 more examples • alter priority of job just streamed: strategy PARM job=!HPLASTJOB; pri=CS altproc job=!job; pri=!pri “Altp” script • Aligned fields for output: PARM cnt=5 “Align” script setvar i 0 while setvar(i,i+1) <= !cnt do setvar a rpt('a',i) setvar b rpt('b',!cnt-i+1) echo xx ![rpt(' ',!cnt-len(a))]!a xx ![rpt(' ',!cnt-len(b))]!b xx endwhile • Example: :align 4 xx a xx bbbb xx xx aa xx bbb xx xx aaa xx bb xx xx aaaa xx b xx July 22, 2008 Page 26
hp e3000 strategy MPE version • PARM vers_parm=!hprelversion “Vers” script # react to MPE version string setvar vers "!vers_parm” # convert to integer, e.g.. "C.65.02" => 6502 setvar vers str(vers,3,2) + rht(vers,2) setvar vers !vers if vers >= 7000 then echo On 7.0! elseif vers >= 6500 then echo On 6.5! elseif vers >= 6000 then echo On 6.
hp e3000 printing spoolfiles • PRINTSP script: strategy PARM job=!HPLASTJOB # Prints spoolfile for a job, default is the last job you streamed if “!job” = “” then echo No job to print return endif setvar hplastjob “!job” if HPLASTSPID = “” then echo No $STDLIST spoolfile to print return endif print !HPLASTSPID.out.hpspool • :stream scopejob #J324 :printsp :JOB SCOPEJOB,MANAGER.SYS,SCOPE. Priority = DS; Inpri = 8; Time = UNLIMITED seconds . . .
hp e3000 new location (group, CWD) • CD script strategy PARM dir=“” setvar d “!dir” # “-” means go to prior CWD if d = ‘-’ and bound(save_chdir) then setvar d save_chdir elseif fsyntax(d) = “MPE” then if finfo(“./”+d, “exists”) then setvar d “./” + d elseif finfo(“../”+ups(d), “exists”) then setvar d “..
hp e3000 strategy synchronize jobs !JOB job0… !limit +2 !stream job1 !pause job=!hplastjob !stream job2 !errclear !pause 600, !hplastjob !if hpcierr = -9032 then ! tellop Job ”!hplastjob” has exceeded the 10 minute limit ! eoj !endif !stream job3 !pause job=!hplastjob; WAIT !input reply, “’Reply ‘Y’ for !hplastjob”; readcnt=1; CONSOLE !if dwns(reply) = “y” then ...
hp e3000 INFO= example • ANYPARM info=![""] run volutil.pub.sys; info=”:!info" strategy # “anyrun” script • :anyrun echo "Hi there!” run volutil.pub.sys;info=”:echo "Hi there!"" ^ Expected semicolon or carriage return. (CIERR 687) • ANYPARM info=![""] setvar _inf repl('!info', '"', '""') run volutil.pub.sys;info=”:!_inf " # double up quotes in :RUN • :anyrun echo "Hi there!” Volume Utility A.02.00, (C) Hewlett-Packard Co., 1987. All Rights...
hp e3000 strategy INFO= example (cont) • ANYPARM info=![""] setvar _inf anyparm(!info) setvar _inf repl(_inf, '"', '""') run volutil.pub.sys;info=”:_!inf ” # note info parm is not quoted • :anyrun echo "Hi there, ‘buddy’!” Volume Utility A.02.00, (C) Hewlett-Packard Co., 1987. All Rights...
random names hp e3000 • strategy PARM varname, minlen=4, maxlen=8 # This script returns in the variable specified as "varname" a `random’ # name consisting of letters and numbers - cannot start with a number. # At least "minlen" characters long and not more than "maxlen" chars.
hp e3000 strategy where is that “cmd”? PARM cmd=“”, entry=main # This script finds all occurrences of "cmd" as a UDC, script or program in # HPPATH. Wildcards are supported for UDC, program and command file names. # Note: a cmd name like "foo.sh" is treated as a POSIX name, not a qualified # MPE name. if "!entry" = "main" then errclear setvar _wh_cmd "!cmd” if delimpos(_wh_cmd,”/.") = 1 then echo WHERE requires the POSIX cmd to be unqualified.
hp e3000 strategy where (cont) ... # check for UDCs first if _wh_udc_ok then continue showcatalog >whereudc if cierror = 0 then xeq !hpfile !_wh_cmd entry=process_udcs 0 . . . continued . . .
hp e3000 strategy where (cont) ... # loop through hppath setvar _wh_i 0 while setvar(_wh_tok,word(hppath,”,; “,setvar(_wh_i,_wh_i+1)))<>”” do if delimpos(_wh_tok,”/.”) = 1 then # we have a POSIX path element setvar _wh_tok "!_wh_tok/!_wh_cmd” elseif _wh_mpe_ok then # we have an MPE syntax HPPATH element with an unqualified _tok setvar _wh_tok "!_wh_cmd.
hp e3000 strategy where (cont) … elseif "!entry" = "process_udcs" then # input redirected from the output of showcatalog setvar _wh_udcf rtrim(input()) setvar _wh_eof finfo(hpstdin,”eof”) -1 while setvar(_wh_eof,_wh_eof-1) >= 0 do if lft(setvar(_wh_rec,rtrim(input())),1) = " " then # a UDC command name line if pmatch(ups(_wh_cmd),setvar(_wh_tok,word(_wh_rec))) then # display: UDC_command_name UDC_level UDC_filename echo !_wh_tok ![rpt(" ",26-len(_wh_tok))] & ![setvar(_wh_tok2,word(_wh_rec,,-1))+rpt(" ",7-
hp e3000 strategy where (cont) … elseif "!entry" = "process_listf" then # input redirected from the output of listfile,6 or a simple filename setvar _wh_eof finfo(hpstdin,'eof') while setvar(_wh_eof,_wh_eof-1) >= 0 do setvar _wh_fc "” if setvar(_wh_fc, finfo(setvar(_wh_tok,ltrim(rtrim(input()))),'fmtfcode')) = ”” setvar _wh_fc 'script’ elseif _wh_fc <> 'NMPRG' and _wh_fc <> 'PROG' then setvar _wh_fc "” endif if _wh_fc <> "" and finfo(_wh_tok,'eof') > 0 then setvar _wh_lnk “” if _wh_fc = “script” and finfo
hp e3000 where (cont) … strategy # display: qualified_filename file_code or "script" and link if any echo !_wh_tok ![rpt(" ",max(0,26-len(_wh_tok)))] !_wh_fc & ![rpt(" ",7-len(_wh_fc))] !_wh_lnk endif endwhile return endif • :where @sh@ SHOWME USER SH SH.PUB.VANCE SHOWVOL.PUB.VANCE BASHELP.PUB.SYS HSHELL.PUB.SYS PUSH.SCRIPTS.SYS RSH.HPBIN.SYS SH.HPBIN.SYS /bin/csh /bin/ksh /bin/remsh /bin/rsh /bin/sh UDC in SYS52801.UDC.SYS SYSTEM UDC in HPPXUDC.PUB.
hp e3000 strategy stream UDC - overview • STREAM ANYPARM streamparms = ![“”] OPTION nohelp, recursion ... if main entry point then # initialize … - if “jobq=“ not specified then read job file for job “card” - if still no “jobq=“ then read config file matching “[jobname,]user.acct” - stream job in HPSYSJQ (default) or derived job queue - clean up else # alternate entries separate entry name from remaining arguments ...
hp e3000 strategy stream UDC - “main” # comments … if "!streamparms" = "" or pos("entry=","!streamparms") = 0 then # main entry point of UDC setvar _str_jobfile word("!streamparms") # extract 1st arg ...
hp e3000 strategy stream UDC - “main” (cont) if _str_jobq = '' and finfo(_str_config_file,'exists') then # No jobq=name specified so far so use the config file. STREAM ![word(_str_jobcard,";")] _str_jobq entry=read_config & '' then # found a match in config file, append jobq name to stream command line setvar _str_parms _str_parms + ";jobq=!_str_jobq" endif endif ... # now finally stream the job.
hp e3000 strategy stream UDC - “read_jobcard” else # alternate entry points for UDC. setvar _str_entry word("!streamparms",,-1) # remove entry=name from parm line setvar _str_entry_parms lft('!streamparms',pos('entry=','!streamparms')-1) if _str_entry = "read_jobcard" then # Arg 1 is the *name* of the var to hold all of the JOB card right of "JOB". # Input redirected to the target job file being streamed # Read file until JOB card is found.
hp e3000 strategy stream UDC - “read_jobcard” (cont) … # concatenate continuation (&) lines while rht(setvar(!_str_arg1,rtrim(!_str_arg1)),1) = '&' do # remove & and read next input record setvar !_str_arg1 lft(!_str_arg1,len(!_str_arg1)-1)+ltrim(rht(input(), -2)) if _str_numbered then setvar !_str_arg1 lft(!_str_arg1,len(!_str_arg1)-8 endif endwhile # remove passwords, if any while setvar(_str_pos,pos('/',!_str_arg1)) > 0 do setvar !_str_arg1 repl(!_str_arg1,"/"+word(!_str_arg1,'.
hp e3000 strategy stream UDC - “read_config” elseif _str_entry = "read_config" then # Arg 1 is the "[jobname,]user.acct" name from the job card. # Arg 2 is the *name* of the var to return the jobQ name if the acct name # Input redirected to the jobQ config file. setvar _str_arg1 word(_str_entry_parms," ") setvar _str_arg2 word(_str_entry_parms," ",2) setvar _str_eof finfo (hpstdin, “eof”) … # read config file and find [jobname,]user.
hp e3000 strategy appendix • COMMAND vs.
hp e3000 strategy COMMAND intrinsic • COMMAND is a programmatic system call (intrinsic) syntax: COMMAND (cmdimage, error, parm) • implemented in native mode (NM, PA-RISC mode) • use COMMAND for system level services, like: • building, altering, copying purging a file • no UDC search (a UDC cannot intercept “cmdimage”) • no command file or implied program file search • returns command error number and error location (for positive parmnum), or file system error number for negative parmnum July 22, 2008 Pa
hp e3000 strategy HPCICOMMAND intrinsic • HPCICOMMAND is an intrinsic syntax: HPCICOMMAND (cmdimage,error,parm [,msglevel]) • implemented in native mode (NM, PA-RISC mode) • use HPCICOMMAND for a “window” to the CI, e.g.: • providing a command interface to a program, “:cmdname” • UDCs searched first • command file and implied program files searched • returns command error number and error location or file system error number.
hp e3000 strategy CI i/o redirection • > name - redirect output from $STDLIST to “name” • “name” will be overwritten if it already exists • file will be saved as “name”;rec=-256,,v,ascii;disc=10000;TEMP • file name can be MPE or POSIX syntax • >> name - redirect, append output from $STDLIST to “name” • same file attributes for “name” if it is created • < name - redirect input from $STDIN to “name” • “name” must exist (TEMP files looked for before PERM files) • I/O redirection has no meaning if the command
hp e3000 strategy CI i/o redirection (cont) • how it works: • CI ensures the command is not one of the excluded commands • CI scans the command line looking for <, >, >> followed by a possible filename (after explicit variable resolution has already occurred) – – text inside quotes is excluded from this scan text inside square brackets is excluded from the scan • filename is opened and “exchanged” for the $STDIN or $STDLIST • after the command completes the redirection is undone • examples: • • • • • •
hp e3000 strategy CI expressions • operators: • + (ints and strings), -, *, /, ^, (), <, <=, >, >=, =, AND, BAND, BNOT, BOR, BXOR, CSL, CSR, LSL, LSR, MOD, NOT, OR, XOR • precedence (high to low): • 1) variable dereferencing • 2) unary + or • 3) bit operators (csr, lsl…) • 4) exponentiation ( ^ ) • 5) *, /, mod • 6) +, • 7) <, <=, =, >, >= • 8) logical operators (not, or…) • left to right evaluation, except exponentiation is r-to-l July 22, 2008 Page 51
hp e3000 CI variables • 113 predefined “HP” variables strategy • user can create their own variables via :SETVAR • variable types are: integer (signed 32 bits), Boolean and string (up 1024 characters) • variable names can be up 255 alphanumeric alphanumeric and “_” (cannot start with number) • predefined variable cannot be deleted, some allow write access • :SHOWVAR @ ; HP -- shows all predefined variables • can see user defined variables for another job/session (need SM) • :SHOWVAR @ ; job=#S or Jnnn
hp e3000 strategy compound variables • • • • • • :setvar a “!!b” :setvar b “123” :showvar a, b :echo b is !b, a is !a :setvar a123 “xyz” :echo Compound var "a!!b": !"a!b” # B is not referenced, 2!’s fold to 1 A=!b B=123 b is 123, a is 123 Compound var "a!b": xyz • :setvar J 2 :setvar VAL2 “bar” :setvar VAL3 “foo” • • • • :calc VAL!J :calc VAL![J] :calc VAL![decimal(J)] :calc VAL![setvar(J,J+1)] bar bar bar foo July 22, 2008 Page 53
hp e3000 variables arrays • simple convention using standard CI variables strategy • varname0 varname1…varnameN varname!J !”varname!J” = = = = number of elements in the array array elements, 1 ..
hp e3000 variable array example • centering output: PARM count=5 “Center” setvar cnt 0 while setvar(cnt,cnt+1) <= !count do setvar string!cnt,input("Enter string !cnt: ") endwhile setvar cnt 0 while setvar(cnt,cnt+1) <= !count do echo ![rpt(" ",39-len(string!cnt))]!"string!cnt” endwhile strategy script :center Enter Enter Enter Enter Enter string string string string string 1: 2: 3: 4: 5: The great thing about Open Source software is that you can have any color "screen of death” that you want.
hp e3000 filling variables arrays -- wrong! • example 1: strategy # array name is “rec” setvar j 0 setvar looping true while looping do input name, “Enter name “ if name = “” then setvar looping false else setvar j j+1 setvar rec!j name endif endwhile setvar rec0 j • :exmpl1 • infinite loop!, won’t end until July 22, 2008 Page 56
hp e3000 filling variables arrays (cont) • example 2: strategy setvar j 0 setvar looping true while looping do setvar NAME “” input name, “Enter name “ if name = “” then setvar looping false else setvar j j+1 setvar rec!j name endif endwhile setvar rec0 j • :exmpl2
hp e3000 filling variables arrays (cont) • example 3; strategy setvar j 0 if HPINTERACTIVE then setvar prompt “’Name = ‘” setvar limit 2^30 setvar test ‘name= “” ‘ else setvar prompt “” setvar limit FINFO (HPSTDIN, ”eof”) setvar test “false” endif while (j < limit) do setvar name “” input name , !prompt if !test then setvar limit 0 # exit interactive input else setvar j j+1 setvar rec!j name endif endwhile setvar rec0 j July 22, 2008 Page 58
hp e3000 filling variables arrays (cont) • :exmpl3
hp e3000 strategy filling variables arrays (cont) • can we fill arrays (and read files) faster? • example 4: setvar rec0 0 setvar limit FINFO (HPSTDIN, ”eof”) while setvar(rec0, rec0+1) <= limit and & setvar(rec![rec0+1], input()) <> chr(1) do endwhile setvar rec0 rec0-1 • performance (:exmpl4
hp e3000 predefined variables • HPAUTOCONT - set TRUE causes CI to behave as if each command is protected by a :continue. strategy • HPCMDTRACE - set TRUE causes UDC / scripts to echo each command line as long as OPTION NOHELP not specified. Useful for debugging. • HPCPUMSECS - tracks the number of milliseconds of CPU time used by the process. useful for measuring script performance. • HPCWD - current working directory in POSIX syntax.
hp e3000 strategy predefined variables (cont) • HPLASTSPID - the $STDLIST spoolfile ID of the last job streamed, useful in :print !hplastspid.out.hpspool • HPLOCIPADDR - IP address for your system. • HPMAXPIN - the maximum number of processes supported on your system. • HPPATH - list of group[.acct] or directory names used to search for script and program files • HPPIN - the Process Identification Number (PIN) for the current process.
hp e3000 UDCs • user defined command files (UDCs) - a single file that contains 1 or more strategy command definitions, separated by a row of asterisks (***) • features: • simple way to execute several commands via one command • allow built-in MPE commands to be overridden • can be invoked each time the user logs on • require lock and (read or eXecute) access to the file • cataloged (defined to the system) for easy viewing and prevention of accidental deletion -- see :SETCATALOG and :SHOWCATALOG command
hp e3000 command files (scripts) • command file - a file that contains a single command definition strategy • features: • same convenience as UDCs • searched for after UDCs and built-in commands using the HPPATH variable -default HPPATH includes “logon group, PUB.logon account, PUB.SYS, ARPA.
hp e3000 UDC / script comparisons • similarities: strategy • ASCII, NOCCTL, numbered or unnumbered, max 511 record width • optional parameter line ok - max of 255 arguments • optional options, e.g. HELP, NOBREAK, RECURSION • optional body (actual commands) – no inline data, unlike Unix ‘here’ files :( • can protect file contents by allowing eXecute access-only security, i.e.
hp e3000 UDC / script comparisons (cont) • differences: strategy • scripts can be variable record width files • UDCs require lock access, scripts don’t • script names can be in POSIX syntax, UDC filenames must be in MPE syntax • UDC name cannot exceed 16 chars, script name length follows rules for MPE and POSIX named files • EOF for a script is the real eof, end of a UDC command is one or more asterisks, starting in column 1 July 22, 2008 Page 66
hp e3000 UDC file layout filename: AUDC.PUB.
hp e3000 script file layout filename: PRNT.SCRIPTS.SYS strategy header: body: eof header: body: [ PARM parm1, parm2 [= value ] ] [ ANYPARM parm3 [ = value ] ] [ OPTION option_list ] any MPE command, UDC or script (:option list or :option recursion supported in body too) filename: LG.SCRIPTS.SYS PARM … OPTION nohelp ... any MPE command etc...
hp e3000 UDC search order File: UDCUSER.udc.finance strategy 1. Invoke UDCC, which calls UDCA with the argument “ghi” 2. UDCA is found, starting after the UDCC definition (option NOrecursion default) 3. The line “p1=ghi” is echoed 4. Invoke UDCB, which calls UDCA passing the arg “def”. The recursion option causes the first UDCA to be found. This calls UDCC and follows the path at step 1 above 5.
hp e3000 strategy script search order • scripts and programs searched for after command is known to not be a UDC and to not be a built-in command • same order for scripts and for program files • fully or partially qualified names are executed without qualification • unqualified names are combined with HPPATH elements to form qualified filenames: • first match is executed • filecode = 1029, 1030 for program files • EOF > 0 and filecode in 0..
hp e3000 UDCs vs. scripts • option logon strategy • UDCs only (a script can be executed from an “option logon” UDC) • logon UDCs executed in this order: – 1. System level 2. Account level 3. User level (opposite of the non-logon execution order!) • CI command search order: • A. UDCs ( 1. User level 2. Account level 3. System level) – thus UDCs can override built-in commands • B. built-in MPE commands, e.g. LISTFILE • C. script and program files.
hp e3000 UDCs vs. scripts (cont.) • performance strategy • logon time: 9 UDC files, 379 UDCs, 6050 lines: 1/2 sec.
hp e3000 UDCs vs. scripts (cont.) • maintenance / flexibility / security strategy • SETCATALOG opens UDC file, cannot edit without un-cataloging file, but difficult to accidentally purge UDC file • UDC commands grouped together in same file, easier to view and organize • UDC file can be lockword protected but users don’t need to know lockword to execute a UDC • scripts opened while being executed (no cataloging), can be purged and edited more easily than UDCs • scripts can live anywhere on system.
hp e3000 strategy UDC / script exit • EOF -- real EOF for scripts, a row of asterisks (starting in column 1) for UDCs • :BYE, :EOJ, :EXIT -- terminate the CI too, to use BYE or EOJ must be the root CI • :RETURN -- useful for entry point exit, error handling, help text - jumps back one call level • :ESCAPE -- useful to jump all the back to the CI, or an active :CONTINUE. In a job without a :CONTINUE, :escape terminates the job. Sessions are not terminated by :escape.
hp e3000 parameters • syntax: ParmName [ = value ] strategy • supplying a value means the parameter is optional. If no value is defined the parameter is considered required.
hp e3000 strategy parameters (cont) • all parameters are passed “by value”, meaning the parm value cannot be changed within the UDC/script • a parm value can be the name of a CI variable, thus it is possible for a UDC/script to accept a variable name, via a parm, and modify that variable’s value, e.g.
hp e3000 strategy ANYPARM parameter • • • • all delimiters ignored must be last parameter defined in UDC/script only one ANYPARM allowed only way to capture user entered delimiters, without requiring user to quote everything • example: TELLT user ANYPARM msg = “” # prepends timestamp and highlights msg text tell !user; at !hptimef: ![chr(27)]&dB !msg :TELLT op.sys Hi, what’s up,,,, system seems fast! FROM S68 JEFF.
hp e3000 brief acct, group, user, dir listings • LG, LU, LA and LD scripts: strategy • PARM group=@ listgroup !group; format=brief “LG” • PARM user=@ “LU” listuser !user; format=brief • PARM acct=@ “LA” listacct !acct; format=brief • PARM dir=./@ “LD” setvar _dir “!dir” if delimpos(_dir, “.
hp e3000 strategy CI grep • PARM pattern, file, entry=main # This script implements unix $grep -in . setvar savecpu hpcpumsecs if '!entry' = 'main' then errclear setvar _grep_matches 0 if not finfo('!file','exists') then echo File "!file" not found. return endif continue xeq !HPFILE !pattern !file entry=read_match
hp e3000 strategy CI grep (cont) elseif '!entry' = 'read_match' then # finds each "pattern" in "file" and echoes the record + line num # input redirected to "!file” setvar _grep_eof finfo("!file","eof") setvar _grep_recno 0 setvar _grep_pat ups("!pattern") while setvar(_grep_recno,_grep_recno+1) <= _grep_eof and & setvar(_grep_rec, rtrim(input())) <> chr(1) do if pos(_grep_pat,ups(_grep_rec)) > 0 then echo !_grep_recno) !_grep_rec setvar _grep_matches _grep_matches+1 endif endwhile return endif • 4667 166