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