我环顾了一会儿,并没有找到答案。
这是我的用例:
我在遥控器上有几个进程,通过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
答案 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写了一个很棒的模块,让我可以做很棒的自动化。