How to interact with ssh using subprocess module
Question: I'm trying to spawn an ssh child process using subprocess.

I'm working on Python 2.7.6 on Windows 7

here is my code:

    
    
    from subprocess import *
    r=Popen("ssh sshserver@localhost", stdout=PIPE)
    stdout, stderr=r.communicate()
    print(stdout)
    print(stderr)
    

The outputs:

    
    
    None
    

stdout should contain: sshserver@localhost's password:


Answer: Here's an example of working SSH code that handles the promt for yes/no on the
certificate part and also when asked for a password.

    
    
    #!/usr/bin/python
    
    import pty, sys
    from subprocess import Popen, PIPE, STDOUT
    from time import sleep
    from os import fork, waitpid, execv, read, write
    
    class ssh():
        def __init__(self, host, execute='echo "done" > /root/testing.txt', askpass=False, user='root', password=b'SuperSecurePassword'):
            self.exec = execute
            self.host = host
            self.user = user
            self.password = password
            self.askpass = askpass
            self.run()
    
        def run(self):
            command = [
                    '/usr/bin/ssh',
                    self.user+'@'+self.host,
                    '-o', 'NumberOfPasswordPrompts=1',
                    self.exec,
            ]
    
            # PID = 0 for child, and the PID of the child for the parent    
            pid, child_fd = pty.fork()
    
            if not pid: # Child process
                # Replace child process with our SSH process
                execv(command[0], command)
    
            ## if we havn't setup pub-key authentication
            ## we can loop for a password promt and "insert" the password.
            while self.askpass:
                try:
                    output = read(child_fd, 1024).strip()
                except:
                    break
                lower = output.lower()
                # Write the password
                if b'password:' in lower:
                    write(child_fd, self.password + b'\n')
                    break
                elif b'are you sure you want to continue connecting' in lower:
                    # Adding key to known_hosts
                    write(child_fd, b'yes\n')
                elif b'company privacy warning' in lower:
                    pass # This is an understood message
                else:
                    print('Error:',output)
    
            waitpid(pid, 0)
    

The reason (and correct me if i'm wrong here) for you not being able to read
the `stdin` straight away is because SSH runs as a subprocess under a
different process ID which you need to read/attach to.

Since you're using windows, `pty` will not work. there's two solutions that
would work better and that's
[pexpect](http://pexpect.sourceforge.net/pexpect.html) and as someone pointed
out key-based authentication.

In order to achieve a key-based authentication you only need to do the
following: On your client, run: `ssh-keygen` Copy your `id_rsa.pub` content
(one line) into `/home/user/.ssh/authorized_keys` on the server.

And you're done. If not, go with pexpect.

    
    
    import pexpect
    child = pexpect.spawn('ssh user@host.com')
    child.expect('Password:')
    child.sendline('SuperSecretPassword')
    

