3

I'm going to describe my issue as well as possible.

I know in advance that is is possible to type a z/OS shell UNIX command that does not fit on one line using a backslash at the end of the first line. In fact I've tested it in the computer I'm working with and executes well.

For example; in order to do a test I've type ls command as follows:

Firstly without backslash from the command line:

ls -la

After with backslash also from the command line:

ls\
 -la

I get the same good results

What I would like to know is how to do the same in a z/OS UNIX shell script in STDIN executed with BPXBATCH.

If I put the command as follows ls -la it executes well; but If I try to break it in two lines it does not work.

May anyone shed light in this issue?.

Many thaks in advance

(Obvioulsy ls -la is a very simple example only intended to show the problem I'm facing; real commands are much more larger)

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Sorry; the example command ls\ -la spans two lines; the first line till the backslash. The second line has a blank space plus -la – FRANCESC XAVIER DALMAU PUJOL May 15 '18 at 16:16
  • In your post above the '\' is the last charater on the line (OK). When it did not work, did you put a space after de backslash? In that case the bashslash will work on the space, not on the '\n'. – Walter A May 15 '18 at 18:45

4 Answers4

8

I'll take a stab at this. Using BPXBATCH, you want to issue a shell command. Here would be a simple example:

//TSTRADMB  JOB  MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID,REGION=0M
//BPXIT EXEC PGM=BPXBATCH,PARM='SH ls -l'
//BPXPRINT DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*

This has the desired effect of writing the output of the shell command ls -l to stdout. But - what if it's a much longer string? Two ways you could go. One would be to write a wrapper script and call it from BPXBATCH (which is what I would do). The other would be to put the PARM across multiple lines, in which case you need to follow JCL rules for continuation (using a + in column 72 works), e.g.

//TSTRADMB  JOB  MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID,REGION=0M
//BPXIT EXEC PGM=BPXBATCH,PARM='SH ls -l "/u/tstradm/ThisIsAReallyLongD+
//             irectoryThatCrossesMultipleLines"'
//BPXPRINT DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*

The spacing with JCL is truly annoying - so you have to get it right. That + sign has to be in column 72 or you get a JCL error. The start of the next line of text begins in column 16. Start it late and you end up with blanks (which in this case would make a difference).

mike
  • 819
  • 4
  • 14
6

To pass long commands to BPXBATCH, use the STDPARM DD.

While it is possible to pass relatively long commands to BPXBATCH via the PARM parameter on the JCL EXEC statement by using JCL continuation rules, this method is still limited to 100 bytes.

A parameter file passed to BPXBATCH via STDPARM supports parameters (i.e the command) up to 64K in length. The parameter file can be a z/OS-Unix file, a traditional z/OS dataset, or in-stream in the JCL.

For example, place a long command (this sample command is 105 bytes):

SH ls -altr /listed_environments/cics/test/pickup/webs/test-portal-v01/src/assets/mixins | grep functions

into a z/OS-Unix file at /u/userid/stdparmfile

Then execute the command via BPXBATCH by utilizing STDPARM (PATHOPTS must be set to ORDONLY):

//USSCMD EXEC PGM=BPXBATCH
//STDERR  DD SYSOUT=*
//STDOUT  DD SYSOUT=*
//STDPARM DD PATH='/u/userid/stdparmfile',PATHOPTS=ORDONLY
/*
//

Or place the same command into a traditional z/OS dataset (with a sufficient LRECL). Ensure that sequence numbers are removed from the dataset by issuing UNNUM and/or NUMBER OFF while in ISPF EDIT. Then similarly submit through JCL:

//USSCMD EXEC PGM=BPXBATCH
//STDERR  DD SYSOUT=*
//STDOUT  DD SYSOUT=*
//STDPARM DD DISP=SHR,DSN=USERID.STDPARM.TEST
/*
//

In-stream submission on the STDPARM DD is a bit more restrictive, as a space character is assumed on each line-end. An in-stream command should be fine if it can be broken apart on space-char boundaries to fit within the 80-byte limit for JCL. The sample command we've used here would work like this:

//USSCMD EXEC PGM=BPXBATCH
//STDERR  DD SYSOUT=*
//STDOUT  DD SYSOUT=*
//STDPARM DD *
SH ls -altr
/listed_environments/cics/test/pickup/webs/test-portal-v01/src/assets/mixins
| grep functions
/*
//

But, a command that includes an uninterrupted string of text >80 bytes would likely present challenges for in-stream.

The z/OS 2.3 documentation for STDPARM can be found here: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxa400/batstdparm.htm

Rich Jackson
  • 301
  • 1
  • 5
  • 1
    Many thanks Rich; I've been very busy these last weeks and till today I haven't been able to read and check carefully your answer. I've tested every part of your response and all works as expected. – FRANCESC XAVIER DALMAU PUJOL Aug 14 '18 at 12:47
1

In BPXBATCH, you actually want to use '+' as your continuation character for STDIN. BPXBATCH is a TSO command processor so it uses the TSO continuation character and not USS'

Richard Tran
  • 438
  • 3
  • 10
  • It appears that for some reason PBXBATCH does not honor the continuation characters and includes "+" and "-" into the commands. But you can just break lines and it will lump all lines together into one anyway. – Terminality Jun 03 '23 at 09:04
0

Coming a bit late to the party, but PBXBATCH just concatenates multiple lines into one. In your case it could look like:

//PBXTST   JOB ,MSGLEVEL=(2,0),NOTIFY=&SYSUID.
//DOIT     EXEC PGM=BPXBATCH
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//STDPARM  DD *
SH 
ls
-a
/*

Just as a sample with multiple commands,often this would be multiple commands (note the semicolon):

//PBXTST   JOB ,MSGLEVEL=(2,0),NOTIFY=&SYSUID.
//DOIT     EXEC PGM=BPXBATCH
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//STDPARM  DD *
SH (
cd somedir;
ls -a
)
/* 

See this link for reference: https://bit.listserv.ibm-main.narkive.com/LphTazF4/multi-line-stdparm-shell-script-for-bpxbatch

Terminality
  • 799
  • 6
  • 11