python中windows鏈接linux執(zhí)行命令并獲取執(zhí)行狀態(tài)的問題小結(jié)
前言
最新需要做一個小工具,讓協(xié)作部門能夠獲取到服務(wù)器上的一些資源訊息,因為工具是pyqt寫的所以牽扯到用python鏈接linux的問題,這里記錄一下一些碰到的問題
環(huán)境
工具
- pycharm
- qt designer
庫
- python3.7
- pyqt5.15.4
- paramiko2.12.0
上網(wǎng)搜了很多,發(fā)現(xiàn)paramiko實現(xiàn)遠(yuǎn)程SSH鏈接非常的方便,作為python的第三方庫安裝也很方便
pip install paramiko
內(nèi)容匯總
創(chuàng)建SSHClient
ssh = paramiko.SSHClient()
首先通過paramiko創(chuàng)建SSHClient類,SSHClient類封裝了鏈接SSH和發(fā)送命令等方法
設(shè)置鏈接主機(jī)后的策略
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
設(shè)置在連接到?jīng)]有已知主機(jī)密鑰的服務(wù)器時使用的策略,有三種情況,一般直接用Auto,會將遠(yuǎn)程主機(jī)的秘鑰添加到known_hosts文件中
鏈接遠(yuǎn)程主機(jī)
ssh.connect(ip, port, username, password)
- ip:遠(yuǎn)程主機(jī)地址
- port:端口默認(rèn)22
- username:訪問主機(jī)的用戶名
- password:訪問主機(jī)的用戶密碼
通過connect鏈接
發(fā)送命令
cmd = "python /work/tools/build_project.py" stdin, stdout, stderr = ssh.exec_command(cmd)
- stdin:輸入內(nèi)容(用來交互)
- stdout:執(zhí)行命令linux控制臺的輸出內(nèi)容
- stderr:執(zhí)行失敗后的信息
我們通過exec_command方法在鏈接成功后向主機(jī)發(fā)送命令,有三個返回參數(shù)
獲取linux的輸出內(nèi)容
stdin, stdout, stderr = ssh.exec_command(cmd) successResult = stdout.read() errorResult = stdout.read()
可以通過read的方法獲取到linux控制臺的輸出信息
問題總結(jié)
在實際運(yùn)用的時候,碰到了不少問題,如下:
- 順序執(zhí)行多條命令的時候,后邊的命令不生效
- 非瞬時命令執(zhí)行是,read在第一時間拿不到輸出入職
這兩個問題在實際運(yùn)行的時候會造成很大的問題,比如下面的情況:
cd /work git pull cd tools python test.py
同時執(zhí)行多條命令的時候,因為git pull是一個非瞬時完成的命令,所有后邊的命令都沒有生效,并且read也拿不到控制臺的信息,想了想可以通過延時調(diào)用的方式去初始,time.sleep(1),這個樣子,但是很不優(yōu)雅,因為時間是不固定的,這樣做也很不保險
解決方式
搜索查找了一下,找到了相關(guān)問題的解決方式,在exec_command返回參數(shù)stdout內(nèi)有一個channel類,channel可以內(nèi)可以接收遠(yuǎn)端主機(jī)的狀態(tài),就是exit_status_ready(),當(dāng)遠(yuǎn)端主機(jī)執(zhí)行結(jié)束后,exit_status_ready()就是true,如此就方便處理了
stdin, stdout, stderr = ssh.exec_command(s_cmd, get_pty=True)
result = ""
while not stdout.channel.exit_status_ready():
result = result + stdout.readline()
if stdout.channel.exit_status_ready():
break如上述代碼所示,在發(fā)送命令后,在while循環(huán)去判斷遠(yuǎn)端注意執(zhí)行狀態(tài),當(dāng)執(zhí)行狀態(tài)結(jié)束時,返還所有接收到的信息
演示
下述為完整代碼演示, 為了方便執(zhí)行多條命令,這里直接調(diào)用shell腳本
#!/bin/bash project_path="/works" cd $project_path # 清理 git clean -f git checkout * # 拉代碼 git pull cd tools python build_android.py
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.x.xxx', 22, "root", 123456)
s_cmd = "sh /work/tools/ssh/build_android.sh"
stdin, stdout, stderr = ssh.exec_command(s_cmd, get_pty=True)
result = ""
while not stdout.channel.exit_status_ready():
result = result + stdout.readline()
if stdout.channel.exit_status_ready():
break
print(result)如上述代碼所示,兩個腳本的配合,就可以實現(xiàn)多命令的遠(yuǎn)程調(diào)用和回執(zhí),另外建議ssh的操作都放到子線程里去處理,這樣就不會卡著主線程了
推送
Github
到此這篇關(guān)于python中windows鏈接linux執(zhí)行命令并獲取執(zhí)行狀態(tài)的文章就介紹到這了,更多相關(guān)python執(zhí)行l(wèi)inux命令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 循環(huán)結(jié)構(gòu)練習(xí)題
這篇文章主要給大家分享的是python 循環(huán)結(jié)構(gòu)練習(xí)題,求兩個數(shù)最大公約數(shù)、整數(shù)反轉(zhuǎn):如12345,輸出54321等多個練習(xí)題,需要的朋友可以參考一下2021-11-11
python pandas dataframe如何獲取除了指定列以外的所有列
這篇文章主要介紹了python pandas dataframe如何獲取除了指定列以外的所有列問題,具有很好的參考價值,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
12個Pandas/NumPy中的加速函數(shù)使用總結(jié)
在本文中,數(shù)據(jù)和分析工程師?Kunal?Dhariwal?為我們介紹了?12?種?Numpy?和?Pandas?函數(shù),這些高效的函數(shù)會令數(shù)據(jù)分析更為容易、便捷2022-09-09
一篇文章帶你學(xué)習(xí)Python3的高級特性(2)
這篇文章主要為大家詳細(xì)介紹了Python3的高階函數(shù),主要介紹什么是高級特性,高級特性的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
利用Python的tkinter模塊實現(xiàn)界面化的批量修改文件名
這篇文章主要介紹了利用Python的tkinter模塊實現(xiàn)界面化的批量修改文件名,用Python編寫過批量修改文件名的腳本程序,代碼很簡單,運(yùn)行也比較快,詳細(xì)內(nèi)容需要的小伙伴可以參考一下下面文章內(nèi)容2022-08-08
Python進(jìn)行指數(shù)和對數(shù)曲線擬合詳解
曲線擬合是構(gòu)造曲線或數(shù)學(xué)函數(shù)的過程,其具有對一系列數(shù)據(jù)點的最佳擬合,可能受到約束,本文主要介紹了如何使用Python實現(xiàn)指數(shù)和對數(shù)曲線擬合,需要的可以參考下2024-04-04
python 定時器每天就執(zhí)行一次的實現(xiàn)代碼
這篇文章主要介紹了python 定時器每天就執(zhí)行一次的實現(xiàn)代碼,代碼簡單易懂非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08
Django和websocket實現(xiàn)簡單的多人聊天的示例代碼
本文主要介紹了使用Django和WebSocket實現(xiàn)一個簡單的多人聊天應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01

