Chapter 16 ■ telnet and SSh
308
First, SSH can set up a raw shell session for you, running on the remote end inside a pseudoterminal so that
programs act like they normally do when they are interacting with the user at a terminal. This kind of connection
behaves very much like a Telnet connection. Take a look at Listing 16-4 for an example that pushes a simple echo
command at the remote shell and then asks it to exit.
Listing 16-4. Running an Interactive Shell Under SSH
#!/usr/bin/env python3
Foundations of Python Network Programming, Third Edition
https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter16/ssh_simple.py
Using SSH like Telnet: connecting and running two commands
import argparse, paramiko, sys
class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy):
def missing_host_key(self, client, hostname, key):
return
def main(hostname, username):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(AllowAnythingPolicy())
client.connect(hostname, username=username) # password='')
channel = client.invoke_shell()
stdin = channel.makefile('wb')
stdout = channel.makefile('rb')
stdin.write(b'echo Hello, world\rexit\r')
output = stdout.read()
client.close()
sys.stdout.buffer.write(output)
if name == 'main':
parser = argparse.ArgumentParser(description='Connect over SSH')
parser.add_argument('hostname', help='Remote machine name')
parser.add_argument('username', help='Username on the remote machine')
args = parser.parse_args()
main(args.hostname, args.username)
You can see that this script bears the scars of a program operating over a terminal. Instead of being able to
encapsulate neatly each of the two commands it is issuing and separate their arguments, it has to use spaces and
carriage returns and trust the remote shell to divide things up properly. Note that this script is written under the
assumption that you have an identity file and a remote authorized-keys file and, therefore, do not have to type a
password. If you do, then you can edit the script to provide one using the commented-out password parameter. To
avoid typing the password into your Python file, you can have it call getpass(), as you did in the Telnet example.