2016-02-08 2 views
3

Я использую следующий код:paramiko питон модуль висит на stdout.read()

import paramiko 

def runSshCmd(hostname, username, password, cmd, timeout=None):   
    client = paramiko.SSHClient() 
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    client.connect(hostname, username=username, password=password, 
      allow_agent=False, look_for_keys=False, timeout=timeout) 
    stdin, stdout, stderr = client.exec_command(cmd) 
    stdin.flush() 
    data = stdout.read() 
    print (data) 
    client.close() 

runSshCmd("10.128.12.32", "root", "C0mput3Gr!d", "ts_menu") 

, когда дело доходит до stdout.read(), он вешает ... иногда она печатает вывод после долгого времени ,

Можете ли вы предложить, если что-нибудь можно сделать по этой проблеме?

Я вижу этот вопрос уже сообщалось в:

https://bugs.python.org/issue24026

Есть ли лучший модуль питона для подключения SSH и запускать команды ??

ответ

6

Может быть связано с https://github.com/paramiko/paramiko/issues/109

Ниже объяснение того, что я столкнулся и как я работал вокруг него.

Я также испытал эту проблему, это связано с stdout.channel.eof_received == 0

import paramiko 
client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect("1.1.1.1", username="root", password="pass") 
stdin, stdout, stderr = client.exec_command("service XXX start") 

STDIN, STDOUT и STDERR остаются открытыми ...

>>> print stdin 
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>> 
>>> print stdout 
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>> 
>>> print stderr 
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>> 

Так EOF было не принимается ...

>>> print stdin.channel.eof_received 
0 

Обычно я получаю True и могу использовать только stdout.read(), но быть безопасным я использовать этот обходной путь (который работает!): Дождитесь тайм-аута, силы stdout.channel.close(), а затем stdout.read():

>>> timeout = 30 
>>> import time 
>>> endtime = time.time() + timeout 
>>> while not stdout.channel.eof_received: 
...  sleep(1) 
...  if time.time() > endtime: 
...   stdout.channel.close() 
...   break 
>>> stdout.read() 
'Starting XXX: \n[ OK ]\rProgram started . . .\n' 
>>> 

BTW я использую:

Python 2.6.6 
paramiko (1.15.2) 

Надеется, что это помогает ...

0

Его использует, чтобы случиться, когда нет никаких данных в стандартном выводе или есть строка без EOL (т.е. в инструкции чтения внутри сценария sh). Попробуйте установить 'get_pty = True', а затем прочитайте только байты в stdout. Чтобы избежать бесконечных циклов, было бы хорошей идеей установить тайм-аут и спать, несмотря на продолжение заявления:

stdin, stdout, stderr = ssh.exec_command("your-command",get_pty=True) 
stdout.flush() 
nbytes = 0 
while (len(stdout.channel.in_buffer)==0): 
    continue 

nbytes=len(stdout.channel.in_buffer) 
print(nbytes) 
stdout.read(nbytes) 
Смежные вопросы