龙空技术网

记一次使用django+paramiko远程操作时报错无法返回问题

新言糯语 90

前言:

今天大家对“python paramiko 执行nohup命令”可能比较注意,各位老铁们都想要分析一些“python paramiko 执行nohup命令”的相关文章。那么小编在网摘上收集了一些关于“python paramiko 执行nohup命令””的相关文章,希望各位老铁们能喜欢,你们快快来了解一下吧!

前提:

以前能力不足,只能用linux命令行形式写了个线上发布工具。采用的是paramiko来调用远程指令。

最近自学了点前端的东西,打算用django写一个web版的发布工具,在做正常异步远程操作时候发现都没有什么问题。

但是当调用我们游戏的可执行文件启动时候,问题出现了:远程执行启动指令以后,无法退出。

正常情况:

可是我们游戏的情况就是这样,有点类似于socket接口一样在等待着输入,但实际上return已经返回了。

当时问题点:

1、尝试用& nohup都无法解决问题。

2、使用>/dev/null将输出全部丢弃掉,能够退出远程连接。

3、但是我需要查看输出来确定操作结果是否正常,于是考虑到用>/tmp/XXX & cat /tmp/XXX的形式解决。这种方法是可以解决我的需求的。但是我们游戏代码结构比较复杂,又分多国家多地区多版本发布。所有地区、所有进程要各地区的开发都做这类修改的话需要一定的时间。这个方案当做备选方案。

4、直接登录到服务器上,执行admin.sh start all又能完美退出。

正式搭建中问题点:

第一种方式:

import paramikossh = paramiko.SSHClient()# 执行命令stdin, stdout, stderr = ssh.exec_command(self.echo_cmd)# 获取命令结果res = stdout.read().decode()# 获取返回状态EXIT = stdout.channel.recv_exit_status()

最开始我使用stdin,stout,stdeer形式执行指令,但是发现与shell操作类似,无法退出远程操作,一直在等待中,即使使用了return,exit等也无法退出。

第二种方式:

self.chan =self.ssh.get_transport().open_session()self.chan.exec_command(self.echo_cmd)#查看返回状态self.EXIT = self.chan.recv_exit_status()#查看返回结果self.res = self.chan.recv(10000)

然后我改用了get_transport().open_session()打开一个会话的形式。发现能完美执行完指令后退出远程连接。这时候我还高兴了一会儿,但是随后我做异常处理检查时发现问题来了。

例如:我执行一个错误指令,用第一种方式能正常获取到错误返回提示:文件或目录不存在。

而采用第二种get_transport().open_session()会话的方式,能够看到exit返回值不是0的状态,但是res里面确实没有任何内容的。

如上测试,LS指令是不存在的,我后面查看return返回值提示不为0,但是执行结果却没有将"LS指令不存在"这个提示抓取到。

这就陷入到一个死循环了,我这游戏只有开启终端的形式才能正常执行相关admin.sh指令并退出,用类似ssh "ls" 这种远程指令形式是无法退出的。

在这里解决了查找文档搞了2个小时,最后无意间发现

stdin, stdout, stderr = ssh.exec_command(self.echo_cmd, get_pty=True)

##get_pty=True 加一个虚拟tty,问题得到解决。

后续:

我后来查了下aget_pty=True,很多人说有些场景不能用这个参数,可能会出现一些问题,我暂时还没遇到问题点,这里备注下。

标签: #python paramiko 执行nohup命令 #python paramiko 执行nohup命令异常