I want to write a program (in Python 3.x on Windows 7) that executes multiple commands on a remote shell via ssh. After looking at paramikos' exec_command() function, I realized it's not suitable for my use case (because the channel gets closed after the command is executed), as the commands depend on environment variables (set by prior commands) and can't be concatenated into one exec_command() call as they are to be executed at different times in the program.
Thus, I want to execute commands in the same channel. The next option I looked into was implementing an interactive shell using paramikos' invoke_shell() function:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=psw, port=22)
channel = ssh.invoke_shell()
out = channel.recv(9999)
channel.send('cd mivne_final\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
channel.send('cd ..\n')
channel.send('cd or_fail\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
channel.send('cd ..\n')
channel.send('cd simulator\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
ssh.close()
There are some problems with this code:
- The first
printdoesn't always print thelsoutput (sometimes it is only printed on the secondprint). - The first
cdandlscommands are always present in the output (I get them via therecvcommand, as part of the output), while all the followingcdandlscommands are printed sometimes, and sometimes they aren't. - The second and third
cdandlscommands (when printed) always appear before the firstlsoutput.
I'm confused with this "non-determinism" and would very much appreciate your help.
paramiko? I found it much easier to work withfabric. You just set upenvvariables likeuser,passwordandhost_stringand then you can do various stuff like use:getto download files from remote host,putto send files andrunto issue commands. You can chain commands like this for example:run('cd .. && cd simulator && ls').