22

As you see below, is it possible to save the result? Cause, at second and third stdout.read() I couldn't reach the result.

import paramiko
import os
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect('192.168.1.250', username='root', password='pass')
import os
stdin, stdout, stderr = dssh.exec_command('ifconfig')
print stdout.read()
print ('Sleeping 2 seconds!')
os.system('sleep 2')
stdin, stdout, stderr = dssh.exec_command('ls -l')
print stdout.read()
print stdout.read()
print stdout.read()
dssh.close()
MrCskncn
  • 328
  • 1
  • 3
  • 16

2 Answers2

29

Imagine that stdout is an ordinary file. What do you expect to get if you call file.read() the second time? -- nothing (empty string) unless the file has changed outside.

To save the string:

output = stdout.read()

You might find Fabric simpler to use (it uses paramiko to execute commands under the hood).

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • I tried that before and i was not working. But now It works. Huh? Thanks anyway – MrCskncn Nov 15 '11 at 15:19
  • 1
    If the command produces also an output on `stderr`, you need to read both outputs in parallel. Otherwise, once `stderr` output buffer fills, the command will stop, waiting for you to read the `stderr`. If you instead keep reading from `stdout` only, you have a deadlock. – Martin Prikryl Jun 15 '18 at 19:00
  • @MartinPrikryl it is true for OS pipe buffers e.g., if you were using `subprocess.Popen`. I'm not sure it applies to paramiko's streams. Could you provide a complete minimal code example that demonstrates the deadlock? – jfs Jun 15 '18 at 19:51
  • 1
    It's not really about paramiko, but about buffers on server-side. If ssh client does not consume the output, ssh server stops reading remote command output (what's actually an equivalent of `subprocess.Popen` that you refer to). For example, this never finishes on my system `stdin, stdout, stderr = ssh.exec_command("for ((n=0;n<1000000;n++)); do echo 1234567890; done >&2")` `print stdout.read()` - If you remove the `>&2` it finishes. - Though actual number of iterations needed will vary among different systems. – Martin Prikryl Jun 15 '18 at 20:25
  • 1
    This question covers the problem: [Paramiko ssh die/hang with big output](https://stackoverflow.com/q/31625788/850848). – Martin Prikryl Oct 15 '20 at 07:17
7

You can try this Generic API

def ssh_ctrl(ip, user, password,cmd):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(hostname=ip, username=user, password=password, timeout=tout, compress = True,look_for_keys=False, allow_agent=False)
    except (socket.error,paramiko.AuthenticationException,paramiko.SSHException) as message:
        print "ERROR: SSH connection to "+ip+" failed: " +str(message)
        sys.exit(1)

    stdin, stdout, ssh_stderr = ssh.exec_command(cmd)
    out = stdout.read()
    stdin.flush()
    ssh.close()
    return out
Vasfed
  • 18,013
  • 10
  • 47
  • 53