1

I am trying to send a command from Python's os.system() to MS PowerShell. While other commands work as expected the ssh commands are treated as string inputs and do not work when invoked through os.system().

enter image description here

The normal expected output is:

enter image description here

Is there anything that can be done to "force" PowerShell to treat these as normal commands?

OpenSSH is located in System32 directory on Windows 10 and appropriately added to system and user paths.

Python Code (this fails)

import os
os.system('powershell ssh-keygen -R 192.168.2.2')

PowerShell Command (this works)

ssh-keygen -R 192.168.2.2
francman
  • 54
  • 5

3 Answers3

1

To recap: The problem was that your 32-bit Python process didn't see the 64-bit ssh-keygen utility, because 32-bit processes have a distinct C:\Windows\System32 folder.

A simpler and less invasive alternative to your own answer is to use the virtual SysNative subfolder of the Windows directory through which 32-bit processes can access the 64-bit System32(!) folder (32-bit processes see a different, 32-bit-binaries-only directory as C:\Windows\System32).

Note that this is only necessary for 32-bit Python versions.

import os
os.system('%windir%\\SysNative\\OpenSSH\\ssh-keygen -R 192.168.2.2')

If you want to do it via Windows PowerShell:

import os
os.system('powershell $env:windir\\SysNative\\OpenSSH\\ssh-keygen -R 192.168.2.2')
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Python uses 32 bit process for os module commands. To solve the problem from above in Windows 10, use the following steps:

  • Go to the OpenSSH folder under System32
  • Copy the entire OpenSSH directory
  • Paste the directory in SysWOW64 (32-bit processes)
  • Open command prompt and re-run the following code to confirm it works.
import os
os.system('ssh-keygen -R 192.168.2.2')

Any other ssh command should now work with from python using os module.

Credits to @mklement0 for pointing us in the right direction.

francman
  • 54
  • 5
-1

Variant 1: use call operator & before command

os.system('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy ByPass -command ^& ssh-heygen --% -R 192.168.1.1')

--% is stop parsing operator, means powershell will not try to parse rest of command. In your case it is useless, but there are some cases where it is mandatory.

Variant 2: use Start-Process

os.system('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy ByPass -command Start-Process -FilePath "ssh-keygen" -ArgumentList @("-R", "192.168.1.1")')
filimonic
  • 3,988
  • 2
  • 19
  • 26
  • You do not need `&` to call executable `ssh-keygen` - you only need `&` if the executable path is _quoted_ and/or contains _variable references or subexpressions_. To synchronously execute console applications or batch files, call them _directly_ (`c:\path\to\some.exe ...` or `& $exePath ...`), do _not_ use `Start-Process` - see [this answer](https://stackoverflow.com/a/51334633/45375). – mklement0 Aug 10 '20 at 21:50