I wrote this code in Paramiko:
ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect(hostname, username=user, password=passwd, timeout=3)
session = ssh.invoke_shell()
session.send("\n")
session.send("echo step 1\n")
time.sleep(1)
session.send("sleep 30\n")
time.sleep(1)
while not session.recv_ready():
time.wait(2)
output = session.recv(65535)
session.send("echo step 2\n")
time.sleep(1)
output += session.recv(65535)
I'm trying execute more commands on my Linux server. The problem is my Python code not wait to finish execute command, for example if I'm try to execute sleep 30
, the Python not wait 30 seconds for finish execute commands. How can resolve this problem ? I tried with while recv_ready()
, but it still does not wait.
banner_timeout (float) – an optional timeout (in seconds) to wait for the SSH banner to be presented. auth_timeout (float) – an optional timeout (in seconds) to wait for an authentication response.
Is paramiko safe to use? The python package paramiko was scanned for known vulnerabilities and missing license, and no issues were found. Thus the package was deemed as safe to use.
Paramiko Expect provides an expect-like extension for the Paramiko SSH library which allows scripts to fully interact with hosts via a true SSH connection. The class is constructed with an SSH Client object (this will likely be extended to support a transport in future for more flexibility).
Using exec_command() in Paramiko returns a tuple (stdin, stdout, stderr) . Most of the time, you just want to read stdout and ignore stdin and stderr . You can get the output the command by using stdout. read() (returns a string) or stdout.
Use exec_command
: http://docs.paramiko.org/en/1.16/api/channel.html
stdin, stdout, stderr = ssh.exec_command("my_long_command --arg 1 --arg 2")
The following code works for me:
from paramiko import SSHClient, AutoAddPolicy
import time
ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect('111.111.111.111', username='myname', key_filename='/path/to/my/id_rsa.pub', port=1123)
sleeptime = 0.001
outdata, errdata = '', ''
ssh_transp = ssh.get_transport()
chan = ssh_transp.open_session()
# chan.settimeout(3 * 60 * 60)
chan.setblocking(0)
chan.exec_command('ls -la')
while True: # monitoring process
# Reading from output streams
while chan.recv_ready():
outdata += chan.recv(1000)
while chan.recv_stderr_ready():
errdata += chan.recv_stderr(1000)
if chan.exit_status_ready(): # If completed
break
time.sleep(sleeptime)
retcode = chan.recv_exit_status()
ssh_transp.close()
print(outdata)
print(errdata)
Please note that command history
cannot be executed with ssh as is.
See example here: https://superuser.com/questions/962001/incorrect-output-of-history-command-of-ssh-how-to-read-the-timestamp-info-corre
In case you do not need to read the stdout and stderr separately, you can use way more straightforward code:
stdin, stdout, stderr = ssh_client.exec_command(command)
stdout.channel.set_combine_stderr(True)
output = stdout.readlines()
The readlines
reads until the command finishes and returns a complete output.
In case you need the output separately, do not be tempted to remove the set_combine_stderr
and call readlines
on stdout
and stderr
separately. That might deadlock. See Paramiko ssh die/hang with big output
For a correct code that reads the outputs separately, see Run multiple commands in different SSH servers in parallel using Python Paramiko.
Obligatory warning: Do not use AutoAddPolicy
– You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With