Python 實現遠程服務器批量執行命令


 paramiko 遠程控制介紹

Python paramiko是一個相當好用的遠程登錄模塊,采用ssh協議,可以實現linux服務器的ssh遠程登錄。首先來看一個簡單的例子

import paramiko #實例化ssh客戶端
ssh = paramiko.SSHClient() #創建默認的白名單
policy = paramiko.AutoAddPolicy() #設置白名單
ssh.set_missing_host_key_policy(policy) #鏈接服務器
ssh.connect( hostname = "192.168.2.186", #服務器的ip
    port = 22, #服務器的端口
    username = "root", #服務器的用戶名
    password = "123" #用戶名對應的密碼
) #遠程執行命令
stdin,stdout,stderr = ssh.exec_command("ls") #exec_command 返回的對象都是類文件對象
    #stdin 標准輸入 用於向遠程服務器提交參數,通常用write方法提交
    #stdout 標准輸出 服務器執行命令成功,返回的結果 通常用read方法查看
    #stderr 標准錯誤 服務器執行命令錯誤返回的錯誤值 通常也用read方法 #查看結果,注意在Python3 字符串分為了:字符串和字節兩種格式,文件返回的是字節
result = stdout.read().decode() print(result)

這是一段最簡單的paramiko的代碼,其中比較難理解的就是白名單概念,所謂的白名單就是ssh的know_hosts文件,用來記錄paramiko可以信任的遠程主機,在

paramiko當中,需要生成和采用兩個步驟,來避免在遠程鏈接的時候,被詢問是否信任遠程登錄的服務器。

 

threaing多線程介紹

想要學習多線程,先要明白:

  進程:是程序的一次運行,我們運行一個程序,就會形成一個進程,進程有獨立的內存空間,也被稱為重量級進程。

  線程:線程是進程下的一個分支,也被稱為輕量級進程。

threading是python多線程的基礎模塊,也可以說Python程序員接觸多線程最初接觸的模塊,

我們來看一下threading最基礎的案例

為了好理解我們來了解前置代碼的編寫

最簡單的例子:

 1 from time import sleep
 2 #通過這個例子我們來看計算機正常情況下的執行順序 從左往右,從上到下
 3 def loop0():
 4     print("loop 0 is start")
 5     sleep(3)
 6     print("loop 0 is down")
 7 
 8 def loop1():
 9     print("loop 1 is start")
10     sleep(2)
11     print("loop 1 is down")
12 
13 def main():
14     print("all is start")
15     loop0()
16     loop1()
17     print("all is down")
18 
19 if __name__ == "__main__":
20     main()

代碼優化過的例子:

from time import sleep def loop(num,sleeptime): """ 當前函數作為功能函數 :param num: 函數的編號 :param sleeptime: 睡眠的時間 """
    print("loop %s is start"%num) sleep(sleeptime) print("loop %s is done"%num) def main(): sleep_list = [3,2] #睡眠時間
    lenth = len(sleep_list) #獲取列表長度
    print("all is start") for i in range(lenth): loop(i,sleep_list[i]) #按照列表長度和列表內容調用函數
    print("all is down") if __name__ == "__main__": main()

多線程調用的例子:

 1 import threading
 2 from time import sleep
 3 
 4 def loop(num,sleeptime):
 5     """
 6     當前函數作為功能函數
 7     :param num: 函數的編號
 8     :param sleeptime:  睡眠的時間
 9     """
10     print("loop %s is start"%num)
11     sleep(sleeptime)
12     print("loop %s is done"%num)
13 
14 def main():
15     sleep_list = [3,2] #睡眠時間
16     lenth = len(sleep_list) #獲取列表長度
17     thread_list = []
18     print("all is start")
19     for i in range(lenth):
20         #threading.Thread 就是用線程來執行我們的功能
21         t = threading.Thread(target = loop,args = (i,sleep_list[i])) #按照列表長度和列表內容調用函數
22         thread_list.append(t) #將生成的線程添加到列表里
23     for t in thread_list:
24         t.start() #開始執行線程
25     for t in thread_list:
26         t.join()  #掛起線程,到所有線程結束
27     print("all is down")
28         

通過上面例子的執行,我們需要掌握以幾個點:

  1、threading.Thread方法用來創建線程,線程被創建的時候沒有執行,需要通過start方法執行

  2、多線程調用實際上就是把原有的功能發到線程上面去跑,所以我們使用多線程,功能要寫成函數

  3、Python的多線程是異步並發,而不是大家理解的並行,在這里

    並發:指的是同時出發,不同時執行

    並行:指的是同時進行,不一定同時出發

  希望各位同學注意上面的三點,而值得大家思考的就是上面代碼最后的for循環可以簡化嗎?為啥?

 

paramiko+threading 實現遠程服務器批量執行命令

完成上面的代碼實例,我們進行代碼的整合,完成遠程服務器批量執行命令的效果

 1 #coding:utf-8
 2 
 3 import sys  4 import paramiko  5 import threading  6 
 7 def getConnection(ip,username,password,command,port = 22):  8     """
 9  :param ip: 服務器的ip 10  :param username: 服務器的用戶名稱 11  :param password: 服務器的密碼 12  :param CMD: 服務器的命令 13  :param port: 服務器的端口 14     """
15     ssh = paramiko.SSHClient() 16     policy = paramiko.AutoAddPolicy() 17  ssh.set_missing_host_key_policy(policy) 18  ssh.connect( 19         hostname = ip,  # 服務器的ip
20         port = port,  # 服務器的端口
21         username = username,  # 服務器的用戶名
22         password = password  # 用戶名對應的密碼
23  ) 24     stdin, stdout, stderr = ssh.exec_command(command) 25 
26     result = stdout.read().decode() 27 
28     error = stderr.read().decode() 29 
30     print("+++++++++++++++++++++++start++++++++++++++++++++") 31     print("[connect success] | ip : %s" % ip) 32     print("result: \n %s"%result) 33     if error != " ": 34         print("error: \n %s"%error) 35     print("+++++++++++++++++++++++done++++++++++++++++++++") 36 
37  ssh.close() 38 #我們采用多線程
39 def main(host_list,command): 40     thread_list = [] 41     for ip,username,password in host_list: 42         thread = threading.Thread(target = getConnection, args = (ip,username,password,command)) 43  thread_list.append(thread) 44     for t in thread_list: 45  t.start() 46     for t in thread_list: 47  t.join() 48 
49 
50 if __name__ == "__main__": 51     host_list = [ 52         ("192.168.2.186", "root", "123"), 53         ("192.168.2.88", "root", "123"), 54  ] 55     command = sys.argv[1] 56     main(host_list,command)

在這當中,我們使用了sys.argv方法來接收腳本外面執行的參數,當然,我們也可以將host_list寫到一個配置文件當中使用。執行效果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM