Python paramiko ssh
Я новичок в python. я написал script для подключения к хосту и выполнения одной команды
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=pw)
print 'running remote command'
stdin, stdout, stderr = ssh.exec_command(command)
stdin.close()
for line in stdout.read().splitlines():
print '%s$: %s' % (host, line)
if outfile != None:
f_outfile.write("%s\n" %line)
for line in stderr.read().splitlines():
print '%s$: %s' % (host, line + "\n")
if outfile != None:
f_outfile.write("%s\n" %line)
ssh.close()
if outfile != None:
f_outfile.close()
print 'connection to %s closed' %host
except:
e = sys.exc_info()[1]
print '%s' %e
отлично работает, когда удаленная команда не нуждается в tty. Я нашел пример invoke_shell Вложенный сеанс SSH с Paramiko. я не доволен этим решением, потому что, если у сервера есть приглашение, которое не указано в моем контуре script → , или заданное приглашение в script - это строка в возвращаемом тексте → не все данные будут получены. есть ли лучшее решение, возможно, когда stdout и stderr отправляются обратно, как в моем script?
Ответы
Ответ 1
Существует обширная документация API paramiko, которую вы можете найти по адресу: http://docs.paramiko.org/en/stable/index.html
Я использую следующий метод для выполнения команд для защищенного паролем клиента:
import paramiko
import sys
nbytes = 4096
hostname = 'hostname'
port = 22
username = 'username'
password = 'password'
command = 'ls'
client = paramiko.Transport((hostname, port))
client.connect(username=username, password=password)
stdout_data = []
stderr_data = []
session = client.open_channel(kind='session')
session.exec_command(command)
while True:
if session.recv_ready():
stdout_data.append(session.recv(nbytes))
if session.recv_stderr_ready():
stderr_data.append(session.recv_stderr(nbytes))
if session.exit_status_ready():
break
print 'exit status: ', session.recv_exit_status()
print ''.join(stdout_data)
print ''.join(stderr_data)
session.close()
client.close()
Ответ 2
В принятом ответе что-то не так, иногда (случайным образом) вызывается обрезанный ответ с сервера. Я не знаю, почему, я не исследовал ошибочную причину принятого ответа, потому что этот код отлично работал у меня:
import paramiko
ip='server ip'
port=22
username='username'
password='password'
cmd='some useful command'
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,port,username,password)
stdin,stdout,stderr=ssh.exec_command(cmd)
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
stdin,stdout,stderr=ssh.exec_command('some really useful command')
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
Ответ 3
Код @ThePracticalOne отлично подходит для показа использования, за исключением одного:
Непосредственно вывод будет неполным. (session.recv_ready()
становится истинным после if session.recv_ready():
, а session.recv_stderr_ready()
и session.exit_status_ready()
повернуто true перед вводом следующего цикла)
поэтому я думаю, что вы должны получить данные, когда они готовы выйти из сеанса.
while True:
if session.exit_status_ready():
while True:
while True:
print "try to recv stdout..."
ret = session.recv(nbytes)
if len(ret) == 0:
break
stdout_data.append(ret)
while True:
print "try to recv stderr..."
ret = session.recv_stderr(nbytes)
if len(ret) == 0:
break
stderr_data.append(ret)
break