ssh批量登入並執行命令(python實現)

2021-06-09 04:58:42 字數 3496 閱讀 5574

來自 www.cnblogs.com/ma6174/archive/2012/05/25/2508378.html  

區域網內有一百多臺電腦,全部都是linux作業系統,所有電腦配置相同,系統完全相同(包括使用者名稱和密碼),ip位址是自動分配的。現在有個任務是在這些電腦上執行某些命令,者說進行某些操作,比如安裝某些軟體,拷貝某些檔案,批量關機等。如果一台一台得手工去操作,費時又費力,如果要進行多個操作就更麻煩啦。

或許你會想到網路同傳, 網路同傳是什麼?就是在一台電腦上把電腦裝好,配置好,然後利用某些軟體,如「聯想網路同傳」把系統原樣拷貝過去,在裝系統時很有用,只要在一台電腦上裝好,同傳以後所有的電腦都裝好作業系統了,很方便。同傳要求所有電腦硬體完全相同,在聯想的電腦上裝的系統傳到方正電腦上肯定會出問題的。傳系統也是很費時間的,根據硬碟大小,如果30g硬碟,100多台電腦大約要傳2個多小時,反正比一台一台地安裝快!但是如果系統都傳完了,發現忘了裝乙個軟體,或者還需要做些小修改,再同傳一次可以,但是太慢,傳兩次半天時間就沒了。這時候我們可以利用ssh去控制每台電腦去執行某些命令。

先讓我們回憶一下ssh遠端登入的過程:首先執行命令 ssh [email protected] ,第一次登入的時候系統會提示我們是否要繼續連線,我們要輸入「yes」,然後等一段時間後系統提示我們輸入密碼,正確地輸入密碼之後我們就能登入到遠端計算機,然後我們就能執行命令了。我們注意到這裡面有兩次人機互動,一次是輸入『yes』,另一次是輸入密碼。就是因為有兩次互動我們不能簡單的用某些命令去完成我們的任務。我們可以考慮把人機互動變成自動互動,python的pexpect模組可以幫我們實現自動互動。下面這段**是用pexpect實現自動互動登入並執行命令的函式:

!/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模組我們可以做很多事情,由於他提供了自動互動功能,因此我們可以實現ftp,telnet,ssh,scp等的自動登入,還是比較實用的。根據上面的**相信讀者已經知道怎麼實現了(python就是那麼簡單!)。

用上面的**去完成任務還是比較費時間的,因為程式要等待自動互動出現,另外ubuntu用ssh連線就是比較慢,要進行一系列的驗證,這樣才體現出ssh的安全。我們要提高效率,在最短的時間內完成。後來我發現了python裡面的paramiko模組,用這個實現ssh登入更加簡單。看下面的**:

-*- 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!

'] #

你要執行的命令列表

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() 

上面的程式還是有些技巧的:

1.利用多執行緒,同時發出登入請求,同時去連線電腦,這樣速度快很多,我試了一下,如果不用多執行緒,直接乙個乙個挨著執行的話,大約5~10秒鐘才能對一台電腦操作完,具體時間要根據命令的來決定,如果是軟體安裝或者解除安裝時間要更長一些。這樣下來怎麼也要一二十分鐘,用多執行緒後就快多了,所有的命令執行完用了不到2分鐘!

2.最好用root使用者登入,因為安裝或者解除安裝軟體的時候如果用普通使用者又會提示輸入密碼,這樣又多了一次互動,處理起來就比較麻煩!安裝軟體時apt-get install *** 最好加上「-y」引數,因為有時安裝或刪除軟體時提示是否繼續安裝或解除安裝,這又是一次自動互動!加上那個引數後就沒有人機互動了。

3. 迴圈時迴圈所有ip,因為計算機的ip是路由器自動分配的,保險起見,最好全部都執行,保證沒有遺漏的主機

4.遠端執行命令時如果有互動,可以這樣用 stdin.write("y")來完成互動,「y」就是輸入「y」。

5.把所有的命令放到乙個列表裡面,遍歷列表可以依次執行列表裡面的命令

6.為了更好的進行控制,最好在電腦上提前把root使用者開啟,裝好ssh伺服器並讓其開機自動執行。

ssh批量登入並執行命令(python實現)

人生苦短,我用python!區域網內有一百多臺電腦,全部都是linux作業系統,所有電腦配置相同,系統完全相同 包括使用者名稱和密碼 ip位址是自動分配的。現在有個任務是在這些電腦上執行某些命令,者說進行某些操作,比如安裝某些軟體,拷貝某些檔案,批量關機等。如果一台一台得手工去操作,費時又費力,如果...

shell實現ssh登入並執行命令

使用expect可以不用輸入密碼,避免重複勞動。那什麼是expect?查了一下,expect是乙個免費的程式設計工具,用來實現自動的互動式任務,而無需人為干預。說白了,expect就是一套用來實現自動互動功能的軟體。在實際工作中,我們執行命令 指令碼或程式時,這些命令 指令碼或程式都需要從終端輸入某...

shell實現ssh登入並執行命令

最近搞灰度發布,機器太多了,四個國家,每個國家兩台機器,啟停應用很費時間,所有打算寫個shell指令碼來提高效率 偷懶 使用expect可以不用輸入密碼,避免重複勞動。那什麼是expect?查了一下,expect是乙個免費的程式設計工具,用來實現自動的互動式任務,而無需人為干預。說白了,expect...