Technical Blog Post
Abstract
How to Copy a File From C:D z/OS to C:D Windows Including the Path, Then Issue a Run Task to Execute a cmd() Command on Windows
Body
When doing a Run Task from z/OS to be executed on Windows, there are a few limitations which must be considered:
(1) Both the cmd() and arg() commands do not allow single quotes within the command string. For example, neither of the the following are valid:
SYSOPTS='cmd(move 'C:\path1\xxx\test1.txt' 'C:\path2\xxx\test2.txt')'
SYSOPTS="cmd(move 'C:\path1\xxx\test1.txt' 'C:\path2\xxx\test2.txt')"
This means if you define symbolics as the following:
&DSWRK='C:\path1\xxx\test1.txt'
&DSWIN='C:\path2\xxx\test2.txt' (that is, they include the single quotes)
These cannot be passed to the cmd() command, as single quotes are not allowed within the cmd() command.
(2) If single quotes are used on the SYSOPTS on the cmd() command, then symbolics cannot be passed to the SYSOPTS; anything within the single quotes will not be parsed or resolved. For example, the following:
SYSOPTS='cmd(move &DSWRK &DSWIN)'
will actually try to move a file named &DSWRK to &DSWIN, which will fail.
(3) If double quotes are used on the SYSOPTS on the cmd() command, then everything within the cmd() command will go through the parser. So any of the following:
SYSOPTS="cmd(move "C:\path1\xxx\test1.txt" "C:\path2\xxx\test2.txt")"
SYSOPTS="cmd(move C:\path1\xxx\test1.txt C:\path2\xxx\test2.txt)"
SYSOPTS="cmd(move ~"C:\path1\xxx\test1.txt~" ~"C:\path2\xxx\test2.txt~")"
will be parsed and result in the following that will be attempted to be executed (and result in a failure):
SYSOPTS="cmd(move "C: path1 xxx test1.txt" "C: path2 xxx test2.txt")"
SYSOPTS="cmd(move C: path1 xxx test1.txt C: path2 xxx test2.txt)"
SYSOPTS="cmd(move ~"C: path1 xxx test1.txt~" ~"C: path2 xxx test2.txt~")"
(that is, the backslashes have been removed).
This will be the same if you define the symbolics the same as above, only with double quotes instead of single quotes.
Therefore, symbolics can only be passed to a cmd() command on a Run Task to Windows if the symbolics do not contain single quotes and do not contain any characters that would be considered a delimiter in C:D z/OS, such as a backslash.
So what do you do when you want to have a batch job that calls a process that does a Run Task to issue a cmd() that contains path/filename(s) without having to alter the actual process each time?
The solution is to define and pass the entire SYSOPTS as a symbolic rather than pass symbolics into the SYSOPTS. The following is an example of how the DMBATCH job would be coded using the previous filenames; the process called will copy a file from z/OS to Windows, then if the COPY was successful, will issue a Run Task to issue the cmd(move) command to move the file from one folder to another folder:
DMBATCH job:
//SYSIN DD *
SIGNON USERID=(cduser) ESF=YES CASE=YES
SUBMIT PROC=CMDCOPY -
&DSNMVS=your_file_on_zos -
&DSWRK='C:\path1\test1.txt' -
&SYSO=\'CMD(MOVE \ -
|| -
\"C:\\path1\\xxx\\test1.txt" \ -
|| -
\"C:\\path2\\xxx\\test2.txt")'\ -
&JOBERRO=CMDCOPY
SIGNOFF
(it is very important that the sets of double backslashes are used - if only single backslashes are used, this will fail)
Process:
CMDCOPY PROCESS PNODE=zos_node SNODE=win_node
COPY01 COPY FROM(PNODE -
DSN=&DSNMVS -
DISP=SHR) -
TO(SNODE DSN=&DSWRK -
SYSOPTS="datatype(text)" -
DISP=RPL)
VER01 IF (COPY01=0) THEN
MOVEIN RUN TASK SNODE PGM=Windows -
SYSOPTS=&SYSO
EIF
[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SS4PJT","label":"IBM Sterling Connect:Direct"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]
UID
ibm11124013