首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有连续标准输出的Paramiko

具有连续标准输出的Paramiko
EN

Stack Overflow用户
提问于 2014-08-12 16:56:21
回答 2查看 13.4K关注 0票数 10

我使用Paramiko向远程Linux服务器运行一些ssh命令。这些命令将在控制台中连续输出,我希望在本地控制台窗口中打印所有这些信息。

代码语言:javascript
运行
复制
stdin, stdout, stderr = ssh.client.exec_command("ls")
for line in stdout.read()
    print line,
ssh.client.close()

因此,如果我像这样编写代码,所有输出信息都将被发送回给我,直到命令执行完毕,而我想要在live中打印输出。

非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-26 04:56:38

当然有一种方法可以做到这一点。Paramiko execute_command是异步的,无论你的主线程是什么,数据到达时缓冲区都会被填充。

在您的示例中,stdout.read(size=None)将尝试一次读取完整的缓冲区大小。因为新数据总是会到达,所以它永远不会退出。为了避免这种情况,您可以尝试以较小的块读取stdout。下面是一个按字节读取缓冲区并在接收到\n后生成行的示例。

代码语言:javascript
运行
复制
stdin,stdout,stderr = ssh.exec_command("while true; do uptime; done")

def line_buffered(f):
    line_buf = ""
    while not f.channel.exit_status_ready():
        line_buf += f.read(1)
        if line_buf.endswith('\n'):
            yield line_buf
            line_buf = ''

for l in line_buffered(stdout):
    print l

您可以通过调整代码以使用select.select()和具有更大的块大小来提高性能,请参阅this answer,它还考虑了可能导致空响应的常见挂起和远程命令退出检测场景。

票数 14
EN

Stack Overflow用户

发布于 2022-02-23 19:40:42

因此,因为分享是关心的,所以我解决了PARAMIKO的问题,并像这样连续输出(忽略索引并替换内容,这是我设备的专有问题):

代码语言:javascript
运行
复制
"elif action == "icmd":
        cmd = command
        channel = ssh.get_transport().open_session()
        channel.exec_command(cmd)
        channel.set_combine_stderr(True)
        index = 0
        a = ""  # list to be filled with output of the commands.
        while True:
            if channel.exit_status_ready():
                break
            o = channel.recv(2048).decode("utf-8")
            if o:
                a += o
                if "\n" in o:
                    b = a.split("\n")
                    a = b[-1]
                    b.pop()
                    for x in b:
                        print(x.replace("●", "").replace("└─", ""), flush=True)
                        index += 1
                if index == 0 and len(o) > 0:
                    print(o.replace("●", "").replace("└─", ""), flush=True)
                if index == 0 and len(o) == 0:
                    print(f"Your command '{cmd}' did not returned anything! ")
        channel.close()
        ssh.close()

我之所以选择拆分和弹出,是因为在使用诸如traceroute www.google.com之类的命令时,输出会被拆分成单独的行。

此外,我还集成了一个shell,用于与设备进行交互输入/输出,如下所示:

代码语言:javascript
运行
复制
elif action == "shell":
        channel = ssh.invoke_shell()
        cmd = command
        print("Shell started")
        print(channel.recv(2048).decode())
        while True:
            if channel.exit_status_ready():
                print("Session Ended!")
                break
            try:
                cmd = input(cmd)
                channel.send(f"{cmd}\n".encode())
                time.sleep(1)
                output = channel.recv(2048).decode("utf-8")
                print(output.replace("●", "").replace("└─", ""), flush=True)
                if cmd == "exit":
                    break
            except KeyboardInterrupt:
                break
        channel.close()
        ssh.close()

尽情享受吧!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25260088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档