Chapter 16 ■ telnet and SSh
311
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='')
def read_until_EOF(fileobj):
s = fileobj.readline()
while s:
print(s.strip())
s = fileobj.readline()
ioe1 = client.exec_command('echo One;sleep 2;echo Two;sleep 1;echo Three')
ioe2 = client.exec_command('echo A;sleep 1;echo B;sleep 2;echo C')
thread1 = threading.Thread(target=read_until_EOF, args=(ioe1[1],))
thread2 = threading.Thread(target=read_until_EOF, args=(ioe2[1],))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
client.close()
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)
To be able to process these two streams of data simultaneously, you are kicking off two threads and are handing
each of them one of the channels from which to read. Both print each line of new information as soon as it arrives and
finally exit when the readline() command indicates end-of-file by returning an empty string. When run, this script
should return something like this:
$ python3 ssh_threads.py localhost brandon
One
A
B
Two
Three
C
As you can see, SSH channels over the same TCP connection are completely independent, can each receive
(and send) data at their own pace, and can close independently when the particular command to which they are
talking finally terminates. The same is true of the features you are about to look at—file transfer and port forwarding.