How to list out a GDG base properties through REXX - mainframe

How to know GDG base properties through REXX code; Of course we can view the GDG limit thru File-aid 3.2 option But need to list the properties on the fly and may be used in consecutive program/module. Hope made you clear and waiting for response!
(Do let me know if any other information is required?)

From REXX, you can target TSO then use the listcat command:
ADDRESS TSO
"LISTCAT ENTRY('XXX') ALL"
where XXX is the GDG base.
For capturing TSO output, look into OUTTRAP which can capture the output from most TSO commands - I haven't specifically tested listcat since I don't have a z900 under my desk at home :-) I'll give it a shot at work tomorrow.
Call OutTrap "xyzzy."
should give you the output into the xyzzy stem variable and you can stop the capture with:
Call OutTrap "off"

Something like this should do it.
/* REXX */
arg entry .
call outtrap "listc."
"LISTCAT ENT("entry") GDG ALL"
if rc > 0 then exit 12
do i = 1 to listc.0
if pos("LIMIT", listc.i) > 0 then do
limit = word(translate(listc.i,' ','-'),2)
say 'GDG limit is' limit
leave
end
end

One caveate to the above suggestion... If you only want GDG entries you may need to consider removing the keyword ALL on the LISTCAT ENTRY('XXX') ALL line. I believe the ALL word will list GDG & Non-GDG datasets that happen to match the catalog entry name.

Related

Is there a bash function for determining number of variables from a read provided from end user

I am currently working on a small command line interface tool that someone not very familiar with bash could run from their computer. I have changed content for confidentiality, however functionality has remained the same.
The user would be given a prompt
the user would then respond with their answer(s)
From this, I would be given two bits of information:
1.their responses now as individual variables
2.the number of variables that I have now been given: this value is now a variable as well
my current script is as follows
echo List your favorite car manufacturers
read $car1 $car2 $car3 #end user can list as many as they wish
for n in {1..$numberofmanufacturers} #finding the number of
variables/manufactures is my second question
do
echo car$n
done
I am wanting to allow for the user to enter as many car manufacturers as they please (1=<n), however I need each manufacturer to be a different variable. I also need to be able to automate the count of the number of manufacturers and have that value be its own new variable.
Would I be better suited for having the end user create a .txt file in which they list (vertically) their manufactures, thus forcing me to use wc -l to determine the number of manufacturers?
I appreciate any help in advance.
As I said in the comment, whenever you want to use multiple dynamically created variables, you should check if there isn't a better data structure for your use case; and in almost all cases there will be. Here is the implementation using bash arrays. It prints out the contents of the input array in three different ways.
echo List your favorite car manufacturers
# read in an array, split on spaces
read -a cars
echo Looping over array values
for car in "${cars[#]}"
do
echo $car
done
echo Looping over array indices
for i in ${!cars[#]}
do
echo ${cars[$i]}
done
echo Looping from 0 to length-1
let numcars=${#cars[#]}
for i in $(seq 0 $((numcars-1)))
do
echo ${cars[$i]}
done

Cannot get SDSF to respond to TSO or batch commands

I am trying to write a JCL Job Step that will retrieve the JESMSGLG, JESJCL, and JESLOG datasets of the active (this) job. The idea here is that I need to collect the log (from the beginning of the job to now) and record it in a data set before it ends execution.
So I have:
// EXEC PGM=SDSF
//MYOUT DD SYSOUT=* (to changed to a dataset in the future)
//ISFOUT DD SYSOUT=*
//ISFIN DD *
SET CONSOLE BATCH
PREFIX *
OWNER myid
DA OJOB
++S
PRINT FILE MYOUT
FIND JESMSGLG FIRST
++X
FIND JESJCL FIRST
++X
FIND JESLOG FIRST
++X
PRINT CLOSE
When I run the job all I get is CC=0000 and a printout of the SDSF Primary panel in IFSOUT.
If I try this under TSO with the SDSF command, again, all I get is the primary panel. If I enter any command (even an invalid one) it just seems to take the command and silently ignore it.
I can do this under ISPF just fine.
Any ideas as to what to look for to see what I am doing wrong or missing? Its pretty clear to me that this may well be a setup/invocation/security issue but I don't know how to debug it when all I seem to get is CC=0000.
Yup, that was it! I added PARM='++24,80' to the // EXEC PGM=SDSF and it now works. I'm not entirely sure why but it may have been a local installation error of SDSF.
It turns out the the commands I listed above are not quite right, but that's not relevant to this question.
Thank you, Kevin, for your time and interest.

How to order control m job using REXX? like Control m utility CTMAPI

I have to order few jobs in control m from different scheduling tables. this is manual task so i want to automate it using rexx.
I found below in 'Order or Force under Batch, REXX or CLIST' section of 'CONTROL M USERGUIDE'
EXEC CTMAPI PARM=‘ORDER variable’
I could not find syntax to call CMTAPI using rexx.
ADDRESS 'LINKMVS' is the equivalent of // EXEC PGM=something,PARM='whatever' in REXX. I don't know what the variable is supposed to be, but since this is Control-M, I am going to assume job name. A very simple example:
say 'Enter name of job'
pull jobname
parmvar = 'ORDER' jobname
`ADDRESS 'LINKMVS' 'CTMAPI parmvar'
Please note that for LINKMVS, the variable name goes inside the string passed. The LINKMVS environment substitutes the variable automatically. For example, if I entered MYJOB to the prompt, LINKMVS will build a PARM string of `ORDER MYJOB'. This is the exact equivalent of
// EXEC PGM=CTMAPI,PARM='ORDER MYJOB'
This IBM® Knowledge Center page for the z/OS 2.3 TSO/E REXX Reference manual shows several examples of calling a program in the same manner as // EXEC PGM=,PARM= (item 1). Items 5 through 9 show different ways of using ADDRESS 'LINKMVS'; note how variables are treated in each example.
After suggestions from NicC, zarchasmpgmr and few research, finally i am able to order job with CTMJOB utility. I searched for the loadlib and called TSO using REXX.
/*****REXX*******/
ADDRESS TSO
"CALL 'MY.IN.LOAD(CTMJOB)'
' ORDER DSN=MY.SCHED.LIB TABLE=SCHDTBL,
JOB=JOBNAME,DATE=DATE'"
EXIT
Details found in INCONTROL for ZOS utilities guide. This document was very useful.
http://documents.bmc.com/supportu/952/56/64/195664/195664.pdf

JCL - MVS: how to retrieve result from submiting MVS command in Batch

Morning guys,
After submitting a MVS command in Batch, I wonder if it is possible to print the result in a seq file. Thanks for your time.
//S02IEBG EXEC PGM=IEBGENER
//SYSUT2 DD SYSOUT=(A,INTRDR),DCB=BLKSIZE=23440
//SYSIN DD DUMMY
//SYSOUT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD *,DLM=$$
/*$VS,'$DQ'
$$
It isn't clear from your question, but if you mean "after submitting your job, can you capture output to a dataset", I would suggest you use the XDC line command in SDSF. If you want a specific part of the output, use the ? line command first to show each of the outputs, then XDC on the one you want to save.
Yes it is possible to write the SYSOUT to a sequential file. I have done this before, but I would not recommend it unless you absolutely need to.
Your system should have some SYSLOG management system (like SMR/JMR or similar), where you can browse the SYSOUTs that a job has produced. Don't get me wrong, I realize that this isn't fool proof. There are times when you may need to write the SYSOUT to a file. The reason I needed to was because I looping with a lot of debugging displays and needed to have a lot lines to help me debug.
If you want to make sure that the SYSOUT goes to a file all you need to do is put the file after the SYSOUT:
//S02IEBG EXEC PGM=IEBGENER
//SYSUT2 DD SYSOUT=(A,INTRDR),DCB=BLKSIZE=23440
//SYSIN DD DUMMY
//SYSOUT DD DSN=YOUR.SYSOUT.FILE,
// DISP=(NEW,CATLG,DELETE),
// UNIT=TEST,SPACE=(TRK,(2,1),RLSE),
// DCB=(LRECL=080,BLKSIZE=0,RECFM=FB)
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD *,DLM=$$
You can alter the size of the file if you need to by editing the SPACE parameter. If you plan on running this job more than once, you will need to add a delete step before this, or make your SYSOUT file a GDG that can be incremented. Otherwise, the DISP of NEW will not work.
This can be done with any DD name as long as you know what the proper file allocation is.
I believe that the following may work. That is assuming that you want to capture the output from the DQ command :-
//SDSF EXEC PGM=SDSF
//ISFOUT DD SYSOUT=*
//CMDOUT DD DSN=YOUR.DATASET,
// DISP=(,CATLG,DELETE),
// DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0),
// SPACE=(CYL,(1,1)),UNIT=SYSDA
//ISFIN DD *
SET CONSOLE BATCH
SET DELAY 60
/$ DQ
PRINT FILE CMDOUT
ULOG
PRINT
PRINT CLOSE
/*
//
Obviously this may need to be tailored according to your site's requirement.
You may find Issuing MVS or JES commands helpful.
Addition Re Comment :-
I did try the SDSF but I am not authorized to use it, which is why I
am looking for another way.
Perhaps then using TSO/E (REXX) as per :-
From TSO/E, you can establish an extended MCS console session using
the TSO/E CONSOLE command. After you activate a console session, you
can issue MVS™ system and subsystem commands and obtain command
responses. This appendix describes the different commands and
functions you can use in REXX execs to set up and use a console
session.
Writing REXX Execs to perform MVS operator activities
However, authority may be an issue if not immediately perhaps as soon as someone cottons on to you getting around the doors already closed.
This may work (I don't have the facilities to test it) :-
/* REXX */
ADDRESS TSO 'CONSPROF SOLDISPLAY(NO)'
ADDRESS TSO 'CONSOLE ACTIVATE'
ADDRESS CONSOLE '$DQ'
/* retrieve output command */
max_iterations = 100
DO i = 1 to max_iterations
messages_remaining = GETMSG('line.','SOL',,,10)
IF messages_remaining = 0 THEN leave
END
/* Done so echo retrieved messages
say 'Messages Retrieved are :-'
DO i = 1 to line.0
say '*** ' line.i
END
ADDRESS TSO 'CONSOLE DEACTIVATE'
EXIT
You'd need to wrap that into your batch job, so you may find the following helpful
How can I run my Rexx program as a batch job?.
Method 2 would be appropriate, as you want a TSO/E environment
A solution could be speaking to those responsible for denying access to SDSF, This could result in authority being given. There again it may result in the open doors such as being able to issue JES commands being shut.
You probably have access to SDSF to view the output.
Next to the job you want to print type xdc this will pop up a panel for dataset allocation(or it can be already existing one). Once done it will print the output and close it.
If You need just a output of a certain step/sysout you can type ? next to the job in SDSF. This will give you the list of the outputs. Same as before type xdc next to the one you picked and allocate a dataset.
This can also be done to your TSO session if you use the commands directly and need to have a history of it. Although this will only work until you close the SDSF ULOG.

Find out ID of 'at' job from within it

When I schedule a job with 'at' it is assigned an id, viz:
job 44 at 2014-01-28 17:30
When that job runs I would like to get at that id from within it. This is on Centos, FWIW. I have established that no environment variable contains the ID. When the Perl code in that job runs I would like it to be able to print the job ID (44 in this example).
Yes, I know that atq shows an = next to jobs that are executing, but there might be more than one of those at a time.
I could do something like pass a unique argument to the job when scheduling it, capture the ID, save that and the argument to a file somewhere, read that from the job. That's a lot of work I'd rather not go to if I don't have to, and it seems like this should be simple but I'm drawing a blank.
What follows is figured out by reading sources of at-3.14. The way at puts job id and the time when it is run into the file name should be similar for any version, but I haven't checked this.
To begin whith at encodes the job id and the time when a particular job should be run into the file name describing a job. The file name has format aJJJJJTTTTTTTT, where JJJJJ is 5 character hexadecimal string, the job id, and TTTTTTTT is an 8 character hexadecimal string, the time when the job should be run. The time is stored as seconds from the epoch.
At jobs are run by feeding a job description file as the standard input to sh -c. Fortunately the Linux kernel provides a symbolic link, /proc/self/fd/0, which will point to the standard input of the process currently being executed (play with ls -l /proc/self/fd/0 in case you need to assure yourself that this indeed is so).
A file describing a job has been deleted by the time a job is run. However, the file is still available for the kernel because it has been duplicated with dup(2) before being used as the standard input for a job. So, actually we are resolving a symbolic link to a file name which is not visible any more. In the perl script at the end we need to take this into account as readlink will return something like /foo/bar/baz (deleted) instead of /foo/bar/baz. And we're interested in just the file name which has all the information we need.
The reason why the symbolic link points to a deleted file is because at daemon unlinks the original before executing the job. Unlinking gets done only after creating a copy, a hard link, which begins with = instead of a. With this the at daemon tries to ensure there will be only one copy of a job running: the daemon will not execle(2), ie. it will bail out, should the link(2) fail. Because the original file has been subject to open(2) and dup(2) the inode is still there for the kernel to use because it still has hard links pointing to it.
After a fairly long and possibly confusing introduction, here is how to put it all together:
#!/usr/bin/perl
use strict;
use warnings;
my $job_file = readlink("/proc/self/fd/0");
if (index($job_file, " ") > 0) {
$job_file = substr($job_file, 0, index($job_file, " ") - 1);
}
my $tmp = substr($job_file, rindex($job_file, "/") + 1);
$tmp =~ s/^a([0-9a-f]{5})[0-9a-f]+/$1/;
my $job_id = hex($tmp);
if ($job_id > 0) {
printf("My AT job id is %d.\n", $job_id);
}
# end of file.

Resources