It can sometimes be useful to run git commands in batch from JCL. This turns out to be a bit tricky; here’s an approach that works for me. I would be interested in hearing about other approaches.
The key documentation for this is UNIX System Services User’s Guide: The BPXBATCH utility. There are several issues that make this challenging:
- There are some unpleasant restrictions on the handling of the standard I/O streams,
stdin/stdout/stderr
:
- All three standard I/O streams are, by default, directed to
/dev/null
.
-
stdin
cannot be directed to an MVS dataset. It may be directed to a file in the USS file system.
-
stdout
and stderr
may be directed to MVS datasets, but you have to be careful about the DCB characteristics.
- The command to be executed is passed to
BPXBATCH
via the PARM
option on the EXEC
statement; this is limited to a maximum length of 100 characters.
My JCL for running BPXBATCH
looks like this:
//STEP1 EXEC PGM=BPXBATCH
//STDOUT DD SYSOUT=*
//STDPARM DD *
SH command_to_run ...
/*
The STDPARM DD
statement replaces the PARM=
option on the EXEC
statement and increases the length of the parameter string to abount 32K. By removing the command line from the EXEC
statement, it also makes the JCL easier to read.
If only STDOUT
is allocated, both of the stdout
and stderr
streams will be sent to the same MVS dataset. This is handy because it blends the two streams together in order, much as they are when running a shell from the command line. If you want the two streams separated, you can provide a DD statement for STDERR
as well.
So that’s the actual JCL, but what should the STDPARM
dataset look like? Here’s an example:
//STEP1 EXEC PGM=BPXBATCH
//STDOUT DD SYSOUT=*
//STDPARM DD *
SH /rsusr/ported/bin/bash -c '
export USER=TSJLC ;
export _BPXK_AUTOCVT=ON ;
export _CEE_RUNOPTS="FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)" ;
export _TAG_REDIR_ERR=txt ;
export _TAG_REDIR_IN=txt ;
export _TAG_REDIR_OUT=txt ;
export _BPXK_JOBLOG=STDERR ;
export _EDC_ADD_ERRNO2=1 ;
export PATH=/rsusr/ported/bin:/bin ;
export LIBPATH=/rsusr/ported/lib:/usr/lib ;
set -x ;
git clone git@github.com:zorts/hello_world.git ;
cd hello_world ;
git status ;
git remote -v ;
'
/*
I’ll explain this section by section.
SH /rsusr/ported/bin/bash -c '
This executes the bash
shell; the path to bash
will depend on where you installed it. The -c
command line option causes bash
to execute the argument of -c
as a command. Note that the last character on that line is a single quote; this starts the command to be run, and the closing quote is at the very end of the input stream.
Following this first line are the commands to be executed. Note that, as far as bash
is concerned, these commands are all on a single “line” (because they are just the argument to the -c
option). This means that:
- each command must be terminated with a semicolon, and
- you must not try to use comments in this stream! The first hash character (
#
) will cause all the remaining input to be treated as comment.
The next chunk of lines sets up the environment for git
:
export USER=TSJLC ;
export _BPXK_AUTOCVT=ON ;
export _CEE_RUNOPTS="FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)" ;
export _TAG_REDIR_ERR=txt ;
export _TAG_REDIR_IN=txt ;
export _TAG_REDIR_OUT=txt ;
export _BPXK_JOBLOG=STDERR ;
export _EDC_ADD_ERRNO2=1 ;
export PATH=/rsusr/ported/bin:/bin ;
export LIBPATH=/rsusr/ported/lib:/usr/lib ;
There’s no reason these couldn’t be put into a USS file and then sourced (using the .
command), which will make this job stream less verbose. However, providing the setup in the job stream makes it very obvious what’s being done.
This command:
set -x ;
turns on bash
's debugging mode, causing it to display every command it’s about to execute. This isn’t strictly necessary, but it make debugging a bit easier.
Finally, we get to the actual git
commands:
git clone git@github.com:zorts/hello_world.git ;
cd hello_world ;
git status ;
git remote -v ;
'
Note that final closing single quote!
Assuming you have already installed git for z/OS and set up GitHub to be used from z/OS, you could run the JCL above unmodified and it should work.