paramiko python module hangs at stdout.read()

前端 未结 4 1576
北恋
北恋 2021-01-04 06:24

I am using the below code:

import paramiko

def runSshCmd(hostname, username, password, cmd, timeout=None):          
    client = paramiko.SSHClient()
            


        
相关标签:
4条回答
  • 2021-01-04 06:41

    I happen to come across this issue. But I kinda work around it by using "readline" instead "readlines".

    For example:

    client = paramiko.SSHClient()
    client.connect(addr, port, username, password)
    stdin, stdout, stderr = client.exec_command(cmd)
    
    while True:
        print(stdout.readline())
        if stdout.channel.exit_status_ready():
            break
    

    So it will print every line immediately and no more hanging, also exit_status_ready() will make sure the loop breaks when stdout has stopped/exited.

    0 讨论(0)
  • 2021-01-04 06:56

    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)
    
    0 讨论(0)
  • 2021-01-04 07:02

    For anyone still struggling with this: I was able to fix this by running client.close() before trying to read from stdout or stderr.

    0 讨论(0)
  • 2021-01-04 07:07

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

    0 讨论(0)
提交回复
热议问题