I'm creating a python (3.13.5) program on my pc that connects to our mainframe and runs a python (3.12.8) program from our z/os uss environment.
I can successfully connect using this code here:
remote_script_path = '/u/h39808'
script = 'helloworld.py'
try:
with paramiko.SSHClient() as client:
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host_address,
username=username_entry.get(),
password=passowrd_entry.get())
And when I use the following invoke_shell method to run my python program remotely, it does so fine:
shell = client.invoke_shell()
shell.send(f"python {remote_script_path}/{script}\n")
But since all I am doing is executing one program at any time and waiting for a response, I'd like to do this with exec_command; problem is, when I use the following:
**stdin, stdout, stderr = client.exec_command(f"python {remote_script_path}/{script}")
print(stderr.read().decode())**
It returns - python: FSUM7351 not found
And let's say I try using a command to go to the remote path and list the contents:
stdin, stdout, stderr = client.exec_command(f"cd {remote_script_path}; ls -l")
This comes back, which is what I am expecting: -rwxrwxr-x 1 BPXROOT 99999999 59 Jun 24 14:28 helloworld.py
Could this be due to a security restriction, or something else off with our uss environment, or is it my code that is to blame?
The error:
python: FSUM7351 not found
means that the shell cannot find the python
command. This typically happens when:
The PATH
variable isn't set properly in non-interactive shells (like the one used by exec_command
).
exec_command
doesn’t invoke a full login shell, so it may skip profile scripts like .profile
, .bash_profile
, or .bashrc
(depending on shell type).
On USS (z/OS UNIX System Services), the profile that sets up Python paths may only be loaded in interactive shells, which is why your invoke_shell()
works but exec_command()
doesn’t.
Use the full path to Python
Find out the absolute path to Python on USS by running:
which python
from your working interactive shell (invoke_shell
). You might get something like:
/usr/lpp/python3/bin/python
Then change:
stdin, stdout, stderr = client.exec_command(f"python {remote_script_path}/{script}")
to:
stdin, stdout, stderr = client.exec_command(f"/usr/lpp/python3/bin/python {remote_script_path}/{script}")
This is the simplest and most robust solution.