首頁 > 軟體

python中windows連結linux執行命令並獲取執行狀態的問題小結

2022-11-13 14:00:52

前言

最新需要做一個小工具,讓共同作業部門能夠獲取到伺服器上的一些資源訊息,因為工具是pyqt寫的所以牽扯到用python連結linux的問題,這裡記錄一下一些碰到的問題

環境

工具

  • pycharm
  • qt designer

  • python3.7
  • pyqt5.15.4
  • paramiko2.12.0

上網搜了很多,發現paramiko實現遠端SSH連結非常的方便,作為python的第三方庫安裝也很方便

pip install paramiko

內容彙總

建立SSHClient

ssh = paramiko.SSHClient()

首先通過paramiko建立SSHClient類,SSHClient類封裝了連結SSH和傳送命令等方法

設定連結主機後的策略

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

設定在連線到沒有已知主機金鑰的伺服器時使用的策略,有三種情況,一般直接用Auto,會將遠端主機的祕鑰新增到known_hosts檔案中

連結遠端主機

ssh.connect(ip, port, username, password)
  • ip:遠端主機地址
  • port:埠預設22
  • username:存取主機的使用者名稱
  • password:存取主機的使用者密碼

通過connect連結

傳送命令

cmd = "python /work/tools/build_project.py"
stdin, stdout, stderr = ssh.exec_command(cmd)
  • stdin:輸入內容(用來互動)
  • stdout:執行命令linux控制檯的輸出內容
  • stderr:執行失敗後的資訊

我們通過exec_command方法在連結成功後向主機傳送命令,有三個返回引數

獲取linux的輸出內容

stdin, stdout, stderr = ssh.exec_command(cmd)
successResult = stdout.read()
errorResult = stdout.read()

可以通過read的方法獲取到linux控制檯的輸出資訊

問題總結

在實際運用的時候,碰到了不少問題,如下:

  • 順序執行多條命令的時候,後邊的命令不生效
  • 非瞬時命令執行是,read在第一時間拿不到輸出入職

這兩個問題在實際執行的時候會造成很大的問題,比如下面的情況:

cd /work
git pull
cd tools
python test.py

同時執行多條命令的時候,因為git pull是一個非瞬時完成的命令,所有後邊的命令都沒有生效,並且read也拿不到控制檯的資訊,想了想可以通過延時呼叫的方式去初始,time.sleep(1),這個樣子,但是很不優雅,因為時間是不固定的,這樣做也很不保險

解決方式

搜尋查詢了一下,找到了相關問題的解決方式,在exec_command返回引數stdout內有一個channel類,channel可以內可以接收遠端主機的狀態,就是exit_status_ready(),當遠端主機執行結束後,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

如上述程式碼所示,在傳送命令後,在while迴圈去判斷遠端注意執行狀態,當執行狀態結束時,返還所有接收到的資訊

演示

下述為完整程式碼演示, 為了方便執行多條命令,這裡直接呼叫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)

如上述程式碼所示,兩個指令碼的配合,就可以實現多命令的遠端呼叫和回執,另外建議ssh的操作都放到子執行緒裡去處理,這樣就不會卡著主執行緒了

推播

Github

https://github.com/KingSun5

到此這篇關於python中windows連結linux執行命令並獲取執行狀態的文章就介紹到這了,更多相關python執行linux命令內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com