长期运行的命令在paramiko中阻止

时间:2016-09-05 04:53:51

标签: python paramiko

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

我已阅读此帖中的解决方案: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秒,而没有收到退出信号。

1 个答案:

答案 0 :(得分:0)

当stdout中没有数据或没有eol的行时(即在sh脚本中的read语句中),会发生这种情况。尝试设置'get_pty = True',然后只读取stdout中的字节。以下是直接使用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)