Search code examples
pythonparamiko

channel.recv didn't return prompt back even after command is completed. 'while True' loop didn't break


channel.recv didn't return prompt back even after command is completed. 'while True' loop didn't break.

I am using paramiko to login a server with user 'xyz' and then 'su -' using paramiko channel.

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
    ssh.connect(hostname, username='xyz', password=list_pass(hostname, 'xyz'))

    command = 'puppet agent -t --no-use_cached_catalog ; echo COMMAND_COMPLETED'

    channel = ssh.invoke_shell()
    channel.send("su -\n")
    time.sleep(2)
    channel.send(list_pass(hostname, 'root') + "\n")
    time.sleep(2)
    channel.send(command + '\n')
    time.sleep(5)

    while True:
        if channel.recv:
            time.sleep(1)
            print(channel.recv(1024).decode())
            if "COMMAND_COMPLETED" in channel.recv(1024).decode():
                break
        else:
            continue

    channel.close()
    ssh.close()

except paramiko.AuthenticationException:
    print("Authentication failed")
except socket.gaierror:
    print(f"Can't connect to {hostname}. Verify if server exists and it's up.")

This code went to infinite loop. Command still running.

enter image description here


Solution

  • I tried below code and it worked.

    channel.send(command + '\n')
    time.sleep(5)
    # Create a new receive buffer
    receive_buffer = ""
    
    while not receive_buffer.endswith("# ") or receive_buffer.endswith("$ "):
        '''
        'root' user prompt ends with '# '.
        'non-root' user prompt end with '$ '.
        '''
        receive_buffer += channel.recv(9999).decode()
    
    print(receive_buffer)
    channel.close()
    ssh.close()