1

I'm working on using the subprocess module to send shell commands from Python, specifically, ssh. Below is a barebones sample:

import subprocess

sp = subprocess.run(["ssh"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(f"stdout: {sp.stdout.decode()} \n\nstderr: {sp.stderr.decode()}")

This should return the ssh command help from stdout, and nothing from stderr. However, I get:

stdout:  

stderr: 'ssh' is not recognized as an internal or external command,
operable program or batch file.

I've tried other commands, like echo and cd, and those work fine. I am also able to use ssh when manually typing the command into the shell, but it fails when I try to do it through subprocess. The directory C:\Windows\System32\OpenSSH does exist on my computer (and it contains ssh.exe), but for some strange reason I'm unable to cd to it using subprocess.

If it matters, subprocess is using the command prompt, cmd.exe, as it seems to be the default.

Any help is appreciated. Thanks!

-- Edits with tests from comments --

  • Using the absolute path C:/Windows/System32/OpenSSH/ssh.exe does not work, and gives The system cannot find the path specified via stderr. The OpenSSH folder doesn't seem to be visible to Python through subprocess
  • os.environ[PATH] contains both C:/Windows/System32/ and C:/Windows/System32/OpenSSH/
  • Running it with shell=False (either with the absolute path or just with ssh) raises an error in Python: FileNotFoundError: [WinError 2] The system cannot find the file specified
smci
  • 32,567
  • 20
  • 113
  • 146
  • Check this: https://stackoverflow.com/questions/24158177/ssh-is-not-recognized-as-an-internal-or-external-command – 7koFnMiP Jan 27 '21 at 23:03
  • Does it work if you use absolute path? `C:/Windows/System32/OpenSSH/ssh.exe` – Lev Levitsky Jan 27 '21 at 23:05
  • ssh is installed, and I can successfully use it from the command prompt, just not from Python via subprocess. The absolute path doesn't help; "The system cannot find the path specified". For whatever reason, subprocess can't see the OpenSSH folder. – Evan Rittner Jan 27 '21 at 23:06
  • A place to start would be to determine whether the directory with your OpenSSH binaries is listed in `os.environ['PATH']`. `echo` and `cd` are built into the shell, so they're _always_ available with `shell=True`. (Mind, using `shell=True` at all is usually a Very Bad Idea... but that's not quite as true on Windows as it is everywhere else). – Charles Duffy Jan 27 '21 at 23:10
  • Both `C:/Windows/System32/` and `C:/Windows/System32/OpenSSH/` are on the path. – Evan Rittner Jan 27 '21 at 23:13
  • Should work with `shell=False` if ssh is on the path. It’s not rocket science/wizardry: you need to specify a program name that’s on the path or an absolute path to the exe. What did you try - edit all the things you’ve tried into your question. – DisappointedByUnaccountableMod Jan 27 '21 at 23:27
  • Main post updated. There is something tricky going on -- it's not just that ssh.exe is not on the path, it's somehow inaccessible. – Evan Rittner Jan 28 '21 at 00:11
  • The error has nothing to do with `subprocess`. – smci Jan 28 '21 at 02:41

1 Answers1

2

You say C:\Windows\System32\OpenSSH\ssh.exe exists, but that it's not found when running from Python. This is likely a result of having a 32 bit version of Python installed, rather than a 64 bit version.

If the path exists elsewhere, but not for Python, that would tend to implicate the file system redirector. Python is probably seeing C:\Windows\SysWOW64 when you tell it to look in C:\Windows\System32. I'd recommend uninstalling whatever Python you have, and explicitly installing a 64 bit version, so it isn't affected by the redirector, and sees the "real" System32.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Wow, thank you, that's it. I didn't know there was a redirector that worked like that. – Evan Rittner Jan 28 '21 at 00:22
  • Wow+1. Nice one! You Windows programmers have to live in a more strange and complex world than the rest of us. – CryptoFool Jan 28 '21 at 00:26
  • @EvanRittner: Yeah, Windows doesn't do fat DLLs (a DLL is compiled for either 32 or 64 bit, not both at once), and so many 32 bit programs assumed they'd find their DLLs in `System32` (the original name), while many 64 bit programs were written for 32 bit and just recompiled targeting 64 bit, and the DLLs all had the same name. So Microsoft came up with this kludge to let *both* 32 and 64 bit programs think that `System32` was where they could find their DLLs, and it seamlessly redirects to the "real" location under the hood. Got great back/forward compat at the expense of rank insanity. :-) – ShadowRanger Jan 28 '21 at 00:27
  • i am on python 64 and windows 64 bit and i get the same error, its in the PATH and all – Flying Thunder Dec 16 '21 at 10:31
  • @FlyingThunder: Then either you haven't installed OpenSSH, or you're mistaken as to which version of Python is being run. I can't guess as to which problem is occurring. Using `shutil.which` might tell you where it's finding `ssh` (or if it is). – ShadowRanger Dec 16 '21 at 11:38
  • I just found that when running the python script from cmd (python ssh.py) it works fine. when running it from pycharm (same interpreter) it cant find it so at least i know its not a problem with openssh or subprocess – Flying Thunder Dec 16 '21 at 11:56
  • 1
    @FlyingThunder: PyCharm historically has defaulted to a 32 bit interpreter IIRC. How sure are you it's *really* the same interpreter, and it's *really* 64 bits? – ShadowRanger Dec 16 '21 at 13:23