Mainframe Playground

Executing REXX scripts

Introduction

REXX (REstructured eXtended eXecutor) is a popular and powerful programming language. It's widely used in z/OS environments in various administrative tasks such as data gathering or automation of commonly performed activities. In this assignments you'll learn how to work with REXX scripts.

Tasks

1. Write down "Hello World" program in REXX. 2. Execute the program in following ways: - Using TSO EXEC command without /* REXX */ line at the beginning of the script. - Using TSO EXEC command with /* REXX */ line at the beginning of the script. - From member view in 3.4 panel. 3. Write a job that executes REXX script with use of IKJEFT1B: - First execute it specifying full TSO EXEC command as in Task#2. - Then modify the job so data set is allocated to SYSEXEC DD statement and execute the script using the member name only. 4. Execute the script using only member name: - Display SYSEXEC and SYSPROC DD statements allocated by your user session. - Check what's allocating those data sets. - Copy your "Hello World" script to some library in SYSEXEC concatenation. - Execute it using 'TSO %rexxname' command - What's the difference between 'TSO %rexxname' and 'TSO rexxname' execution? - Execute it from batch job. Can you now execute it without coding SYSEXEC DD statement? - Remove the script from the library in SYSEXEC concatenation. 5. Compile your REXX to CEXEC format.

Hint 1-3

Check "EXEC" command description in "TSO/E Command Reference". Two main documents describing REXX language are called "TSO/E REXX Reference" and "TSO/E REXX User’s Guide". You may want to check "Chapter 2. Writing and Running a REXX Exec" of the latter document.

Hint 4

You can read more about SYSEXEC and SYSPROC concatenation in "Using SYSPROC and SYSEXEC for REXX execs" chapter of "TSO/E REXX Reference".

Hint 5

REXX compiler and the process of compiling REXX programs is described in document "IBM Compiler and Library for REXX on System z: User’s Guide and Reference". Check ALT, SL and CEXEC compilation options. On your system you'll have to find: - Compiler procedure: REXXC or FANCMC - Compiler: REXXCOMP

Solution 1

REXX code:

SAY 'HELLO WORLD!'

Not much to it. SAY keyword writes a line to output stream. When you execute job as a TSO user the string is sent to your TSO terminal session.

Solution 2

To execute script you need EXEC TSO command: - “TSO EXEC 'JSADEK.MP.REXX(HIWORLD)' EXEC” Notice two 'EXEC' keywords. TSO EXEC command by default assumes that you are executing CLIST. You need to manually point out that you want to execute script as REXX, not CLIST. You can do that in two ways: - Use “TSO EXEC rexx EXEC” command. - Have REXX word as a comment in first line of the script – this is the recommended way so always ensure you have '/* REXX */' comment in first line of your script. For example:

/* MY REXX SCRIPT */ SAY 'HELLO WORLD!'

You can also put other comments in first line. Interpreter searches for 'REXX' word in it. Now you can execute script with command: - ”TSO EXEC 'JSADEK.MP.REXX(HIWORLD)'” The easiest way to execute the script is to put 'EX' command left to the member name in 3.4 panel.

Solution 3

JCL Code:

//REXXEXEC EXEC PGM=IKJEFT1B,REGION=6M //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * EX 'JSADEK.MP.REXX(HIWORLD)'

Now you've executed REXX script in job's address space so it has 6M of memory available as defined in REGION parameter. When you execute REXX with TSO command it runs in address space of your TSO user session and uses resources of user's address space. Also, output is not routed to your terminal session but to output stream defined by IKJEFT1B so SYSTSPRT. Enter job with '?' to see how it looks like in SDSF. You don't always have to specify full data set name. You can also execute script using only member name. In this case you need to allocate library with the script to SYSEXEC DD statement:

//REXXEXEC EXEC PGM=IKJEFT01,REGION=6M //SYSEXEC DD DSN=JSADEK.MP.REXX,DISP=SHR //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * %HIWORLD

Solution 4

If you have REXX or CLIST scripts that are often used by many users in your environment can be stored in common libraries. Your TSO logon procedure should have two DD statements: - SYSEXEC – used for only REXX scripts. - SYSPROC – used for both CLIST and REXX scripts. You can display them with “TSO ISRDDN” command. You can use “D GRS,RES=(*,SYS1.USER.REXX)” or “ISRDDN E” command in 3.4 to see what's allocating those libraries.

Command - Enter "/" to select action ------------------------------------ isrddn e SYS1.USER.REXX

After adding REXX to SYSEXEC (or SYSPROC) you can execute it with a simple command “TSO HIWORLD”. You can also use “TSO %HIWORLD” as described in "TSO/E Command Reference" '%' character defines that you execute CLIST or REXX. If you don't use it TSO first searches for TSO command, only when no HIWORLD command is found in TSO command library SYSEXEC and SYSPROC concatenations are checked. Because of that it's best to always use % character when executing script, you'll speed up search order this way. Let's now rerun our job:

//REXXEXEC EXEC PGM=IKJEFT01,REGION=6M //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * %HIWORLD

It will end in error. After all SYSEXEC concatenation is used by TSO users. It's not visible to jobs. So you still have to have SYSEXEC DD statement in your jobs. Note: If you want to temporarily add your script library to SYSEXEC concatenation you should NOT use “TSO ALLOC DSNAME('JSADEK.MP.REXX') DDNAME(SYSEXEC) SHR REUSE” – this will replace the entire SYSEXEC concatenation. In effect you wont be able to use scripts stored in there. Such scripts are sometimes used by ISPF panels so you may not be able to access some ISPF tool. If you want to use this method you should remember to also allocate data sets that are currently allocated to SYSEXEC, for example: “TSO ALLOC DSNAME('SYS1.USER.REXX' 'SYSU.TOOLS.REXX' 'JSADEK.MP.REXX') DDNAME(SYSEXEC) SHR REUSE”. Such setting will be only retained by the time of your user session. For permanent changes you could customize your logon procedure. There is also “TSO ALTLIB” command: “TSO ALTLIB ACTIVATE APPLICATION(EXEC) DA('JSADEK.MP.REXX')” This enables you to temporarily add your data set to REXX and CLIST search order. Use “TSO ALTLIB DISPLAY” command to see current search order:

Current search order (by DDNAME) is: System-level EXEC DDNAME=SYSEXEC System-level CLIST DDNAME=SYSPROC

After issuing the above command:

Current search order (by DDNAME) is: Application-level EXEC DDNAME=SYS00017 System-level EXEC DDNAME=SYSEXEC System-level CLIST DDNAME=SYSPROC

Where SY00017 (ISRDDN panel):

VOL039 SHR,KEEP > SYS00017 JSADEK.MP.REXX

The unfortunate thing is that “ALTLIB ACTIVATE” command works only for one ISPF panel. If you have three panels opened you'll be able to use libraries allocated this way only from the panel from which you've issued ALTLIB command.

Solution 5

JCL Code:

//COMPILE EXEC REXXC,PARM.REXX='ALT SL CEXEC CONDENSE' //REXX.STEPLIB DD DISP=SHR,DSN=SYS1.REXX.LINKLIB //REXX.SYSIN DD DISP=SHR,DSN=JSADEK.MP.REXX(HIWORLD) //REXX.SYSCEXEC DD DISP=SHR,DSN=JSADEK.MP.CREXX(CHIWORLD) //REXX.SYSPUNCH DD DUMMY

The job itself is very simple. First you need to find procedure for compilation it's called REXXC or FANCMC and it should be somewhere in your PROCLIB concatenation. You also need to find REXXCOMP load module. It may be already in the LINKLIST concatenation, if not you have to find it somehow and specify in STEPLIB DD statement. To create executable REXX you need to use either IEXEC or CEXEC option. In our REXX script no INCLUDE clause is used so we can use CEXEC. When you use those options your program will be saved under SYSCEXEC or SYSIEXEC DD statements respectively. ALT keyword specifies that the compiled REXX can be executed under Alternate Library. Alternate Library for REXX is a software shipped with z/OS that enables users to run compiled REXX programs without standard payed REXX software. SL keyword is required when using Alternate Library. CONDENSE keyword is not required but it's worth using. Without this keyword the source code of your REXX can be read in CEXEC member. It also makes the member smaller.