无法在具有通道和exec_command的paramiko中长时间运行的进程读取stdout和stderr

时间:2019-01-02 21:12:32

标签: python paramiko

我正在运行从我的机器(本地机器)上的Python进程在服务器(远程机器)上运行长时间运行的进程。

我可以使用Paramiko的exec_command函数成功地启动和执行该过程,并且效果很好。但是,我在远程计算机上运行的代码是一个长时间运行的过程,因此我希望对输出/日志进行一些检查。也就是说,我想在运行时读取输出,并检查输出中的某些关键字。

我整理了一个最小的工作示例来说明这一点。我没有检查某些关键字,而是将输出打印到屏幕上。

运行以下命令时,一旦过程结束,我将所有输出汇总在一起。当远程进程正在打印输出时,我无法获得输出。

我什至尝试使用setblockingsettimeout无济于事。

我有以下文件,该文件是通过笔记本电脑运行的。

import sys
import paramiko
import os
import select
import getpass
import time

rpi = {
    "username": getpass.getuser(),
    "hostname": "hostname.of.server.here"
}

command = "cd /path/to/folder/ && python test_worker.py"
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(**rpi)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command)

def worker(stdout, stderr):

    # Wait for the command to terminate
    print("Status of worker is {}".format(stdout.channel.exit_status_ready()))
    while not stdout.channel.exit_status_ready():
        time.sleep(1)
        print("Status of worker is {}".format(stdout.channel.exit_status_ready()))
        if stdout.channel.recv_ready():
            # Only print data if there is data to read in the channel
            print("Worker stdout.channel.recv_ready: {}".format(stdout.channel.recv_ready()))
            rl, wl, xl = select.select([stdout.channel], [], [], 0.0)
            if len(rl) > 0:
                # Print data from stdout
                print("Output: {}".format(stdout.channel.recv(1024).decode("utf-8")))

print("Reading output from master")
worker(ssh_stdout, ssh_stderr)
print("Finished reading output from master")

test_worker.py文件如下:

import time
import sys

i = 0

while True:
    time.sleep(5)
    i = i + 5
    print("At time {}".format(i))
    if i > 15:
        sys.exit(0)

这是我目前获得的输出,

$ python paramiko_runner.py                                                                                                                                                                                                                    
Reading output from master
Worker function printer
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is True
Worker stdout.channel.recv_ready: True
Output: At time 5
At time 10
At time 15
At time 20

Finished reading output from master

1 个答案:

答案 0 :(得分:0)

如果您要读取连续值,我相信您必须get_pty。您可以执行以下操作:

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command, get_pty=True)