MVS TOOLS AND TRICKS OF THE TRADE SEPTEMBER 2003 Sam Golob MVS Systems Programmer P.O. Box 906 Tallman, New York 10982 Sam Golob is a Senior Systems Programmer. He also participates in library tours and book signings with his wife, author Courtney Taylor. Sam can be contacted at sbgolob@cbttape.org. Information about the CBT MVS Tapes can be found on the web, at http://www.cbttape.org. A FRESH LOOK AT THE PDS COMMAND PACKAGE I am happy to say that growing numbers of sysprogs are doing things to improve your life. How? They are writing and enhancing utilities for their own use, but they are sharing them with the public. And there is a great difference between "free software", which anyone can use, and "free market software", that is, vendor software, which for an MVS system, usually costs a big bundle. So when I read the announcements about new vendor products on the market, I usually say "whoopdie doo", and I'm only interested if the new stuff has something to do with a need of ours. But if I read about free software that came out, I'm all ears. And that's because I can use all of it, right away, myself, with no restrictions. I'm writing this just before SHARE, and Sam Knutson is busy making duplicates of the CBT Tapes (the actual tape cartridges) and the cd-roms containing the CBT Tape materials. Sam Knutson gives out many hundreds of tapes and cd-roms at SHARE, on his own initiative, to be able to help make our lives easier. And I, for my part, being the proprietor of the CBT Tape collections, have just come out with new releases of both the regular CBT Tape and the CBT Overflow Tape, for the occasion. This could only have been made possible by people's contributions of software. Over the last year or so, we've been fortunate to get contributions for the CBT Tape collections at a rate averaging about 20 or 25 per month. So there's been a lot of activity and improvement. My reaction at seeing so many new developments, is to try and resist being overwhelmed, but I still feel like a kid in a candy store. I look through everything with a quick overview and pick what strikes my eye, for trying out. Some really nice packages and programs have passed through our portals recently, but I'd really like to present an "oldie but goodie", because I feel it has been neglected by many people who can really use it. THE PDS TSO COMMAND PACKAGE I have a good reason for mentioning the PDS command package here. The PDS command (which is free software) is currently maintained and kept up-to-date by John Kalinich, and it resides on File 182 of the CBT Tape collection. Load modules for PDS are on both Files 035 and 135 of the CBT Tape, but you should also use its ISPF panels and messages that are on File 182, although you don't have to run PDS in ISPF mode. As of this writing, the current version of PDS is 8.5.24. For clarity in this discussion, I'll refer to a partitioned dataset as a pds, in lower case, while I'll talk about the PDS command package itself, as PDS, in upper case. Now, for my reason: It has been my observation that even though the PDS TSO command package is quite old, and versions of it have been around for many years, (I remember using an ancient version of it on MVT when I first started in this business) some people use it, and some do not. I guess you can make that statement for any package--some people use it and some don't. But PDS is very different. The PDS package, as it is today, has at least a thousand (I didn't say a hundred) different utility functions. And something that versatile and useful shouldn't be ignored by ANYONE, in my opinion. So I think it's important for me to say something about it. How do you start talking about something so vast? We are fortunate with PDS, because you really can begin at the beginning. It's only afterward that the sky's the limit. You invoke PDS as a TSO command, and you point it at a dataset name. That is, you invoke PDS from a TSO session by saying its name, as a TSO command, followed by an operand--a dataset name. The dataset name is that dataset which you want the PDS command to manipulate. And manipulate, it can! Please see Figure 1 for a general summary of some of the PDS subcommand categories. And see Figure 2 for an overview of more. If you want to learn more about the PDS command package in depth, I once wrote a course on it. My course is distributed with the PDS command package on CBT Tape File 182, as members $PDSART0 thru $PDSART3. What can PDS do in a dataset? I can only begin the story here, but I can't end it here. If you're interested in becoming a "true dataset jockey", you'll investigate further than what I can mention now. At least read my course! At the time I wrote that material, I invested many hundreds of hours in learning it. And I still use the knowledge in my everyday work today--even so many years afterwards. It has not become obsolete. I want to show you one more clever thing about the PDS command package. A function as simple as a pds member rename, has an added twist when you're talking PDS language. Of course, you can rename one member to another name, possibly with a REPLACE operand if the new name exists and you want to replace it. But PDS can do something that no one else can. You can use PDS to SWAP dataset names in one operation. For example, you can say, RENAME MEMBER1 MEMBER2 SWAP. This will rename MEMBER1 to MEMBER2, and MEMBER2 to MEMBER1 in one operation, without involving a third name as an intermediate. If you don't use PDS, you don't know how to do that! So PDS can do a lot of ordinary things to a dataset, and a lot of unusual things too, like expanding the number of directory blocks in a pds, on the fly. If you run out of directory space, there's no need to reallocate a bigger dataset, copy the data over, rename and delete the the old dataset, and rename the new dataset to the old name. Just say: FIXPDS EXPANDDIR(nn), where nn is the number of directory blocks you want to add, and just answer YES to the prompt. Even though you don't have RACF ALTER access to the dataset, just UPDATE access, you should still be able to do that. Expanding the directory works by copying a few of the beginning pds members to the end, and using the freed space at the beginning, to reformat as new directory blocks. There's so much more, that I can't begin to mention it. One thing about the PDS command package is so unique though, that I can't leave this discussion without talking about it. That is, the concept in PDS of "member groups", which actually means "subgroups of the pds members". The PDS command package recognizes two distinct categories of member subgroups. The first is a member subgroup that is defined by RULES. The second is a member subgroup that is a LIST of member names. You use the MEMBERS subcommand of PDS to define a subgroup using rules. You use the SUBLIST subcommand of PDS to define a subgroup as a list of members. The current member group defined by PDS is always referred to by using a single asterisk (*) instead of a member name, in any PDS subcommand that deals with a member. Thus, by using the asterisk as a member name in a PDS subcommand, you do the operation on all the members in the subgroup--possibly hundreds of them at one time! And for the record, if you ever want to refer to ALL the members in a pds as one group, you use the colon (:) as a "member name" in a PDS subcommand, to designate "the subgroup of all members in the pds". And the operation will be performed on all of the members in the target pds. Defining a member subgroup by rules, consists of using the wildcard symbol (*) and the pattern symbol (/) in various combinations. For example, if you want to define a group of members beginning with ABC, you'd say: MEMBERS ABC* , whereas if you want to define a group of all pds members with the string ABC included anywhere in the name, you'd say: MEMBERS ABC/ or MEMBERS /ABC . Defining a member subgroup as a list of names, is very similar. You just use the SUBLIST subcommand instead of the MEMBERS subcommand. But the effect is very different. When you use the SUBLIST command along with a rule (wildcard or pattern or a combination), PDS does not just leave the rule intact, to define the group. Instead, PDS goes through the entire pds directory, and picks out all of the actual member names which satisfy the rule conditions, and then it defines the list of names as the group (NOT the rule). What difference does this make? Plenty! Much of the difference takes effect when you issue a CHANGE PDS subcommand to change the target pds that the PDS command is aimed at. When you CHANGE the target partitioned dataset, PDS does not change the default subgroup. If that subgroup is defined as a rule, it will refer to a different subset of members in the new pds--those members in the new pds that satisfy the rule. But if the member subgroup is defined as a list of member names, and you CHANGE the target pds that PDS is pointing to, there may be no member names in the new pds, that are common with the member names in the old pds. So the default member subgroup in the new pds, may actually turn out to be null, but this will not be seen until you issue a new PDS subcommand against the default group (*), and no member name matches turn up against the old list. You can always convert the default member group to a list of names, by issuing the SUBLIST * command. This will cause PDS to look at all the member names in the target pds which overlap with the currently defined member subgroup, and cause that list of names to be the new "currently defined member subgroup". There is another (and extremely powerful) way to define a member subgroup, and that is with the IF and FIND PDS subcommands. IF will pick a subgroup of members based on about 60 possible different criteria. And FIND will pick a member subgroup of all members which contain, or don't contain, a certain character string. Thus, you can say: IF : CHANGED(mm/dd/yy:mm/dd/yy) THEN(SUBLIST) and this will mean, that all members with ISPF statistics showing that they were changed between the two indicated dates, will be chosen for inclusion in the "list" member group. Or you can say: FIND : /somestring/ THEN(SUBLIST) and this will mean that from all the members in the pds, you are picking only the members containing the indicated character string, to be included in the member subgroup list. Once you've picked your group, you can either refine it further by picking a smaller subgroup from it, containing a second string. For example: FIND * /secondstring/ THEN(SUBLIST) Or you can immediately issue a PDS subcommand to operate on all the members in your current subgroup now, such as: COPY * second.pds REPLACE which will set up an IEBCOPY job in the foreground, to just copy those selected members to the second pds. WHAT ABOUT FOR THE OLD PDS USERS? So I hope I've whetted the appetite of those "new people", who haven't used the powerful PDS command package before. But for those thousands of "old people" who have used PDS for years, to their immense profit, there is still something to add. One of those things is PDS's immense capabilities for manipulating, re-linkediting, and changing the attributes of load modules. Using PDS subcommands, you can possibly change the attributes or replace an equal-sized string in hundreds of load modules at one time. So it pays, even for the old veterans, to study the PDSHELP member, the undocumented features (the $$$UNDOC member) and my course (members $PDSART0 thru $$PDSART3) in CBT Tape File 182. In addition, John Kalinich is constantly adding enhancements, including some PDSE support, so it pays to keep up. I trust that this month's topic will be of much help. Best of luck to all of you, and I hope to see you again next month. * * * * * * * * * * * * * * * * * * * * * * * Figure 1. General Overview of PDS Command Options -------------------------- PDS O Subcommand Selection ------------------------- OPTION ===> Member subcommands (or enter P for member group prompting): A - Attrib DEL - Delete L - List REPRO - Repro AL - Alias DSP - Dsprint M - Map RES - Restore B - Browse E - Edit MEML - Memlist REV - Review COM - Compare F - Find OUT - Outcopy SUB - Submit COP - Copy FSE - Fse PR - Printoff SUBL - Sublist DIR - Direntry HI - History REN - Rename V - View DCF - Dcf Script IF - If REP - Replace VE - Verify VPS - Vpsprint Data set subcommands: C - Change D - Display FIX - Fixpds PA - Pattern COMPR - Compress DSN - Dsname MEM - Members U - Usage Miscellaneous subcommands: CON - Control H - Help ISPM - Ispmode T - TSO END - End ISPF - Ispf R - Recall UT - Utility Enter O for subcommand selection menu (DIALOG and PDS commands) * * * * * * * * * * * * * * * * * * * * * * * Figure 2. Overview of some Specific command categories for PDS 8.5 ---------------------- PDS O Subcommand Selection --------------------- OPTION ===> Choose one of the following: DIALOG commands (ISPF mode operation) 1 - Function selection list 2 - Display or Table processing options (SORT, F, X) 3 - Features and Short Hand commands 4 - Set default selection list 5 - Extended/User/Installation processing selection list PDS commands 6 - Whole dataset related commands 7 - Miscellaneous commands 8 - Member related commands 9 - Member group prompting panel