1. 程式人生 > 實用技巧 >python 批量ssh並執行命令

python 批量ssh並執行命令

1、安裝paramiko模組

    pip install paramiko

   可以修改ssh連線超時時間,windows下路徑:在安裝路徑Python\Python36\Lib\site-packages\paramiko\transport.py,修改self.banner_timeout = 60(設定ssh超時為60秒)

2、利用python進行ssh

import paramiko,getpass  #getpass是隱藏密碼

def ssh_connect(password):
    host_ip = '192.168.0.150'
    user_name = '
root' host_port ='22' # 待執行的命令 sed_command = "sed -i 's/123/abc/g' /root/test/test.txt" ls_command = "ls /root/test/" # 注意:依次執行多條命令時,命令之間用分號隔開 command = sed_command+";"+ls_command
# SSH遠端連線
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #
指定當對方主機沒有本機公鑰的情況時應該怎麼辦AutoAddPolicy表示自動在對方主機儲存下本機的祕鑰 ssh.connect(host_ip, host_port, user_name, password) # 執行命令並獲取執行結果 stdin, stdout, stderr = ssh.exec_command(command) out = stdout.readlines() err = stderr.readlines()
#關閉連線 ssh.close()
return out,err if __name__
== '__main__': pwd = getpass.getpass("請輸入密碼:")

   #有了密碼,開始呼叫函式

result
= ssh_connect(pwd)
print(result)

python中的paramiko模組是用來實現ssh連線到遠端伺服器上的庫,在進行連線的時候,可以用來執行命令,也可以用來上傳檔案。

1、得到一個連線的物件

在進行連線的時候,可以使用如下的程式碼:

def connect(host):
  ssh = paramiko.SSHClient()
  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  try:
    #ssh.connect(host,username='root',allow_agent=True,look_for_keys=True)

ssh.connect(host,username='root',password='root',allow_agent=True)
return ssh except: return None

在connect函式中,引數是一個主機的IP地址或者是主機名稱,在執行這個方法之後,如果成功的連線到伺服器,那麼就會返回一個sshclient物件。

第一步是建立一個SSHClient的物件,然後設定ssh客戶端允許連線不在know_host檔案中的機器,然後就嘗試連線伺服器。

在連線伺服器的時候,可以使用兩種方式:

(1)方式是使用祕鑰的方式,也就是引數look_for_keys

(2)用設定密碼尋找,也可以直接使用密碼的方式,也就是直接使用引數password,從而最後返回一個連線的物件。

2、 獲取設定的命令

在進行paramiko連線之後,那麼必須要得到需要執行的命令,如下程式碼所示:

def command(args,outpath):
  
  cmd = '%s %s' % (outpath,args)
  return cmd

在引數中,一個是args,一個outpath,args表示命令的引數,而outpath表示為可執行檔案的路徑,例如/usr/bin/ls -l。在其中outpath也就是/usr/bin/ls ,而引數為-l

這個方法主要是用來組合命令,將分開的引數作為命令的一部分進行組裝。

3、 執行命令

在連線過後,可以進行直接執行命令,那麼就有了如下的函式:

def exec_commands(conn,cmd):
  
  stdin,stdout,stderr = conn.exec_command(cmd)
  results=stdout.read()
  return results

在此函式中,傳入的引數一個為連線的物件conn,一個為需要執行的命令cmd,最後得到執行的結果,也就是stdout.read(),最後返回得到的結果

4、 上傳檔案

在使用連線物件的時候,也可以直接進行上傳相關的檔案,如下函式:

def copy_moddule(conn,inpath,outpath):
  
  ftp = conn.open_sftp()
  ftp.put(inpath,outpath)
  ftp.close()
  return outpath

此函式的主要引數為,一個是連線物件conn,一個是上傳的檔名稱,一個上傳之後的檔名稱,在此必須寫入完整的檔名稱包括路徑。

做法主要是開啟一個sftp物件,然後使用put方法進行上傳檔案,最後關閉sftp連線,最後返回一個上傳的檔名稱的完整路徑

5、 執行命令得到結果

最後就是,執行命令,得到返回的結果,如下程式碼:

def excutor(host,outpath,args):
  conn = connect(host)
  if not conn:
    return [host,None]

#呼叫函式 exec_commands(conn,
'chmod +x %s' % outpath)

#呼叫函式,獲得命令引數及其路徑 cmd
=command(args,outpath)

#呼叫函式執行命令 result
= exec_commands(conn,cmd)
print '%r' % result result = json.loads(result) return [host,result]

首先,進行連線伺服器,得到一個連線物件,如果連線不成功,那麼返回主機名和None,表示沒有連線成功,如果連線成功,那麼修改檔案的執行許可權,從而可以執行檔案,然後得到執行的命令,最後,進行執行命令,得到結果,將結果用json格式表示返回,從而結果能得到一個美觀的json格式,最後和主機名一起返回相關的資訊

6、 測試程式碼

測試程式碼如下:

if __name__ == '__main__':
  print json.dumps(excutor('192.168.1.165','ls',' -l'),indent=4,sort_keys=True)
  print copy_module(connect('192.168.1.165'),'kel.txt','/root/kel.1.txt')
  exec_commands(connect('192.168.1.165'),'chmod +x %s' % '/root/kel.1.txt')

第一步測試命令執行,第二步測試上傳檔案,第三部測試修改上傳檔案的許可權。

完整程式碼如下:

#!/usr/bin/env python
import json
import paramiko

def connect(host):
  
  ssh = paramiko.SSHClient()
  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  try:
    #ssh.connect(host,username='root',allow_agent=True,look_for_keys=True)
    ssh.connect(host,username='root',password='root',allow_agent=True)
    return ssh
  except:
    return None

def command(args,outpath):
  
  cmd = '%s %s' % (outpath,args)
  return cmd

def exec_commands(conn,cmd):
  
  stdin,stdout,stderr = conn.exec_command(cmd)
  results=stdout.read()
  return results

def excutor(host,outpath,args):
  conn = connect(host)
  if not conn:
    return [host,None]
  #exec_commands(conn,'chmod +x %s' % outpath)
  cmd =command(args,outpath)
  result = exec_commands(conn,cmd)
  result = json.dumps(result)
  return [host,result]

def copy_module(conn,inpath,outpath):
  
  ftp = conn.open_sftp()
  ftp.put(inpath,outpath)
  ftp.close()
  return outpath


if __name__ == '__main__':
  print json.dumps(excutor('192.168.1.165','ls',' -l'),indent=4,sort_keys=True)
  print copy_module(connect('192.168.1.165'),'kel.txt','/root/kel.1.txt')
  exec_commands(connect('192.168.1.165'),'chmod +x %s' % '/root/kel.1.txt')

Python實現ssh批量登入並執行命令

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

aramiko模組版本

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

python 切換root 執行命令的方法

import paramiko
def create_user(root_pwd,username,password):
  
  result = []
ssh
= paramiko.SSHClient()
#把要連線的機器新增到known_hosts檔案中 ssh.load_system_host_keys() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect( hostname
= settings.HOST, port = settings.PORT, username = settings.USERNAME, password = settings.PASSWORD, timeout = 60, ) sc = ssh.invoke_shell()
#定義函式
def exe_cmd(cmd,t=0.1): sc.send(cmd) sc.send("\n") time.sleep(t) resp = sc.recv(9999).decode("utf8") #print "cmd='%s',echo='%s'\n"%(cmd,resp) return resp #切換root賬號 resp = exe_cmd("su root",t=1) if resp.endswith(u"密碼:"): resp = exe_cmd(root_pwd) #建立使用者 cmd_create_user = "useradd {username} -d /home/{username}".format( username = username, ) exe_cmd(cmd_create_user) #修改密碼 cmd_change_user_pwd = """echo "{password}" | passwd --stdin {username}""".format( username = username, password = password, ) exe_cmd(cmd_change_user_pwd)

Python實現SSH遠端登陸,並執行命令的方法

import paramiko 
 
def sshclient_execmd(hostname, port, username, password, execmd): 
paramiko.util.log_to_file(
"paramiko.log") s = paramiko.SSHClient() s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#連線 s.connect(hostname
=hostname, port=port, username=username, password=password)

#執行 stdin, stdout, stderr
= s.exec_command (execmd) stdin.write("Y") # Generally speaking, the first connection, need a simple interaction. print stdout.read() s.close() def main(): hostname = '10.***.***.**' port = 22 username = 'root' password = '******' execmd = "free"
#呼叫函式 sshclient_execmd(hostname, port, username, password, execmd)
if __name__ == "__main__": main()

Python 實現遠端伺服器(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+threading 實現遠端伺服器批量執行命令

 #coding:utf-8
 
 import sys
 import paramiko
 import threading
 
 def getConnection(ip,username,password,command,port = 22):
#例項化物件 ssh = paramiko.SSHClient() policy = paramiko.AutoAddPolicy() ssh.set_missing_host_key_policy(policy)

#連線 ssh.connect( hostname
= ip, # 伺服器的ip port = port, # 伺服器的埠 username = username, # 伺服器的使用者名稱 password = password # 使用者名稱對應的密碼 )

#執行 stdin, stdout, stderr
= ssh.exec_command(command) result = stdout.read().decode() error = stderr.read().decode() print("+++++++++++++++++++++++start++++++++++++++++++++") print("[connect success] | ip : %s" % ip) print("result: \n %s"%result) if error != " ": print("error: \n %s"%error) print("+++++++++++++++++++++++done++++++++++++++++++++") ssh.close()


#我們採用多執行緒 def main(host_list,command): thread_list = []
for ip,username,password in host_list:
thread
= threading.Thread(target = getConnection, args = (ip,username,password,command)) thread_list.append(thread)
for t in thread_list: t.start() for t in thread_list: t.join() if __name__ == "__main__": host_list = [ ("192.168.2.186", "root", "123"), ("192.168.2.88", "root", "123"), ] command = sys.argv[1] main(host_list,command)

    

#單執行緒執行

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



#多執行緒執行

 import threading
 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) #獲取列表長度
thread_list = [] print("all is start") for i in range(lenth):
#threading.Thread 就是用執行緒來執行我們的功能 t = threading.Thread(target = loop,args = (i,sleep_list[i])) #按照列表長度和列表內容呼叫函式 thread_list.append(t) #將生成的執行緒新增到列表裡
for t in thread_list: t.start() #開始執行執行緒 for t in thread_list: t.join() #掛起執行緒,到所有執行緒結束 print("all is down")