Python實現(xiàn)ssh批量登錄并執(zhí)行命令
局域網(wǎng)內(nèi)有一百多臺電腦,全部都是linux操作系統(tǒng),所有電腦配置相同,系統(tǒng)完全相同(包括用戶名和密碼),ip地址是自動分配的?,F(xiàn)在有個任務(wù)是在這些電腦上執(zhí)行某些命令,者說進行某些操作,比如安裝某些軟件,拷貝某些文件,批量關(guān)機等。如果一臺一臺得手工去操作,費時又費力,如果要進行多個操作就更麻煩啦。
或許你會想到網(wǎng)絡(luò)同傳,網(wǎng)絡(luò)同傳是什么?就是在一臺電腦上把電腦裝好,配置好,然后利用某些軟件,如“聯(lián)想網(wǎng)絡(luò)同傳”把系統(tǒng)原樣拷貝過去,在裝系統(tǒng)時很有用,只要在一臺電腦上裝好,同傳以后所有的電腦都裝好操作系統(tǒng)了,很方便。同傳要求所有電腦硬件完全相同,在聯(lián)想的電腦上裝的系統(tǒng)傳到方正電腦上肯定會出問題的。傳系統(tǒng)也是很費時間的,根據(jù)硬盤大小,如果30G硬盤,100多臺電腦大約要傳2個多小時,反正比一臺一臺地安裝快!但是如果系統(tǒng)都傳完了,發(fā)現(xiàn)忘了裝一個軟件,或者還需要做些小修改,再同傳一次可以,但是太慢,傳兩次半天時間就沒了。這時候我們可以利用ssh去控制每臺電腦去執(zhí)行某些命令。
先讓我們回憶一下ssh遠程登錄的過程:首先執(zhí)行命令 ssh username@192.168.1.x ,第一次登錄的時候系統(tǒng)會提示我們是否要繼續(xù)連接,我們要輸入“yes”,然后等一段時間后系統(tǒng)提示我們輸入密碼,正確地輸入密碼之后我們就能登錄到遠程計算機,然后我們就能執(zhí)行命令了。我們注意到這里面有兩次人機交互,一次是輸入‘yes',另一次是輸入密碼。就是因為有兩次交互我們不能簡單的用某些命令去完成我們的任務(wù)。我們可以考慮把人機交互變成自動交互,python的pexpect模塊可以幫我們實現(xiàn)自動交互。下面這段代碼是用pexpect實現(xiàn)自動交互登錄并執(zhí)行命令的函數(shù):
#!/usr/bin/env python # -*- coding: utf-8 -*- import pexpect def ssh_cmd(ip, passwd, cmd): ret = -1 ssh = pexpect.spawn('ssh root@%s "%s"' % (ip, cmd)) try: i = ssh.expect(['password:', 'continue connecting (yes/no)?'], timeout=5) if i == 0 : ssh.sendline(passwd) elif i == 1: ssh.sendline('yes\n') ssh.expect('password: ') ssh.sendline(passwd) ssh.sendline(cmd) r = ssh.read() print r ret = 0 except pexpect.EOF: print "EOF" ssh.close() ret = -1 except pexpect.TIMEOUT: print "TIMEOUT" ssh.close() ret = -2 return ret
利用pexpect模塊我們可以做很多事情,由于他提供了自動交互功能,因此我們可以實現(xiàn)ftp,telnet,ssh,scp等的自動登錄,還是比較實用的。根據(jù)上面的代碼相信讀者已經(jīng)知道怎么實現(xiàn)了(python就是那么簡單!)。
用上面的代碼去完成任務(wù)還是比較費時間的,因為程序要等待自動交互出現(xiàn),另外ubuntu用ssh連接就是比較慢,要進行一系列的驗證,這樣才體現(xiàn)出ssh的安全。我們要提高效率,在最短的時間內(nèi)完成。后來我發(fā)現(xiàn)了python里面的paramiko模塊,用這個實現(xiàn)ssh登錄更加簡單??聪旅娴拇a:
#-*- coding: utf-8 -*- #!/usr/bin/python import paramiko import threading def ssh2(ip,username,passwd,cmd): try: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip,22,username,passwd,timeout=5) for m in cmd: stdin, stdout, stderr = ssh.exec_command(m) # stdin.write("Y") #簡單交互,輸入 ‘Y' out = stdout.readlines() #屏幕輸出 for o in out: print o, print '%s\tOK\n'%(ip) ssh.close() except : print '%s\tError\n'%(ip) if __name__=='__main__': cmd = ['cal','echo hello!']#你要執(zhí)行的命令列表 username = "" #用戶名 passwd = "" #密碼 threads = [] #多線程 print "Begin......" for i in range(1,254): ip = '192.168.1.'+str(i) a=threading.Thread(target=ssh2,args=(ip,username,passwd,cmd)) a.start()
上面的程序還是有些技巧的:
- 利用多線程,同時發(fā)出登錄請求,同時去連接電腦,這樣速度快很多,我試了一下,如果不用多線程,直接一個一個挨著執(zhí)行的話,大約5~10秒鐘才能對一臺電腦操作完,具體時間要根據(jù)命令的來決定,如果是軟件安裝或者卸載時間要更長一些。這樣下來怎么也要一二十分鐘,用多線程后就快多了,所有的命令執(zhí)行完用了不到2分鐘!
- 最好用root用戶登錄,因為安裝或者卸載軟件的時候如果用普通用戶又會提示輸入密碼,這樣又多了一次交互,處理起來就比較麻煩!安裝軟件時apt-get install xxx 最好加上“-y”參數(shù),因為有時安裝或刪除軟件時提示是否繼續(xù)安裝或卸載,這又是一次自動交互!加上那個參數(shù)后就沒有人機交互了。
- 循環(huán)時循環(huán)所有ip,因為計算機的ip是路由器自動分配的,保險起見,最好全部都執(zhí)行,保證沒有遺漏的主機
- 遠端執(zhí)行命令時如果有交互,可以這樣用 stdin.write("Y")來完成交互,“Y”就是輸入“Y”。
- 把所有的命令放到一個列表里面,遍歷列表可以依次執(zhí)行列表里面的命令
- 為了更好的進行控制,最好在電腦上提前把root用戶打開,裝好ssh服務(wù)器并讓其開機自動執(zhí)行。
希望本文所述對你有所幫助,Python實現(xiàn)ssh批量登錄并執(zhí)行命令內(nèi)容就給大家介紹到這里了。希望大家繼續(xù)關(guān)注我們的網(wǎng)站!想要學習Python可以繼續(xù)關(guān)注本站。
相關(guān)文章
python程序運行添加命令行參數(shù)argparse模塊具體用法詳解
這篇文章主要給大家介紹了關(guān)于python程序運行添加命令行參數(shù)argparse模塊具體用法的相關(guān)資料,argparse是Python內(nèi)置的一個用于命令項選項與參數(shù)解析的模塊,通過在程序中定義好我們需要的參數(shù),需要的朋友可以參考下2024-01-01Python semaphore evevt生產(chǎn)者消費者模型原理解析
這篇文章主要介紹了Python semaphore evevt生產(chǎn)者消費者模型原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03利用Python實現(xiàn)字幕掛載(把字幕文件與視頻合并)思路詳解
這篇文章主要介紹了如何利用Python實現(xiàn)字幕掛載,把字幕文件與視頻合并,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10詳解PyCharm使用pyQT5進行GUI開發(fā)的基本流程
本文主要介紹了PyCharm使用pyQT5進行GUI開發(fā)的基本流程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10Python如何應用cx_Oracle獲取oracle中的clob字段問題
今天小編就為大家分享一篇Python如何應用cx_Oracle獲取oracle中的clob字段問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python 實現(xiàn)「食行生鮮」簽到領(lǐng)積分功能
今天我們就用 Python 來實現(xiàn)自動簽到,省得我每天打開 APP 來操作了。感興趣的朋友跟隨小編一起看看吧2018-09-09