当输入停止使用paramiko和Flask时,停止在远程服务器上拖尾文件

时间:2018-04-25 17:47:42

标签: python linux flask paramiko

我环顾了一会儿,并没有找到答案。

这是我的用例:

我在遥控器上有几个进程,通过python脚本使用paramiko执行ssh到机器。我在这一点上的问题是第一个脚本执行正常但由于paramiko的尾部动作没有退出而挂起。以下是当前的相关代码。

建立ssh连接:

from paramiko_expect import SSHClientInteraction


def get_logs(appid, app):
    try:
        ssh = client.connect_ssh(IPADDRESS, USER)
        interact = SSHClientInteraction(ssh, timeout=10, display=False)
        interact.send('tail -f <Path to file>)
        interact.tail(line_prefix=str(app)+': ')
    except KeyboardInterrupt:
        print('Ctrl+C interruption detected, stopping tail')
    finally:
        ssh.close()

有一个帮助函数没有显示,但这不是问题所在,所以我没有包含它。

主应用代码的相关部分

@app.route('/processing', methods=['GET', 'POST'])
def processing():
    form = InstitutionForm()
    version_selected = form.versions.data
    resp = make_response(render_template('processing.html', form=form))
    sp_id = (request.cookies.get('sp_id').strip("[]").replace("L", ""), "SP")
    rs_appid = (request.cookies.get('rs_base_id').strip("[]").replace("L", ""), "RS Base")
    print "Undeploying"
    for i in [rs_appid, sp_id]:
        print i[0]
        app_actions.undeploy(i[0].strip())
        app_actions.get_logs(i[0].strip(), i[1])
        while True:
            time.sleep(10)
            status = app_actions.check_status(i, "'undeploy'")[0][2]
            print status
            if status == 'failure':
                print "undeploy failed"
                break
            elif status == 'success':
                print "undeploy succeded"
                break
            else:
                print "processing"
                pass

所以我的问题是,当脚本通过processing()函数时,它会根据需要从app_actions.get_logs()调用开始显示日志。之后就挂了。这似乎是因为get_logs()函数中的尾调用没有结束。

我总结的问题是:

使用paramiko如何拖动文件直到它停止然后退出并关闭ssh连接,以便循环的下一部分可以运行?

对不起,如果这个问题有任何错误或错误或遗漏,这是我第一个问题 SO

2 个答案:

答案 0 :(得分:1)

我会使用纯Python来实现它,而不是使用tail。这是Dan Beazy关于发电机的讨论的一部分。

import time

def tail(fin):
    fin.seek(0,2)
    while True:
        line = fin.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

_fin = open("path/to/file","r")
lines = tail(_fin)
for line in lines:
    print line,

答案 1 :(得分:0)

所以eagle给出的答案是正确的,并指出了正确的方向,经过一些研究后我发现了一个更好的解决方案。此解决方案专门用于我正在使用的paramiko_expect库。您可以调用几个函数来突破tail循环。

Here是添加它们的拉取请求。

我个人使用timeout函数在没有收到任何输入后等待15秒来突破循环。这对我来说非常适合。

以下是修订后的代码:

def get_logs(appid, app):
    try:
        ssh = client.connect_ssh(IPADDRESS, USER)
        interact = SSHClientInteraction(ssh, timeout=10, display=False)
        interact.send('tail -f <path to file>')
        interact.tail(line_prefix=str(app) + ': ', timeout=15)
    except KeyboardInterrupt:
        print('Ctrl+C interruption detected, stopping tail')
    except Exception:
        ssh.close()
    finally:
        try:
            ssh.close()
        except:
            pass

还要非常感谢fotis写了一个很棒的模块,让我可以做很棒的自动化。