【问题标题】:Long-running commands block in paramikoparamiko 中的长时间运行命令块
【发布时间】:2017-02-24 06:52:55
【问题描述】:

我想在远程服务器上运行一些软件的自动部署。无论如何,远程命令的输出总是阻塞并且永远不会结束。我已经检查了远程服务器,并且可以确认命令仍在运行,尽管 paramiko 打印的标准输出会阻塞。

我已经阅读了这篇文章的解决方案:LINK

import paramiko
import select

client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
channel = client.get_transport().open_session()
channel.exec_command("packstack --allinone")
while True:
    if channel.exit_status_ready():
        break
    rl, wl, xl = select.select([channel], [], [], 0.0)
    if len(rl) > 0:
        print channel.recv(1024)

每次我使用Ctrl + C强制脚本停止时,似乎卡在rl, wl, xl = select.select([channel], [], [], 0.0)

作为参考,我还阅读了this 帖子。但没有找到运气。

如何修改代码以使其与持久且输出量大的命令一起使用?

现在我发现了问题。 实际上它并没有停留在rl, wl, xl = select.select([channel], [], [], 0.0)。由于timeout 设置为0.0,因此它处于非阻塞模式。

因此,问题在于,程序永远执行了while 循环,但它无法从channel 接收任何内容,尽管远程进程仍在输出内容。

我认为这可能是由 paramiko 或坏的远程服务器引起的。

现在我的解决方案是当频道在有限的时间内(比如 120 秒)无法接收到任何东西,而没有收到退出信号时重新运行我的命令。

【问题讨论】:

  • 试试exec_command("for i in 1 2 3 4 5; do echo $i; sleep 1; done"),看看它是否适合你。
  • @whjm 我试过了。输出是正确的,它永远不会挂起。

标签: python paramiko


【解决方案1】:

当 stdout 中没有数据或有一行没有 eol 时(即在 sh 脚本内的 read 语句中),通常会发生这种情况。尝试设置“get_pty=True”,然后只读取标准输出中的字节。这是一个直接使用 exec_command 和 SSHClient 的示例。

ssh = paramiko.SSHClient()
...
stdin, stdout, stderr = ssh.exec_command("your-command",get_pty=True)
stdout.flush()
nbytes = 0
while (len(stdout.channel.in_buffer)==0):
     continue

nbytes=len(stdout.channel.in_buffer)
print(nbytes)
stdout.read(nbytes)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 2015-08-11
    • 1970-01-01
    • 2014-04-30
    相关资源
    最近更新 更多