Using SSH as an Alternative to TN3270 on z/OS
Many people think that the only way to do anything on z/OS is through TN3270 and ISPF panels. That has not been true for a very long time. z/OS UNIX System Services is a fantastic alternative to ISPF panels. The best part is that if you are familiar with standard command processing languages like shell, Bash, and Windows Powershell, using z/OS UNIX System Services will be straight forward. This reference provides a myriad of z/OS UNIX System Services alternatives to traditional TN3270 interfaces on z/OS.
ZOAU is a prerequisite for many of these examples. A dependency on ZOAU will be noted for each example where ZOAU is required. This reference also assumes that you are using ZOAU 1.2.x or greater. See Install ZOAU 1.2.x for inscructions on how to install ZOAU.
Having SSH login enabled is also a prerequisite.
Installing BASH and setting it as your default shell is not required, but highly recommended.
Working With Data Sets
In the world of z/OS, data sets are functionally the same as UNIX files. So, for all intents and purposes data sets are just files.
However, it is worth noting that data sets are fundamentally different from UNIX files architecturally speaking. So, the way data sets are managed, located, manipulated, and created is highly esoteric from the perspective of someone with a distributed systems background.
Data sets are relevant because they compose the entire MVS (Multiple Virtual Storage) side of z/OS. For context, the combination MVS and Unix System Services is what makes z/OS what it is. So, if you are unable to manage data sets, you are essentially limited to half of the system’s capabilities.
ISPF panels are inherently oriented towards working with data sets, but given the objective of this guide is to make doing most tasks through z/OS Unix System Services possible, this segment will focus on the interfaces available for working with data sets through z/OS UNIX System Services.
The scope of this section is limited to non-VSAM data sets only.
List Data Sets (Requires ZOAU)
The following example uses the dls
command to display a list of data sets that match a pattern. In the following example all data sets that match the pattern USER.LLO.*
are displayed. The dls
command is functionally similar to the standard standard UNIX ls
command.
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
List Data Sets With Details (Requires ZOAU)
If the -s
flag is used with the dls
command, the following information is also provided with each data set listed.
- Data Set Organization
- PS (Physical Sequential)
- This is just a fancy way of saying it is just a flat file.
- PO (Partitioned Organization)
- This is just a fancy way of saying that it functions like a folder that can contain a number of files.
- PS (Physical Sequential)
- Logical Record Format
- This describes the structure of that data. For example, FB (Fixed Blocked) means that each “line“ or record is a fixed length and that the data set uses blocking.
- Logical Record Length
- The is the length of each “line” or record in the data set.
- Volume
- The name or ID of the DASD (Direct Access Storage Device) device that the data set resides on.
- Total Bytes Used
- Total Bytes Available
$ dls -s USER.LLQ.*
USER.LLQ.DATASET1 PS FB 80 VOL001 11 56664
USER.LLQ.DATASET2 PO FBA 133 VOL002 1021 56664
USER.LLQ.DATASET3 PO U 0 VOL003 2192 56664
If the -b
flag is used with the dls
command, block size is included as part of the additional details instead of total bytes used and total bytes available. The block size is used to optimize I/O and is generally a multiple of the record length. Block size can also be significant for things other than I/O.
All of the data set listed in this example have a block size of
32720
.
$ dls -b USER.LLQ.*
USER.LLQ.DATASET1 PS FB 80 32720 VOL001
USER.LLQ.DATASET2 PO FBA 133 32718 VOL002
USER.LLQ.DATASET3 PO U 0 32720 VOL003
List Data Sets and Include Migrated Data Sets (Requires ZOAU)
Migrated data sets are those that have been migrated from DASD (Direct Access Storage Device) to low cost tape. These migrated data sets are not displayed by default when using the dls
command, but if you use the -m
flag with the dls
command, migrated data sets will also be listed.
$ dls -m USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
USER.LLQ.MIGRATE1
USER.LLQ.MIGRATE2
List All Data Sets on a DASD Volume (Requires ZOAU)
The following example uses the vtocls
command to list a DASD (Direct Access Storage Device) volume’s VTOC (Volume Table of Contents) which is a listing of all the data sets the reside on the volume.
$ vtocls VOL001
USER.LLQ.DATASET1 PS FB 80 VOL001
USER2.LLQ2.DATASET5 PO FBA 133 VOL001
USER2.LLQ2.DATASET7 PO U 0 VOL001
USER3.LLQ3.DATASET1 PS FB 80 VOL001
List Partitioned Data Set Members (Requires ZOAU)
The members or entries contained in a partitioned data set can me listed using the mls
command.
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
MEMBER3
List Partitioned Data Set Members And Include Aliases
The aliases to data set members in a partitioned data set can be displayed using tsocmd
to run the TSO (Time Sharing Option) LISTDS
command with the last positional argument being MEMBERS
, which tells LISTDS
to display a member listing.
$ tsocmd "LISTDS USER.LLQ.DATASET2' MEMBERS"
LISTDS 'USER.LLQ.DATASET2' MEMBERS
USER.LLQ.DATASET2
--RECFM-LRECL-BLKSIZE-DSORG
FBA 133 32718 PO
--VOLUMES--
VOL002
--MEMBERS--
MEMBER1 ALIAS(ALIAS1)
MEMBER2
MEMBER3 ALIAS(ALIAS2,ALIAS3)
Rename a Data Set (Requires ZOAU)
A data set can be renamed using the dmv
command. This command functions exactly like the standard UNIX mv
command.
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
$ dmv USER.LLQ.DATASET2 USER.LLQ.RENAME
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET3
USER.LLQ.RENAME
Rename a Partitioned Data Set Member (Requires ZOAU)
A partitioned data set member can be renamed using the mmv
command. This command functions almost exactly like the standard UNIX mv
command. The only difference is that the first positional argument must be the name of the partitioned data set.
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
MEMBER3
$ mmv USER.LLQ.DATASET2 MEMBER2 RENAME
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER3
RENAME
Delete a Data Set (Requires ZOAU)
A data set can be deleted using the drm
command. This command functions almost exactly like the standard UNIX rm
command.
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
$ drm USER.LLQ.DATASET3
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
Just like the standard UNIX rm
command, the drm
command can all delete several data sets based on a pattern. Therefore, this command should similarly be used with caution.
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
$ drm USER.LLQ.*
$ dls USER.LLQ.*
BGYSC1103E No datasets match pattern: USER.LLQ.*.
Delete a Partitioned Data Set Member (Requires ZOAU)
A partitioned data set member can be deleted using the mrm
command. This command functions almost exactly like the standard UNIX rm
command.
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
MEMBER3
$ mrm 'USER.LLQ.DATASET2(MEMBER3)'
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
Just like the standard UNIX rm
command, mrm
can delete several partitioned data set members based on a pattern. Therefore, this command should similarly be used with caution.
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
MEMBER3
$ mrm 'USER.LLQ.DATASET2(MEMBER*)'
$ mls USER.LLQ.DATASET2
BGYSC1505E No members match pattern * in dataset USER.LLQ.DATASET2.
Display The Contents of a Sequential Data Set
The standard UNIX cat
command can be used to display the contents of a sequential data set as follows.
$ cat "//'USER.LLQ.DATASET1'"
Hello World!
The standard UNIX
head
andtail
commands can be used in the same exact way.
$ head "//'USER.LLQ.DATASET1'"
Hello World!
$ tail "//'USER.LLQ.DATASET1'"
Hello World!
The standard UNIX
more
command must be used with DSFS (Data Set File System) notation instead. The/user
folder name corresponds to the High Level QualifierUSER
and the/llq.dataset1
file name coresponds to the low level qualfiersLLQ.DATASET1
.
$ more /dsfs/txt/user/llq.dataset1
Display The Contents of a Partitioned Data Set Member
The standard UNIX cat
command can be used to display the contents of a partitioned data set member as follows.
$ cat "//'USER.LLQ.DATASET2(MEMBER1)'"
Hello World!
The standard UNIX
head
andtail
commands can be used in the same exact way.
$ head "//'USER.LLQ.DATASET2(MEMBER1)'"
Hello World!
$ tail "//'USER.LLQ.DATASET2(MEMBER1)'"
Hello World!
The standard UNIX
more
command must be used with DSFS (Data Set File System) notation instead. The/user
folder name corresponds to the High Level QualifierUSER
, the/llq.dataset2
folder name coresponds to the low level qualfiersLLQ.DATASET2
, and the file name/member1
corresponds to the member nameMEMBER1
.
$ more /dsfs/txt/user/llq.dataset2/member1
Compare Data Sets (Requires ZOAU)
The ddiff
command can be used to show the difference between two data sets. Note that ddiff
only works when comparing plain text data.
Compare a Sequential Data Set to a Sequential Data Set
$ ddiff USER.LLQ.SEQ USER.LLQ.LARGE
NEW: USER.LLQ.LARGE OLD: USER.LLQ.SEQ
LISTING OUTPUT SECTION (LINE COMPARE)
ID SOURCE LINES TYPE LEN N-LN# O-LN#
I - New Message. RPL= 1 00001 00001
D - Old Message.
Compare a Data Set Member to a Partitioned Data Set Member
$ ddiff 'USER.LLQ.PDS(MEMBER1)' 'USER.LLQ.PDSE(MEMBER1)'
NEW: USER.LLQ.PDSE(MEMBER1) OLD: USER.LLQ.PDS(MEMBER1)
LISTING OUTPUT SECTION (LINE COMPARE)
ID SOURCE LINES TYPE LEN N-LN# O-LN#
I - New Message. RPL= 1 00001 00001
D - Old Message.
Compare a Sequential Data Set to a Partitioned Data Set Member
$ ddiff USER.LLQ.SEQ 'USER.LLQ.PDS(MEMBER1)'
NEW: USER.LLQ.PDS(MEMBER1) OLD: USER.LLQ.SEQ
LISTING OUTPUT SECTION (LINE COMPARE)
ID SOURCE LINES TYPE LEN N-LN# O-LN#
I - New Message. RPL= 1 00001 00001
D - Old Message.
Compare a Partitioned Data Set Member to a Sequential Data Set
$ ddiff 'USER.LLQ.PDS(MEMBER1)' USER.LLQ.SEQ
NEW: USER.LLQ.SEQ OLD: USER.LLQ.PDS(MEMBER1)
LISTING OUTPUT SECTION (LINE COMPARE)
ID SOURCE LINES TYPE LEN N-LN# O-LN#
I - New Message. RPL= 1 00001 00001
D - Old Message.
Allocate a Data Set (Requires ZOAU)
The dtouch
command is the functional equivalent of the standard UNIX touch
command for data sets. The following example allocates a FB (Fixed Blocked) PDSE data set with a logical record length of 80 and a 1MB primary extent.
Explaining how all of the data set attributes work is beyond the scope of this reference. For more details on data sets, see What is a data set?.
$ dtouch -t PDSE -r FB -l 80 -s 1MB USER.LLQ.NEW
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
USER.LLQ.NEW
You may also optionally use the
tsocmd
command to run the TSO (Time Sharing Option)ALLOCATE
command to allocate a data set instead. The main difference with this example is that it uses tracks as the unit for defining the primary extent instead of megabytes. Also note thatdsntype(library,2)
is used to indicate that the data set being allocated should be a PDSE. See Quick reference: Data set structure for more information on tracks and cylinders as a unit for measuring and allocating disk space.
$ tsocmd "allocate dsname('USER.LLQ.NEW'),dsorg(po),dsntype(library,2),recfm(f,b),lrecl(80),unit(3390),space(100) TRACK"
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
USER.LLQ.NEW
Create a New Partitioned Data Set Member (Requires ZOAU)
The following example uses the decho
command to create an empty data set member.
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
MEMBER3
$ decho '' 'USER.LLQ.DATASET2(NEW)'
$ mls USER.LLQ.DATASET2
MEMBER1
MEMBER2
MEMBER3
NEW
Echo Text to a Sequential Data Set (Requires ZOAU)
The following example uses the decho
command to echo text to a sequential data set.
$ cat "//'USER.LLQ.SEQ'"
Old message.
$ decho 'New message.' USER.LLQ.SEQ
$ cat "//'USER.LLQ.SEQ'"
New message.
Echo Text to a Partitioned Data Set Member (Requires ZOAU)
The following example uses the decho
command to echo text to a partitioned data set member.
$ cat "//'USER.LLQ.PDS(MEMBER1)'"
Old message.
$ decho 'New message.' 'USER.LLQ.PDS(MEMBER1)'
$ cat "//'USER.LLQ.PDS(MEMBER1)'"
New message.
Create a New Partitioned Data Set Member Alias
The following example uses the tsocmd
command to run the TSO (Time Sharing Option) RENAME
command with positional arguments telling it to create an alias of partitioned data set member USER.LLQ.DATASET2(MEMBER1)
called ALIAS1
.
$ tsocmd "RENAME 'USER.LLQ.DATASET2(MEMBER1)' (ALIAS1) ALIAS"
RENAME 'USER.LLQ.DATASET2(MEMBER1)' (ALIAS1) ALIAS
$ tsocmd "LISTDS 'USER.LLQ.DATASET2' MEMBERS"
LISTDS 'USER.LLQ.DATASET2' MEMBERS
USER.LLQ.DATASET2
--RECFM-LRECL-BLKSIZE-DSORG
FBA 133 32718 PO
--VOLUMES--
VOL002
--MEMBERS--
MEMBER1 ALIAS(ALIAS1)
MEMBER2
MEMBER3
Use The vi Command Line Editor to Edit Data Sets
DSFS (Data Set File System) makes data sets look like UNIX files such that UNIX programs and utilities can interact with data sets in the same way they would with any UNIX file. This means that data sets can be edited with the vi
command line editor as an alternative to the ISPF editor.
Edit a Sequential Data Set
In this example, the sequential data set USER.LLQ.SEQ
is being opened with the vi
command line editor. The highest level qualifier USER
corresponds to the the subfolder /user
and the low level qualifiers LLQ.SEQ
correspond to the file name /llq.seq
.
$ vi /dsfs/txt/user/llq.seq
If a port of vim
is installed on the system, you may also edit a sequential data set using vim
in the exact same way.
$ vim /dsfs/txt/user/llq.seq
Other UNIX-based command line editors should be able to be used the same way using DSFS (Data Set File System) notation.
Edit a Partitioned Data Set Member
In this example, the partitioned data set member USER.LLQ.PDS(MEMBER1)
is being opened with the vi
command line editor. The highest level qualifier USER
corresponds to the the subfolder /user
, the low level qualifiers LLQ.PDS
correspond to the subfolder /llq.pds
, and the member name MEMBER1
corresponds to the file name /member1
.
$ vi /dsfs/txt/user/llq.pds/member1
If a port of vim
is installed on the system, you may also edit a sequential data set using vim
in the exact same way.
$ vim /dsfs/txt/user/llq.pds/member1
Other UNIX-based command line editors should be able to be used the same way using DSFS (Data Set File System) notation.
Move Data Between z/OS Unix System Services and MVS
The following examples show how the z/OS UNIX System Services cp
command can be used copy data from data sets to the z/OS Unix System Services filesystem and vice versa.
Copy Modes:
- Plain Text:
- Use the
-T
flag to copy plain text data.
- Use the
- Binary:
- Use the
-B
flag to copy binary data.
- Use the
- Executable:
- Use the
-AIX
flag to copy Link Edited Program/Load Module data.
- Use the
The
-AIX
flag also preserves aliases.
- Auto:
- Use the
-A
flag to allow binary and plain text data to be automatically detected to enable the decision of whether to use the Plain Text copy mode or the Binary copy mode to be determined automatically.
- Use the
The
-A
flag should NOT be used with Link Edited Program/Load Module data. Also be aware that plain text data should contain NO null bytes or any bytes that do NOT map to the codec being used by MVS for data sets.
The following examples use the -T
to copy plain text data. The same actions can be performed using the other Copy Modes described above.
Copy The Contents of a Sequential Data Set to a UNIX File
$ cp -T "//'USER.LLQ.DATASET1'" hello.txt
Copy The Contents of a UNIX File to a Sequential Data Set
$ cp -T hello.txt "//'USER.LLQ.DATASET1'"
Copy The Contents of a Partitioned Data Set Member to a UNIX File
$ cp -T "//'USER.LLQ.DATASET2(MEMBER1)'" hello.txt
Copy The Contents of a UNIX File to a Partitioned Data Set Member
$ cp -T hello.txt "//'USER.LLQ.DATASET2(MEMBER1)'"
Copy All Members From a Partitioned Data Set to a UNIX Folder
$ cp -T "//'USER.LLQ.DATASET2'" folder/
Copy All Files in a UNIX Folder to a Partitioned Data Set
$ cp -T folder/* "//'USER.LLQ.DATASET2'"
Migrate an SMS-Managed Data Set
The following example using the tsocmd
command to run the TSO (Time Sharing Option) HMIGRATE
command which tells DFSMShsm to migrate a data set from DASD to tape.
The data set being migrated MUST be SMS-managed and DFSMShsm MUST be active in order for the
HMIGRATE
command to work.
HMIGRATE
is asynchronous. You will NOT get any return codes or feedback indicating whether or not the request was successful. You need to verify thatHMIGRATE
migrated the data set you requested yourself afterwards.
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
$ tsocmd "HMIGRATE 'USER.LLQ.DATASET1'"
HMIGRATE 'USER.LLQ.DATASET1'
MIGRATE REQUEST XXXXXXXX SENT TO DFSMSHSM
$ dls USER.LLQ.*
USER.LLQ.DATASET2
USER.LLQ.DATASET3
Recall an SMS-Managed Data Set
The following example uses the tsocmd
command to run the TSO (Time Sharing Option) HRECALL
command which tells DFSMShsm to recall a migrated data set back to DASD.
The data set being recalled MUST be SMS-managed and DFSMShsm MUST be active in order for the
HRECALL
command to work.
HRECALL
is asynchronous. You will NOT get any return codes or feedback indicating whether or not the request was successful. You need to verify thatHRECALL
recalled the data set you requested yourself afterwards.
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
$ tsocmd "HRECALL 'USER.LLQ.MIGRATED'"
HRECALL 'USER.LLQ.MIGRATED'
RECALL REQUEST XXXXXXXX SENT TO DFSMSHSM
$ dls USER.LLQ.*
USER.LLQ.DATASET1
USER.LLQ.DATASET2
USER.LLQ.DATASET3
USER.LLQ.MIGRATED
Convert a PDS Data Set to a PDSE (Requires ZOAU)
The following example uses the mvscmdauth
command and the DFSMSdss utility ADRDSSU
to convert the PDS data set USER.LLQ.PDS
to a PDSE data set named USER.LLQ.PDSE
.
The DS(INC(USER.LLQ.PDS))
statement tells ADRDSSU
that USER.LLQ.PDS
is the source data set. The CONVERT (PDSE(**))
statement tells ADRDSSU
that the target data set should be converted to a PDSE data set. The RENUC
statement tells ADRDSSU
to copy the source data set USER.LLQ.PDS
to the target data set USER.LLQ.PDSE
.
$ mvscmdauth --pgm=ADRDSSU \
--sysprint=stdout \
--sysin=stdin <<zz
COPY -
DS(INC(USER.LLQ.PDS)) -
CONVERT (PDSE(**)) -
RENUNC ( -
USER.LLQ.PDS, -
USER.LLQ.PDSE)
zz
Convert a PDSE Data Set to a PDS (Requires ZOAU)
The following example uses the mvscmdauth
command and the DFSMSdss utility ADRDSSU
to convert the PDSE data set USER.LLQ.PDSE
to a PDS data set named USER.LLQ.PDS
.
The DS(INC(USER.LLQ.PDSE))
statement tells ADRDSSU
that USER.LLQ.PDSE
is the source data set. The CONVERT (PDS(**))
statement tells ADRDSSU
that the target data set should be converted to a PDS data set. The RENUC
statement tells ADRDSSU
to copy the source data set USER.LLQ.PDSE
to the target data set USER.LLQ.PDS
.
$ mvscmdauth --pgm=ADRDSSU \
--sysprint=stdout \
--sysin=stdin <<zz
COPY -
DS(INC(USER.LLQ.PDSE)) -
CONVERT (PDS(**)) -
RENUNC ( -
USER.LLQ.PDSE, -
USER.LLQ.PDS)
zz
One to One Copy (Requires ZOAU)
The following examples use the mvscmd
command and the DFSMSdfp utility IEBGENER
to copy sequential data from one data set to another. The sysut1
data definition represents the source and the sysut2
data definition represents the target.
The record length and record format of both
sysut1
andsysut2
should be the same. For example, you CANNOT copy sequential data from a fixed blocked 133 source to a fixed block 80 target and vice versa.
dummy
is analogous to/dev/null
.
Copy The Contents of a Sequential Data Set to Another Sequential Data Set
$ mvscmd --pgm=IEBGENER \
--sysin=dummy \
--sysprint=stdout \
--sysut1=USER.FB80.LARGE \
--sysut2=USER.FB80.SEQ
Copy The Contents of a Partitioned Data Set Member to Another Partitioned Data Set Member
$ mvscmd --pgm=IEBGENER \
--sysin=dummy \
--sysprint=stdout \
--sysut1='USER.FB80.PDSE(MEMBER1)' \
--sysut2='USER.FB80.PDS(MEMBER1)'
Copy The Contents of a Sequential Data Set to a Partitioned Data Set Member
$ mvscmd --pgm=IEBGENER \
--sysin=dummy \
--sysprint=stdout \
--sysut1=USER.FB80.SEQ \
--sysut2='USER.FB80.PDS(MEMBER1)'
Copy The Contents of a Partitioned Data Set Member to a Sequential Data Set
$ mvscmd --pgm=IEBGENER \
--sysin=dummy \
--sysprint=stdout \
--sysut1='USER.FB80.PDS(MEMBER1)' \
--sysut2=USER.FB80.SEQ
Clone A Data Set (Requires ZOAU)
The following example uses the mvscmdauth
command and the DFSMSdss utility ADRDSSU
to clone data set USER.LLQ.DATASET2
to a new data set named USER.LLQ.CLONE
.
The DS(INC(USER.LLQ.PDS))
statement tells ADRDSSU
that USER.LLQ.DATASET2
is the source data set. The RENUC
statement tells ADRDSSU
to copy the source data set USER.LLQ.DATASET2
to the target data set USER.LLQ.CLONE
.
$ mvscmdauth --pgm=ADRDSSU \
--sysprint=stdout \
--sysin=stdin <<zz
COPY -
DS(INC(USER.LLQ.DATASET2)) -
RENUNC ( -
USER.LLQ.DATASET2, -
USER.LLQ.CLONE)
zz
Clone Several Data Sets Based on A Pattern (Requires ZOAU)
The following example uses the mvscmdauth
command and the DFSMSdss utility ADRDSSU
to clone all data sets that match the pattern USER.LLQ.**
to new data sets with the naming convention USER.CLONE.**
.
The DS(INC(USER.LLQ.**))
statement tells ADRDSSU
that all data sets that match the pattern USER.LLQ.**
are the source data sets. The RENUC
statement tells ADRDSSU
to copy the source data sets from USER.LLQ.**
to target data sets with the naming convention USER.CLONE.**
.
$ mvscmdauth --pgm=ADRDSSU \
--sysprint=stdout \
--sysin=stdin <<zz
COPY -
DS(INC(USER.LLQ.**)) -
RENUNC ( -
USER.LLQ.**, -
USER.CLONE.**)
zz
Copy and Merge Partitioned Data Sets (Requires ZOAU)
The following example uses the mvscmd
command and DFSMSdfp utility IEBCOPY
to copy and merge all of the partitioned data set members from USER.LLQ.FROM
into partitioned data set USER.LLQ.TO
.
The COPYGROUP INDD=IN,OUTDD=OUT
statement tells IEBCOPY
that the source data set is the in
data definition (USER.LLQ.FROM
) and the target data set is the out
data definition (USER.LLQ.TO
).
$ mvscmd --pgm=IEBCOPY \
--sysprint=stdout \
--in=USER.LLQ.FROM \
--out=USER.LLQ.TO \
--sysin=stdin <<zz
COPYGROUP INDD=IN,OUTDD=OUT
zz
Copy and Merge Partitioned Data Sets and Include Aliases (Requires ZOAU)
The following example uses the mvscmd
command and the DFSMSdfp utility IEBCOPY
to copy and merge all of the partitioned data set members and aliases from USER.LLQ.FROM
into partitioned data set USER.LLQ.TO
.
The COPYGROUP INDD=((IN,R)),OUTDD=OUT
statement tells IEBCOPY
that the source data set is the in
data definition (USER.LLQ.FROM
) and the target data set in the out
data definiton (USER.LLQ.TO
).
The thing that enables aliases to be preserved is is the INDD=((IN,R))
portion of the COPYGROUP
statement which tells IEBCOPY
to also copy and merge the aliases in the source data set (USER.LLQ.TO
) into the target data set (USER.LLQ.TO
).
$ mvscmd --pgm=IEBCOPY \
--sysprint=stdout \
--in=USER.LLQ.FROM \
--out=USER.LLQ.TO \
--sysin=stdin <<zz
COPYGROUP INDD=((IN,R)),OUTDD=OUT
zz
Copy and Merge Partitioned Data Sets and Filter Members (Requires ZOAU)
The following example uses the mvscmd
and and the DFSMSdfp utility IEBCOPY
to copy and merge only a subset of the partitioned data set members from USER.LLQ.FROM
into partitioned data set USER.LLQ.TO
.
The COPYGROUP INDD=IN,OUTDD=OUT
statement tells IEBCOPY
that the source data set is the in
data definition (USER.LLQ.FROM
) and the target data set is the out
data definition (USER.LLQ.TO
).
The SELECT MEMBER=
statement is what tells IBECOPY
to filter the the partitioned data set members being copied from the source. This example uses a comma separated list of member names to specify a subset of partitioned data set members that should be copied and merged from the source into the target.
$ mvscmd --pgm=IEBCOPY \
--sysprint=stdout \
--in=USER.LLQ.FROM \
--out=USER.LLQ.TO \
--sysin=stdin <<zz
COPYGROUP INDD=IN,OUTDD=OUT
SELECT MEMBER=(MEMBER1,MEMBER2,MEMBER3)
zz
Wildcarding is also supported when using the
SELECT MEMBER=
statement withIEBCOPY
. The following example will copy and merge all partitioned data set members that match the naming conventionMEMBER*
andA*
fromUSER.LLQ.FROM
intoUSER.LLQ.TO
.
$ mvscmd --pgm=IEBCOPY \
--sysprint=stdout \
--in=USER.LLQ.FROM \
--out=USER.LLQ.TO \
--sysin=stdin <<zz
COPYGROUP INDD=IN,OUTDD=OUT
SELECT MEMBER=(MEMBER*,A*)
zz
If you need to specify a large amount of partitioned data set member patterns, you can use multiple
SELECT MEMBER=
statements.
$ mvscmd --pgm=IEBCOPY \
--sysprint=stdout \
--in=USER.LLQ.FROM \
--out=USER.LLQ.TO \
--sysin=stdin <<zz
COPYGROUP INDD=IN,OUTDD=OUT
SELECT MEMBER=(MEMBER1,MEMBER2,MEMBER3,MEMBER4)
SELECT MEMBER=(MEMBER5,MEMBER6,MEMBER7,MEMBER8)
zz
Display The Directory Information For a Partitioned Data Set (Requires ZOAU)
The following example uses the mvscmd
command and the DFSMSdfp utility IEHLIST
to extract and print the directory information of partitioned data set USER.LLQ.DATASET2
. The LISTPDS
statement describes the function that IEHLIST
will perform. The VOL=3390=VOL001
statement tells IEHLIST
that the data set being worked with resides on a 3390 DASD (Direct Access Storage) device and that the volume serial of that device is VOL002
. The DSNAME=USER.LLQ.DATASET2
statement tells IEHLIST
to use the USER.LLQ.DATASET2
data set.
The volume serial of the DASD volume that the data set resides on is required. In this example, the volume serial
VOL002
is the the volume that the data setUSER.LLQ.DATASET2
resides on.
The capital letter
X
on column 72 tellsIEHLIST
that there is more information on the next line. TheX
also MUST be on column 72.
$ mvscmd --pgm=IEHLIST \
--sysprint=stdout \
--dd1=USER.LLQ.DATASET2,shr,volumes=VOL002 \
--sysin=stdin <<zz
LISTPDS VOL=3390=VOL002,FORMAT, X
DSNAME=USER.LLQ.DATASET2
zz
Working with JES
Though it is often beneficial and even essential to keep work in the foreground so that it can be easily driven though CI/CD tools and open programming languages, it would be remiss to not consider how use of JES Job Entry Subsystem is to submit work asynchronously in batch is hugely significant. Therefore, the following examples show how users can submit JCL jobs and interact with resources that would otherwise require the use of SDSF panels from z/OS Unix System Services instead.
Submit a JCL Job From a Sequential Data Set (Requires ZOAU)
The following example uses the jsub
command to submit a JCL job from the sequential data set USER.LLQ.JCL
. The JOBID assigned by JES (Job Entry Subsystem) is printed to the console. In this example, a JOBID of JOB00002
is assigned to the submitted job.
$ jsub USER.LLQ.JCL
JOB00002
Submit a JCL Job From a Partitioned Data Set Member (Requires ZOAU)
The following example uses the jsub
command to submit a JCL job from the partitioned data set member USER.LLQ.JCL(JOB)
. The JOBID assigned by JES (Job Entry Subsystem) is printed to the console. In this example, a JOBID of JOB00002
is assigned to the submitted job.
$ jsub 'USER.LLQ.JCL(JOB)'
JOB00002
Submit a JCL Job From a UNIX File (Requires ZOAU)
The following example uses the jsub
command to submit a JCL job from the UNIX file /u/user/job.jcl
. The JOBID assigned by JES (Job Entry Subsystem) is printed to the console. In this example, a JOBID of JOB00002
is assigned to the submitted job.
$ jusb -f /u/user/job.jcl
JOB00002
Cancel a Running JCL Job (Requires ZOAU)
The following example uses the jcan
command to cancel a running JCL job with a job name of JOB2
and a JOBID of JOB00002
.
$ jcan C JOB2 JOB00002
Cancel and Purge a JCL Job (Requires ZOAU)
The following example uses the jcan
command to cancel and purge (delete) a JCL job with a job name of JOB2
and a JOBID of JOB00002
.
Additional authorization is required to use the purge option.
$ jcan P JOB2 JOB00002
Get a Listing of JCL Jobs (Requires ZOAU)
The following example uses the jls
command to get a listing of JCL jobs that are owned by the userid USER
.
$ jls /USER
USER JOB1 JOB00001 CC 0000
USER JOB2 JOB00002 CC 0000
Display The Data Definitons Allocated to a JCL Job (Requires ZOAU)
The following examples uses the ddls
command to list all of data defininions associated with a JCL job with a JOBID of JOB00002
.
$ ddls JOB00002
JES2 - JESMSGLG UA 133 23 2
JES2 - JESJCL V 136 4 3
JES2 - JESYSMSG VA 137 20 4
CLONE - SYSPRINT VBA 137 26 102
Display The JCL Used By a Submitted JCL Job (Requires ZOAU)
The following example uses the pjdd
command to display the JESJCL
data definition which contains the JCL used by the JCL job with a JOBID of JOB00002
.
$ pjdd JOB00002 JESJCL
1 //JOB2 JOB JOB00002
2 //CLONE EXEC PGM=ADRDSSU,REGION=0K
3 //SYSPRINT DD SYSOUT=A
4 //SYSIN DD *
Display The Output Produced by a JCL Job (Requires ZOAU)
The following example uses the pjdd
commad to display the SYSPRINT
data definition which contains the output produced by the JCL job with a JOBID of JOB00002
.
$ pjdd JOB00002 SYSPRINT
...
Convert JCL Job Steps to mvscmd Commands (Requires ZOAU)
The following JCL job runs one job step named CLONE
that uses the DFSMSdss utility ADRDSSU
to clone a data set. The CLONE
job step specifies a SYSPRINT
data definition of SYSOUT=A
and a SYSIN
data definition of *
where all of the code on the lines following the SYSIN
data definition gets used by the SYSIN
data definition.
//CLONEJOB JOB
//CLONE EXEC PGM=ADRDSSU,REGION=0K
//SYSPRINT DD SYSOUT=A
//SYSIN DD *
COPY -
DS(INC(USER.LLQ.DATASET2)) -
RENUNC ( -
USER.LLQ.DATASET2, -
USER.LLQ.CLONE)
JCL is a batch oriented language meaning that JCL is intened to be scheduled and run asynchronously in batch. However, there is a myriad of powerful and even essential utilities that are JCL oriented that would provide a huge amount of value and ease of use if we were able to run these utilities in the foreground in the z/OS UNIX System Services environment.
The following example is a conversion of the JCL above to an mvscmdauth
command that can be run directly in the z/OS UNIX System Services environement in the foreground. The SYSPRINT
data definition is changed to UNIX stdout
and the SYSIN
data definition is changed to UNIX stdin
where the zz
block tells z/OS UNIX System Serivces to treat the contained code which is identical to the code used in the JCL above as stdin
.
The
mvscmd
command can be used in place ofmvscmdauth
to run programs that are NOT APF (Authorized Program Facility) authorized.
$ mvscmdauth --pgm=ADRDSSU \
--sysprint=stdout \
--sysin=stdin <<zz
COPY -
DS(INC(USER.LLQ.DATASET2)) -
RENUNC ( -
USER.LLQ.DATASET2, -
USER.LLQ.CLONE)
zz
Running TSO Commands From z/OS UNIX System Services
Most TSO commands that DON’T invoke a panel application can be used from z/OS UNIX System Services using the tsocmd
command and the tso
command. The tsocmd
command is functionally the same as the tso
command, but the tsocmd
command can execute APF (Authorized Program Facility) authorized programs.
$ tsocmd "HELP"
HELP
LANGUAGE PROCESSING COMMANDS:
...
$ tso "HELP"
HELP
LANGUAGE PROCESSING COMMANDS:
...
Here is an example that executes an executable stored in a partitioned data set member.
$ tso "CALL 'USER.LLQ.DATASET3(MAIN)'"