I'm fairly new to Python, but trying to create a small script that will SSH into a server on my work and navigate through various menus. Normally I would do that with Putty client. I did succeed in this using code below:
from socket import setdefaulttimeout
import time
import paramiko
from getpass import getpass
from prompt_toolkit import ANSI
# Connection parameters for SSH + create connection.
hostname = 'workhostname'
port = 22
user = input('User (server): ')
passwd = getpass('Password (server): ')
programlogin = input('User (hyperspace): ')
programpass = getpass('Password (hyperspace): ')
exportdir = "/home/" + user + "/PYTHONTEST1"
commandsequence = ["2", "1", programlogin, programpass, "", "6", "DEP", "", "1", "7", "6", "", "17030", "24650", "", "995", "1121042", "1121806", "", exportdir, "", ""]
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname,port=port,username=user,password=passwd)
# Create shell via paramiko.
chan = client.invoke_shell(term='xterm')
# Time.sleep for more than 5 seconds to make sure that the program initial screen pause of 5 seconds is passed.
# "This message will disapper in 5 seconds"
time.sleep(7)
# Loop through command sequence.
for command in commandsequence:
# Send command.
chan.send(command + '\r')
time.sleep(2.3)
print(chan.recv(4096).decode('ISO-8859-1')) # For debugging purposes - to check whats actually going on in the console
if command == programpass:
print("Command: PASSWORD HIDDEN completed")
else:
print("Command: " + command + " completed")
# Trying to create some loop to check if all bytes has been received from the channel. loops out, if not ready after 10 checks.
"""
counter = 0
while not chan.recv_ready():
print("Not ready")
time.sleep(1)
if counter < 10:
counter += 1
else:
break
"""
# Get all bytes + decode the data (so it is readable through print)
#s = chan.recv(4096).decode()
s = chan.recv(4096).decode('ISO-8859-1')
print(s)
client.close()
However this only works because I give the client enough time (time.sleep(2.3)
) between each command. I have read somewhere that paramikos exec command is the only real reliable way to tell if the command was actually completed. However I don't think I will be able to use the exec command to navigate this "program" that I'm facing when doing the shell approach. I can use linux terminal commands like "hostname" to get that returned, but I have no idea how to start the program and navigate through it this way.
Will I somehow be able to tell, by reading the chan.recv()
if I'm done receiving output from the server, instead of "blindly" trust some high timer? - Or what would the approach be?