A long time ago I wrote blog posts about driving Unix System Services from REXX. My motivation at the time was relatively minor. Now, however, I have a stronger motivation: Python.
You might or might not be aware that z/OS has modern Python support – and I expect it to keep up very well as Python evolves.
For reference, here are the three blog posts from long ago. Probably best to read them first – as it’ll make the code explanation a lot easier.
- BPXWUNIX – z/OS’ Best Kept Secret?
- Filtering REXX Query Results With BPXWUNIX
- TSO Regular Expression Testing Tool
REXX vs Python
In a world where modern languages have become available REXX still has an important place: REXX supports external function packages. I use two of them – SLR and GDDM. I don’t expect to stop using either of them any time soon – as my toolchain relies on them.
Python, however, has a couple of advantages to me:
- It enables data structures to be expressed and manipulated more easily. For example, dictionaries.
- It has access to other capabilities – such as the CSV package.
I could add a third: People know Python. That’s not hugely relevant to me personally, though I’ve written a lot of Python over recent years and indeed have several open source projects written in it.
REXX Invoking Python
Here is a simple example.
It consists of two parts:
- A driving REXX exec.
- A driven Python program.
Here’s the REXX.
/* REXX */
python = "/shared/IBM/cyp/v3r12/pyz/bin/python3"
stdin.0 = 1
stdin.1 = python "python/test.py fred"
cmd = "/bin/sh"
call bpxwunix cmd,stdin.,stdout.,stderr.
interpret stdout.1
say "x=" x
say
Here’s the Python
import sys
print(f"x='{sys.argv[1]}'")
Problems Still To Solve
It would be better if my python code were inline – or at least in a member in my REXX library. That would make backing it up easier, for example.
I could go for (“heredoc”) inline code but that would involve storing the program inside a REXX string in the REXX code itself. That would get messy.
When I tried to pass code interactively to Python it complained it wasn’t UTF-8. It isn’t; It’s EBCDIC. A little taming required, I think.
The example uses interpret – which isn’t clever; That’s an easy problem to solve; You just use a sensible stem variable name for stdout.
It also occurs to me this could be structured so it looks more like Python driving REXX than it currently does today.
Anyhow, I’ll keep experimenting – once I find a real use case. I’m not planning on wholesale refactoring my current REXX code just to introduce some Pythonisms. Real world code has to earn its keep.
Meanwhile I’m continuing to write Python at a rate of knots – on my Mac.