I didn’t know that z/OS command

On one of the z/OS fora I found the following good stuff from David Mingee. Three of these were new to me.

  1. After using START command to start more than one screen, you can enter =XALL to close all screens.
  2. In ISPF enter CMD SWAPBAR ON.  This will cause a screen name to be displayed at the bottom left of your screen.  There will be a screen name for each START CMD that has been done.  The active screen will have an * e.g. *dslist .  You can go directly to any screen listed by clicking your mouse on the desired screen name.  This feature stays turned on for your next logon and until you enter SWAPBAR OFF. You can change the name of the screen using the command such as SCRNAME SDSF. By default you get names like
    1. ISR@PRIM for the main ISPF panel
    1. ISFPCU4 for SDSF
    2. DSLIST for ISPF 3;4
    3. ISRTSO for ISPF option 6 for TSO
    4. OS390S for z/OS System Programmer Primary Option Menu
  3. When editing a file do CC CC A to copy a range of lines AFTER line A, a new feature allows the use of CC CC AK  on as many lines as wanted and then A on the last location for the copy.  Lines are copied to multiple locations with one command. So do cc, cc, ak,ak,a
  4. In ISPF use command 0 for settings then go to page 2 and change 3278 screen display to 1 for DATA vs. STD. This will automatically allow your screen to display up to 120 columns vs. only 80.
  5. In SDSF change FIND LIMIT to 99999 vs default of 5000 as this will speed up log searches.
  6. Use SRCHFOR command in 3.4 for pds/pdse files to find a ‘STRING’ in all members.
  7. Use KEYS command to change your PF KEY settings, e.g. change F9 to SWAP NEXT vs. SWAP.
  8. Use ISPF APPEND command to create a personal DSLIST of files frequently used with different DSN Qualifiers.
  9. ISPF cut and paste. You can have multiple “clipboards”, and do ASCII or EBCDIC conversion. For example CUT .a .b BOARD2 APPEND UTF8 copies the lines labelled .a to .b to clipboard BOARD2.

What can I use to edit program source in Unix Services on z/OS?

I hit this question trying to edit some Python programs on z/OS in Unix Services.

ISPF services

The easy answer for programs which are in EBCDIC or untagged, is just use ISPF edit, and you can use the HILITE command to highlight the constants and variables in the file. You can use this command to highlite, C, REXX, JCL, XML, assembler etc.

Example output for a C program.

Unfortunately although python supports EBCDIC source files, if you want to compile and package these files, they need to be ASCII files. The Unix Services command OEDIT will detect that the file as an ASCII file, and you can edit it, but not use the HILITE command.

To display the type of the file, use the Unix command ls -Tr *.py . This gave me

t ISO8859-1   T=on  cf.py        
- untagged    T=off aa.py        

Where cf.py is tagged as an ASCII file, an aa.py is an untagged file which defaults to EBCDIC.

Download to your work station

You can download ( FTP) these files to your work station, in binary and edit them. I use gedit on Linux. This has support built in for highlighting source.

IBM developer for z/OS.

This is an eclipse based package which allows you to edit data sets, submit jobs, debug programs etc. It has build in support for C, COBOL etc. When you right click on a file, you can select which editor to use, for example LPEX, a simple editor,a remote C/C++ editor, or an editor on your work station (gedit in my case).

For a python file (*.py), Eclipse downloads the file, and the choice is the eclipse simple text editor, or your workstation standard editor (gedit).

Pydev

Pydev is an Integrate Development Environment for Python on Eclipse (IBM Developer for z/OS). I had a few problems getting it working in Eclipse. (I had to use Pydev 8.2 because of incompatible Java release problem). This provides a Python editor with highlighting, and support for “twisties” where you can hide functions etc. As an editor this worked fine for most of the things I did. There were a couple of surprises.

I could not get the debugger to work, as it tried to debug running the Python program on my laptop – not on z/OS.

Whoops who over wrote my file

With all of the non ISPF techniques there is an integrity problem. If there are two people A and B and they want to edit the file at the same time.
With ISPF and ISPF

  • A edits the file
  • B is prevented from editing the file
  • A saves the updates

If A uses ISPF and B uses IBM developer

  • A edits the file
  • B edits the file
  • A saves the file
  • When B tries to save the file, it detects the last changed time stamp is different, and asks if you wan to overwrite it

If A uses ISPF and B uses IBM developer

  • A edits the file
  • B edits the file
  • B saves the file, and as the last changed time stamp has not changed, the save is successful
  • A saves the file, and overwrites the changes B made.

If you use FTP or similar to download the files, there is no locking, and the last person to save will overwrite any previous updates from other people.

ISPF has autocomplete – just like a laptop!

On Linux I can use “ls D” and tab, and it lists Documents/ and Downloads/ . If I type “ls Doc” and press tab it uses autocomplete to give “ls Documents/”. This is a great way to save you typing.

I’ve just found the same function for z/OS. It has been in the product since at least 2004!

  • Set up a pf key to be AUTOTYPE ( type KEYS on the command line) I set PF6 to this
  • Go to ISPF 3.4 and type the start of a data set, for example COLIN.
  • press PF6, it gives me COLIN.JCL, press PF6 again, it gives me COLIN.MP1B.JCL

Of course you could always type COLIN.* and press enter, then tab down the list. But I thought AUTOTYPE was pretty neat.

Setting PF Keys 13 to 24

When I went to set my PF key, I found all 12 keys were allocated. How do I set keys 13 to 24?
If you use PFSHOW TAILOR it allows you to use 12 or 24 keys, and to control what is displayed.

I have my terminal emulator set up so shift PF5 is PF17, and so I set PF17 to AUTOTYPE.

Easy.

Using point and shoot keys in ISPF

ISPF has had hot keys for many years – I have only just got round to using them.

At the top of ISPF screens there is usually an action bar. For example

   Menu  Utilities  Compilers  Options  Status  Help                       
 ────────────────────────────────────────────────────
                   ISPF Primary Option Menu                           
 Option ===>                                                                   

Where the actions are Menu, Utilities etc. The underlined letter is the hot key for the action.

To select Utilities, type U on the command line and press the “Actions” PF key. This will do the same as tabbing to the Utilities action bar item, and pressing enter. For me PF10 is set to Actions.

You can display your PF Key settings using the keys or pfshow command.

For people who like to use short cuts, have your command line at the top, and use the “home” key. This will get you to the command line. So you can do: home, U, PF10 and quickly get to the Utilities action bar item.

Who develops standard?

When the GUI standards came out I wondered why the standard was to put the command line at the bottom, as there was no “go to command line” key, you had to do “Home”, then shift, tab (to do back tab). This was too many keystrokes for me.

ISPF reflists provide hot lists of datasets and files.

You can set up hot lists of data sets names to make it easier to use data sets and files in Unix Services. For example if your hot list of data sets is SYS1.PROCLIB, ADCD.Z245.PROCLIB, COLIN.PROCLIB, COLIN.C.SOURCE, you can get a list of these in ISPF 3.4 format, so you can quickly move between them, rather than have to keep using ISPF 3.4 and typing in the names of the data sets.

ISPF provides a list called REFLIST with the last 30 datasets or Unix files you referenced, so when you come back from holiday and cannot remember what you were working on, then the REFLIST will show you. Recalling Those Darn Dataset Names is an interesting article.

You can have a hot list of Unix Services files.

You can use the REFLISTD command, or go into ISPF 3.4, up to the action bar, and use the pull down to select REFLIST.
By default, this gives you the a list of the last 30 data sets you used.

Example output

File View Options Help .
────────────────────────────────────────────────────────────────────────────── .
ISRPDSNL Personal Data Set List DSLIST processed .
Command ===> 
Enter a list action to perform or select a data set entry to retrieve. .
Action: S=Save A=Save As D=Delete this list E=Extended Edit L=DSLIST U=UDLIST .
.
Action   Name    Description                  Created Referenced .
L        REFLIST Last 30 referenced data sets         22/04/26 11:45 .

Select Data Set, DSLIST Level or z/OS UNIX file Volume WS 
. 'COLIN.CBT503.FILE967' 
. 'USER.Z24C.CLIST' 
. 'COLIN.SRCHML.LIST' 
. 'COLIN.ZLOGON.CLIST' 
. /u/tmp/zpymqi/code/pymqi/MQMAP.h 
. 'COLIN.CUCI.EXEC' 

The data at the bottom of the display is what is in this list. You cannot do anything with these entries. You can have datasets as well as Unix files in the list

The action only applies to the List entry itself.

If you put an L in front of the REFLIST, you get into standard ISPF 3.4 data set list – with all of the data sets from the list. You can use all of the commands you know and love from this list. You can use option U to list all of the Unix files in the list.

You can also save this list, for example use “A” to create your own list (eg COLIN).

If you want to use this list you can use the command REFACTD COLIN, or go to ISPF 3.4, action bar, REFLIST

1. Current Personal Data Set List (COLIN)
2. List of Personal Data Set Lists

Option 2 gives

ISRPLTAB EFLIST             Personal Data Set Lists                List 1 of 2
Command ===>                                                  Scroll ===> PAGE
                                                                               
Action: O=Open  A=Save As  D=Delete  E=Edit  L=DSLIST  U=UDLIST               
                                                                               
Name      Description                  Created  Referenced
_ COLIN   colin's list                 22/04/26 22/04/26 11:55
_ REFLIST Last 30 referenced data sets          22/04/26 11:57
End

This allows you to pick a list, and specify if you want a data set list, or a Unix file list.

This is really handy – but not very well documented. It feels like it has not been written for the end users but from the IBM developers view point.

Configuring ISPF for new applications.

I found an interesting ISPF extension which I wanted to try out. But I could not find any documentation on how to install it. As usual I found out even more interesting stuff trying to document it.

Logging on to TSO.

When you logon to TSO you specify a procedure such as ISPFPROC. This procedure is in the SYS1.PROCLIB concatenation.  A user can have a default procedure specified in the RACF TSO segment. A user is given access to the RACF CLASS TSOPROC. (So you use a command like RDEFINE TSOPROC NEWPROC UACC(READ) )

This procedure allocates the datasets used by TSO and ISPF, for example ISPPLIB, ISPMLIB, ISPLLIB,ISPEXEC, SYSEXEC, SYSOUT.

If you are authorised you can create your own TSO procedure, and add your application’s data sets to the JCL. Most systems do not allow this.

When this JCL is executed you can pass parameters to it, for example

//ISPFPROC EXEC PGM=IKJEFT01,REGION=0M,DYNAMNBR=200,
//             PARM=’%ISPFCL’                       

will cause the ISPFCL exec or clist to be executed.   This is usually in the SYS1.CLIST concatenation. You can specify PARM=’EXEC ”SYS1.CLIST(SPFALLOC)”’ and specify a data set.

You can use this

  1. To write a message to users
  2. Allocate additional data sets,
  3. Check the existence of a profile, and execute it.

User specific processing

With the clist specified in the PARM statement you can have code like

/* rexx */
address TSO
userid = userid()
zl =”‘”userid”.ZLOGON.CLIST'” /* so we get ‘colin.zlogon.clist’ */
if SYSDSN(zl) = “OK” then exec zlogon /* the userid.. and .clist default’ */

For my userid this would check to see if COLIN.ZLOGON.CLIST exists, and if so, it executes it.

userid.ZLOGON.CLIST

Within this data sets you can have user specific processing, for example

/* Rexx */
say "in colin.zlogon.clist"
address ispexec
"LIBDEF ISPLLIB DATASET ID('COLIN.ISPF.ISPLLIB') STACK"
"LIBDEF ISPMLIB DATASET ID('COLIN.CUCI.ISPMLIB') STACK"
"LIBDEF ISPPLIB DATASET ID('COLIN.CUCI.ISPPLIB') STACK"
"LIBDEF ISPTLIB DATASET ID('COLIN.CUCI.ISPTLIB') STACK"
address tso "ALTLIB ACTIVATE APPLICATION(CLIST)
DATASET('COLIN.CUCI.EXEC') "

This will add the datasets to the specified library, for example adds the panel library COLIN.CUCI.ISPPLIB to ISPPLIB.

You can use “LIBDEF ISPPLIB” to “pop” the definitions back to what they were before the call.

Running your own application

If you have your own panel or application you want to use, you could use the following to set up the libraries and display Mypanel

address ispexec
"LIBDEF ISPLLIB DATASET ID('COLIN.ISPF.ISPLLIB') STACK"
"LIBDEF ISPMLIB DATASET ID('COLIN.CUCI.ISPMLIB') STACK"
"LIBDEF ISPPLIB DATASET ID('COLIN.CUCI.ISPPLIB') STACK"
"LIBDEF ISPTLIB DATASET ID('COLIN.CUCI.ISPTLIB') STACK"
address tso "ALTLIB ACTIVATE APPLICATION(CLIST)
DATASET('COLIN.CUCI.EXEC') "
"SELECT PANEL(Mypanel ) NEWAPPL(MYA) PASSLIB"
/* afterwards reset things back */
address tso "ALTLIB DEACTIVATE APPLICATION(CLIST)"
"LIBDEF ISPLLIB"
"LIBDEF ISPPLIB"
"LIBDEF ISPMLIB"
"LIBDEF ISPTLIB"

What has been libdef-ed?

You can use the TSO command ISPLIBD to display the data sets that have been libdef-ed for the logical screen. Note each logical screen can have its own libdef statements – depending on the set up. See here for a description.

I’ve run out of space on z/OS – what is using it all?

I hit this problem when trying to backup some data sets. There was plenty of free space on some of the volumes, but not much free space on the “user” volumes.

You can use ISPF 3;4 to list data sets on a volume or with a specified high level qualifier. You can use the sort command, for example sort tracks. This reports on number of tracks allocated sorted in descending size. You can deletes unwanted data sets.

If you go to ISPF 3;4 and specify option V for VTOC, and specify a Volume Serial, you can display information about the volume.

If you are running in Unix Services

du -a ./ | sort -n -r | head -n 30

Gives the top 30 files or directories

Old dogs, new tricks, ISPF compare

When looking for a comparison facility for Unix files, I stumbled across ISPF edit compare function.

If you are editing a file you can use the compare * command to show the changes you made to the file in the current session. This gave me

000001 line 1
====== line 3
.OAAAA line 2
.OAAAB line 4
.OAAAC line 5

Where

  • line 1 was unchanged
  • line 3 was deleted
  • line 2,4,5 were added

You can then use “mm” or “mdd …. mdd” prefix commands on the ====== to apply the changes to the file, and use “d” or “dd … dd” on the .O prefix lines to delete the lines.

You can use the compare command, and be prompted for options.
I specified a Unix file, and could see the differences.

You can set the exclude option (at the bottom of the panel), which says exclude all the lines, but display ‘n’ lines around changes, where ‘n’ is specified at the top of the panel.

One funny….

I noticed that compare was display “blank” lines in Unix files as being changed. The original file had a null line, with just an end of line. When I customised the file and saved it, ISPF replaces an “end of line” with “blank end of line”. As these do not match, they show up as being changed.

The solution is to edit the original file with null lines, make a dummy change, and save the file. The file will no longer have null lines, and only your changes will be visible.

ASCII files in OMVS

I found I was unable to compare python source files in OMVS, because they were ASCII files. (When the files were tagged as ASCII, I could edit them).

You cannot use ISPF compare if the files are ASCII (non EBCDIC). You can do

Compare the files then use the following to transform them back.

The power of exclude in ISPF edit

I hope most people know about the ISPF edit exclude facility.  You can issue commands like

X ALL /* exclude every thing */
F XXXX ALL
F YYYYY ALL WORD
DELETE ALL X /* delete everything which is excluded */
RESET
X ALL
F ZZZZ all
F AAAA all
FLIP /* make the excluded visible, and the displayed hidden */
CHANGE 'ABC' 'ZYX' ALL NX /* do not change hidden lines */

You can also exploit this in macros.  See ISREDIT XSTATUS.

/* rexx */ 
ADDRESS ISPEXEC
'ISREDIT MACRO'
"ISREDIT EXCLUDE 'AAA' ALL PREFIX" /* just like the command*/
"ISREDIT LOCATE .ZLAST" /* go to the last line */
"ISREDIT (r,c) = CURSOR" /* get the row and column number */
/* r has the row number of the last line */
do i = 1 to r
"ISREDIT (xnx) = XSTATUS "i
say "Line exclude status is" i xnx
"ISREDIT (line) = LINE " i /* extract the line */
if (...) then
"ISREDIT XSTATUS "i" = X" /* exclude it */
end

You can also see if a line has been changed this edit session:

"ISREDIT (status) = LINE_STATUS "i /* for line i */
if (substr(status,8,1) = '1') then
say "Line" i " was changed this session "

 

 

How to capture TSO command output into an ISPF edit session

One way of doing this, is to run a TSO command in batch, use SDSF to look at the output, and then use SE to edit the spool file.

This was too boring, so I wrote a quick macro ETSO

/* REXX /  parse source p1 p2 p3 p4 p5 p6 p7 env p9  
if env = "ISPF" then  
do    
  ADDRESS ISPEXEC    
  "ISREDIT MACRO (cmd ,REST)"  
end  
else  
do
    Say "This has to run from an ISPF edit session " 
   return 8;  
end  
/* prevent auto save … user has to explicitly save or cancel*/  
"ISREDIT autoSave off prompt"  
x = OUTTRAP('VAR.')  
address tso   cmd rest  
y = OUTTRAP('OFF')  
/* insert each record in turn last to first at the top of the file */ 
do i = var.0 to 1 by -1 
  "ISREDIT LINE_AFTER 0  = '"var.i"'" 
end 
exit

This macro needs to go into a dataset in SYSEXEC or SYSPROC concatenation – See TSO ISRDDN. I typed etso LU in an edit session, and it inserted the output of the TSO LU the top of the file.

For capturing long lines of output, you’ll need to be in a file with a long record length.

Neat!

To create a temporary dataset to run the above command I created another rexx called TEMPDSN

/* REXX */
parse source p1 p2 p3 p4 p5 p6 p7 env p9
if env = "ISPF" then
do
  ADDRESS ISPEXEC
  "ISREDIT MACRO (cmd ,REST)"
end
else
do
  Say "This has to run from an ISPF session "
  return 8;
end
u = userid()
address TSO "ALLOC DSN('"u".temptemp') space(1,1) tracks NEW DELETE ",
"BLKSIZE(1330) LRECL(133) recfm(F B) DDNAME(MYDD)"
if (rc <> 0) then exit
address ISPEXEC "EDIT DATASET('"u".temptemp')"
address TSO "FREE DDNAME(MYDD)"

You can then do even cleverer things by having TEMPDSN calling ETSO as a macro, and passing parameters using the ISPF variable support from the TSO command line.

Updated TEMPDSN, changes in bold.

/* REXX */ 
parse source p1 p2 p3 p4 p5 p6 p7 env p9
say "env" env
if env = "ISPF" then
do
ADDRESS ISPEXEC
"ISREDIT MACRO (cmd ,REST)"
end
else
do
Say "This has to run from an ISPF session "
return 8;
end
tempargs = ""
/* if we were passed any parameters */

parse arg args
if ( length(args) > 0) then
do
tempargs = args
"VPUT tempargs profile"
end

u = userid()
address TSO "ALLOC DSN('"u".temptemp') space(1,1) tracks NEW DELETE ",
"BLKSIZE(1330) LRECL(133) recfm(F B) DDNAME(MYDD)"
if (rc <> 0) then exit
address ISPEXEC "EDIT DATASET('"u".temptemp') MACRO(ETSO)"
address TSO "FREE DDNAME(MYDD)"

if ( length(tempargs) > 0) then
do
"VERASE tempargs profile"
end

and the macro ETSO has

/* REXX */ 
parse source p1 p2 p3 p4 p5 p6 p7 env p9
if env = "ISPF" then
do
ADDRESS ISPEXEC
"ISREDIT MACRO (cmd ,REST)"
end
else
do
Say "This has to run from an ISPF edit session "
return 8;
end
/* prevent auto save ... user has to explicitly save or cancel*/
"ISREDIT autoSave off prompt"
if (length(cmd) = 0) then
do
"VGET tempargs " PROFILE
if (rc = 0) then
cmd = tempargs
end
x = OUTTRAP('VAR.')
address tso cmd rest
y = OUTTRAP('OFF')
/* insert each record at the top of the file */
do i = var.0 to 1 by -1
"ISREDIT LINE_AFTER 0 = '"var.i"'"
end
EXIT

From ISPF 6, a TSO command line, I issued tempdsn racdcert list certauth  and it gave me the file with the output from the command, and the file has record length of 133.  If you try to  save the data,  the data set will be deleted on close.