paramiko python module hangs at stdout.read()

匿名 (未验证) 提交于 2019-12-03 08:59:04

问题:

I am using the below code:

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") 

when it comes to stdout.read() , it hangs... sometimes it prints the output after long time.

Can you please suggest if anything can be done about this issue??

I see this issue has been reported in :

https://bugs.python.org/issue24026

Is there any better module in python for ssh connection and run commands ??

回答1:

Could be related to https://github.com/paramiko/paramiko/issues/109

Below is explanation of what i am facing and how i worked around it.

I also experienced this issue it is due to 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 and stderr are staying open...

>>> 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))>>> 

So EOF was not received...

>>> print stdin.channel.eof_received 0 

Usually I receive True and can just stdout.read(), but to be safe i use this workaround (which works!): Wait for a timeout, force stdout.channel.close() and then 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 i use:

Python 2.6.6 paramiko (1.15.2) 

Hope this helps...



回答2:

It use to happen when there is no data in stdout or there is a line without eol (i.e. in a read statement inside a sh script). Try setting 'get_pty=True', then reading only the bytes in stdout. To avoid infinite loops, it'd be a good idea setting a timeout and a sleep in spite of the continue statement:

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) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!