Paramiko频道在阅读大量输出时卡住了

vip*_*ulb 9 python paramiko

我有一个代码,我在远程Linux机器上执行命令并使用Paramiko读取输出.代码def看起来像这样:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(IPAddress, username=user['username'], password=user['password'])


chan = self.ssh.get_transport().open_session()

chan.settimeout(10800)

try:
    # Execute thecommand
    chan.exec_command(cmd)

    contents = StringIO.StringIO()

    data = chan.recv(1024)

    # Capturing data from chan buffer.
    while data:
        contents.write(data)
        data = chan.recv(1024)

except socket.timeout:
    raise socket.timeout


output = contents.getvalue()

return output,chan.recv_stderr(600),chan.recv_exit_status()
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于小输出,但它适用于较大的输出.

这里有缓冲相关的问题吗?

vip*_*ulb 7

我发布的最终代码与Bruce Wayne(:)的输入一起工作

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(IPAddress, username=user['username'], password=user['password'])

chan = self.ssh.get_transport().open_session()
chan.settimeout(10800)

try:
    # Execute the given command
    chan.exec_command(cmd)

    # To capture Data. Need to read the entire buffer to capture output
    contents = StringIO.StringIO()
    error = StringIO.StringIO()

    while not chan.exit_status_ready():
        if chan.recv_ready():
            data = chan.recv(1024)
            #print "Indside stdout"
            while data:
                contents.write(data)
                data = chan.recv(1024)

        if chan.recv_stderr_ready():            
            error_buff = chan.recv_stderr(1024)
            while error_buff:
                error.write(error_buff)
                error_buff = chan.recv_stderr(1024)

    exit_status = chan.recv_exit_status()

except socket.timeout:
    raise socket.timeout

output = contents.getvalue()
error_value = error.getvalue()

return output, error_value, exit_status
Run Code Online (Sandbox Code Playgroud)


bru*_*e_w 3

我没有看到与 stdout 通道相关的问题,但我不确定您处理 stderr 的方式。您能否确认,这不是导致问题的 stderr 捕获?我会尝试你的代码并让你知道。

更新:当您执行的命令在 STDERR 中给出大量消息时,您的代码会冻结。我不确定为什么,但recv_stderr(600)可能是原因。因此,捕获错误流的方式与捕获标准输出的方式相同。就像是,

contents_err = StringIO.StringIO()

data_err = chan.recv_stderr(1024)
while data_err:
    contents_err.write(data_err)
    data_err = chan.recv_stderr(1024)
Run Code Online (Sandbox Code Playgroud)

您甚至可以先尝试更改recv_stderr(600)recv_stderr(1024)或更高。