paramiko执行nohup_记一次使用django+paramiko远程操作时报错无法返回问题
前提:
以前能力不足,只能用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,很多人說有些場景不能用這個參數,可能會出現一些問題,我暫時還沒遇到問題點,這里備注下。
總結
以上是生活随笔為你收集整理的paramiko执行nohup_记一次使用django+paramiko远程操作时报错无法返回问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: labview实例_手把手以实例教你学L
- 下一篇: 表变量是什么_DAX学习:使用VAR定义