paramiko执行nohup_记一次使用django+paramiko远程操作时报错无法返回问题
前提:
以前能力不足,只能用linux命令行形式寫了個線上發(fā)布工具。采用的是paramiko來調(diào)用遠程指令。
最近自學(xué)了點前端的東西,打算用django寫一個web版的發(fā)布工具,在做正常異步遠程操作時候發(fā)現(xiàn)都沒有什么問題。
但是當調(diào)用我們游戲的可執(zhí)行文件啟動時候,問題出現(xiàn)了:遠程執(zhí)行啟動指令以后,無法退出。
正常情況:
可是我們游戲的情況就是這樣,有點類似于socket接口一樣在等待著輸入,但實際上return已經(jīng)返回了。
當時問題點:
1、嘗試用& nohup都無法解決問題。
2、使用>/dev/null將輸出全部丟棄掉,能夠退出遠程連接。
3、但是我需要查看輸出來確定操作結(jié)果是否正常,于是考慮到用>/tmp/XXX & cat /tmp/XXX的形式解決。這種方法是可以解決我的需求的。但是我們游戲代碼結(jié)構(gòu)比較復(fù)雜,又分多國家多地區(qū)多版本發(fā)布。所有地區(qū)、所有進程要各地區(qū)的開發(fā)都做這類修改的話需要一定的時間。這個方案當做備選方案。
4、直接登錄到服務(wù)器上,執(zhí)行admin.sh start all又能完美退出。
正式搭建中問題點:
第一種方式:
import paramikossh = paramiko.SSHClient()# 執(zhí)行命令stdin, stdout, stderr = ssh.exec_command(self.echo_cmd)# 獲取命令結(jié)果res = stdout.read().decode()# 獲取返回狀態(tài)EXIT = stdout.channel.recv_exit_status()最開始我使用stdin,stout,stdeer形式執(zhí)行指令,但是發(fā)現(xiàn)與shell操作類似,無法退出遠程操作,一直在等待中,即使使用了return,exit等也無法退出。
第二種方式:
self.chan =self.ssh.get_transport().open_session()self.chan.exec_command(self.echo_cmd)#查看返回狀態(tài)self.EXIT = self.chan.recv_exit_status()#查看返回結(jié)果self.res = self.chan.recv(10000)然后我改用了get_transport().open_session()打開一個會話的形式。發(fā)現(xiàn)能完美執(zhí)行完指令后退出遠程連接。這時候我還高興了一會兒,但是隨后我做異常處理檢查時發(fā)現(xiàn)問題來了。
例如:我執(zhí)行一個錯誤指令,用第一種方式能正常獲取到錯誤返回提示:文件或目錄不存在。
而采用第二種get_transport().open_session()會話的方式,能夠看到exit返回值不是0的狀態(tài),但是res里面確實沒有任何內(nèi)容的。
如上測試,LS指令是不存在的,我后面查看return返回值提示不為0,但是執(zhí)行結(jié)果卻沒有將"LS指令不存在"這個提示抓取到。
這就陷入到一個死循環(huán)了,我這游戲只有開啟終端的形式才能正常執(zhí)行相關(guān)admin.sh指令并退出,用類似ssh "ls" 這種遠程指令形式是無法退出的。
在這里解決了查找文檔搞了2個小時,最后無意間發(fā)現(xiàn)
stdin, stdout, stderr = ssh.exec_command(self.echo_cmd, get_pty=True)##get_pty=True 加一個虛擬tty,問題得到解決。
后續(xù):
我后來查了下aget_pty=True,很多人說有些場景不能用這個參數(shù),可能會出現(xiàn)一些問題,我暫時還沒遇到問題點,這里備注下。
總結(jié)
以上是生活随笔為你收集整理的paramiko执行nohup_记一次使用django+paramiko远程操作时报错无法返回问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: labview实例_手把手以实例教你学L
- 下一篇: python试卷河南理工大学万方科技学院