Search code examples
pythonpexpect

Pexpect PopenSpawn does not work on Windows


I am currently trying to use pexpect to control a simple ssh connection to my raspberry pi, which I use for certain smart home controls.

I have just started to use it, I'm learning it with the help from "Violent Python", a penetester's book.

I am on Windows and learned that the pexpect.spawn object is not available on Windows. In the docs, it was said that I would have to use PopenSpawn instead. I have a simple script:

import traceback
import pexpect
from pexpect.popen_spawn import PopenSpawn

try:
    child = pexpect.popen_spawn.PopenSpawn('ssh [email protected]')
    a = child.expect(['password:', 'The authenticity of host'], timeout=300, async=True)
    if a == 0:
        child.sendline('123456789')
        print('this ip has exists in know_host files!')
    if a == 1:
        print('this ip will be added to know_host files!')
        child.sendline('yes')
        child.expect('password:')
        child.sendline('raspberry')
        # send test
        child.sendline("echo TestMessage")
        child.interact()
except pexpect.EOF:
    traceback.print_exc()

which always gives me this Error:

Traceback (most recent call last):
  File "D:/CENSORED/pexpect-master/sshforpi2.py", line 6, in <module>
    child = pexpect.popen_spawn.PopenSpawn('ssh [email protected]')
  File "D:/CENSORED/pexpect-master\pexpect\popen_spawn.py", line 46, in __init__
    self.proc = subprocess.Popen(cmd, **kwargs)
  File "C:\Python34\lib\subprocess.py", line 859, in __init__
    restore_signals, start_new_session)
  File "C:\Python34\lib\subprocess.py", line 1112, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system can't find the given file.

I have found this teddyjoe guy asking the same thing - he didn't get an answer (yet).


Solution

  • SSH is not native as a windows command. In the following line map command to point to ssh which is located in C:\Windows\System32\OpenSSH. OpenSSH is now added to Windows 10 in System32. Try this, i think it may work for you.

    child = pexpect.popen_spawn.PopenSpawn('ssh [email protected]')
    

    try this instead

    command = 'C:\Windows\system32\OpenSSH\ssh.exe [email protected]'
    child = pexpect.popen_spawn.PopenSpawn(command)
    

    better yet, you can install the new Windows Subsystem for Linux and run your script with that. Windows Subsystem for Linux Installation Guide for Windows 10