paramiko python模块挂在stdout.read()

use*_*508 10 python python-module paramiko python-3.x

我使用以下代码:

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")
Run Code Online (Sandbox Code Playgroud)

当谈到stdout.read()时,它会挂起......有时它会在很长时间后打印输出.

你能否建议如果能解决这个问题?

我看到这个问题已经报道:

https://bugs.python.org/issue24026

在python中是否有更好的模块用于ssh连接和运行命令?

Dmi*_*rev 16

可能与https://github.com/paramiko/paramiko/issues/109有关

下面解释我面临的问题以及我如何解决这个问题.

我也遇到过这个问题,这是由于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")
Run Code Online (Sandbox Code Playgroud)

stdin,stdout和stderr保持开放......

>>> 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))>>>
Run Code Online (Sandbox Code Playgroud)

所以没有收到EOF ......

>>> print stdin.channel.eof_received
0
Run Code Online (Sandbox Code Playgroud)

通常我收到True并且可以只是stdout.read(),但为了安全起见我使用此解决方法(可行!):等待超时,强制stdout.channel.close()然后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'
>>>
Run Code Online (Sandbox Code Playgroud)

BTW我使用:

Python 2.6.6
paramiko (1.15.2)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...


Car*_*ung 6

我碰巧遇到了这个问题。但我通过使用“readline”而不是“readlines”来解决这个问题。

例如:

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
Run Code Online (Sandbox Code Playgroud)

因此它将立即打印每一行并且不再挂起,同时 exit_status_ready() 将确保当 stdout 停止/退出时循环中断。