Paramiko stdout.read gives "AttributeError: 'tuple' object has no attribute 'read'"

Viewed 437

I'm new to Python so apologies if I missed something.

I'm creating a script that can connect to Linux machines to run a couple commands and output those results to be used in an HTML report. When I run the script (minus the HTML report generation) it is throwing the following error, when the commands are passed over to the function that executes the CLI command:

AttributeError: 'tuple' object has no attribute 'read'

How do I handle this type of error in the function when there will be about 30 different CLI commands passed to it and need to return the results?

import paramiko as paramiko
from paramiko import SSHClient

# Connect

ssh = SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('', username='', password='', look_for_keys=False)

def ExecSSHCommand(cli):
    stdout = ssh.exec_command(cli)

    print(type(stdout))  # <class 'paramiko.channel.ChannelFile'>

    # Print output of command. Will wait for command to finish.
    print(f'STDOUT: {stdout.read().decode("utf8")}')

    stdout.close()

    # Close the client itself
    ssh.close()

status = ExecSSHCommand('show status') 
service = ExecSSHCommand('show services')

This is the full error:

line 55, in <module>
  status = ExecSSHCommand('show status') line 22,
in ExecSSHCommand print(f'STDOUT: {stdout.read().decode("utf8")}')
AttributeError: 'tuple' object has no attribute 'read' 
1 Answers

The exec_command indeed returns a stdin/stdout/stderr tuple.

You want this:

stdin, stdout, stderr = ssh.exec_command(cli)

Another unrelated thing is that you cannot close the SSHClient after the each command. So this has to be moved from the end of the ExecSSHCommand function to to the end of the script:

ssh.close()
Related