需求:
1.主机信息配置文件用configparser解析
2.可批量执行命令,上传文件,结果实时返回
3.主机用户名密码、端口可以不同
4.执行远程命令使用paramiko模块
5.多台主机链接创建多个进程并发,单台主机上的多条执行命令使用多线程并发
一、安装模块
paramiko模块是遵循python模块标准的openssh协议模块,可以使用pip快速安装。
首先需安装pip工具,windows的python安装包一般没有集成pip,需单独安装
下载pip源码包:
https://pypi.python.org/pypi/pip#downloads
打开windows cmd,打开后进入
解压源码包后进入源目录
执行:
python setup.py install
安装完成后,pip安装paramiko
pip install paramiko
安装成功后,开始code
二、生成配置文件:
def addhost():
while True:
num=input('Add host to conf.ini,Input last num,or q|Q to continue :')
if num== 'q' or 'Q':
break
else:
ip=str('192.168.0.%s'%num)
config.add_section(ip)
config.set(ip,'username','root')
config.set(ip,'password','xxxxxxxxxxx')
config.write(sys.stdout)
config.write(open('sample.ini','w'))
addhost()
密码正好是统一的不用改了。生成配置文件如下:
三、加载配置文件,连接主机执行命令,所有代码如下:
from multiprocessing import Process
import configparser,sys,threading,os
import paramiko
config=configparser.ConfigParser()
config.read(u'sample.ini')
host_list=config.sections()
'''
configparser用法:
#config.set('section','username','root') #给大标题内的key赋值
# print(config.get("size","size")) #查看大标题内的指定小标题
# print(config.sections() ) #查看所有section大标题
'''
def addhost():
while True:
num=input('\033[0;32mAdd host to conf.ini,Input last num,or q|Q to continue :\033[0m')
if num== 'q' or 'Q':
break
else:
ip=str('192.168.0.%s'%num)
config.add_section(ip)
config.set(ip,'username','root')
config.set(ip,'password','yinwenqin')
config.write(sys.stdout)
config.write(open('sample.ini','w'))
def ssh_conn(host,cmd_list):
usr=config.get(host,'username')
passwd=config.get(host,'password')
print('\033[1;32mProcess ID:\033[0m',os.getpid())
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname=host, port=22, username=usr, password=passwd)
for c in cmd_list:
t=threading.Thread(target=exec,args=(host,ssh,c,))
#将连接实例传递给线程执行
t.start()
t.join()
ssh.close()
def exec(host,ssh,c):
stdin, stdout, stderr = ssh.exec_command(c) # 执行命令,分别保存标准输入、标准输出、标准错误结果到变量
# 获取命令结果
result = stdout.read().decode()
print('\033[1;33mExec thread ID:\033[0m',threading.current_thread())
print('\033[1;33mHost %s exec cmd <<%s>> result>>:\033[0m' %(host,c))
print(result)
def sftp_conn(host,cmd_list):
usr=config.get(host,'username')
passwd=config.get(host,'password')
print('\033[1;32mProcess ID:\033[0m',os.getpid())
transport = paramiko.Transport((host,22))
transport.connect(username=usr,password=passwd)
sftp = paramiko.SFTPClient.from_transport(transport)
filename_list=cmd_list[1:]
for file in filename_list:
if cmd_list[0] == 'put':
t=threading.Thread(target=put,args=(host,sftp,file,))
t.start()
t.join()
elif cmd_list[0] == 'get':
t=threading.Thread(target=get,args=(host,sftp,file,))
t.start()
t.join()
transport.close()
def put(host,sftp,file):
sftp.put(file,'/root/%s' %file)
print('\033[1;33mExec thread ID:\033[0m',threading.current_thread())
print('\033[1;33mHost %s exec cmd <<put %s>> result>>:\033[0m' %(host,file))
print('\033[1;33mFile info:\033[0m \n',os.stat(file))
def get(host,sftp,file):
sftp.get('/root/%s' %file, 'D:\Python\Myscript\process & threading\%s' %file)
print('\033[1;33mExec thread ID:\033[0m',threading.current_thread())
print('\033[1;33mHost %s exec cmd << get %s>> result>>:\033[0m' %(host,file))
print('\033[1;33mFile info:\033[0m \n',os.stat('D:\Python\Myscript\process & threading\%s' %file))
if __name__ == '__main__':
addhost()
while True:
try:
print('\033[0;31mHosts list:\033[0m')
print(host_list)
choice=input('\033[0;32mChoose host to login:( divide multi hosts by space ):\033[0m \n')
if len(choice)==0:continue
choice_list=choice.split()
print(choice_list)
choice2=input('\033[0;32m 1.Exec cmd \n2.Put/get file \nPlease choose \033[0m \n ')
print(choice2)
cmd=input('\033[0;32mInput cmd ( <;> to devide cmds , <space> to divide files ):\033[0m \n')
print(cmd)
if int(choice2) == 1:
cmd_list=cmd.split(';') #use ';' to devide cmd str
for i in choice_list:
print(i)
p=Process(target=ssh_conn,args=(i,cmd_list))
p.start()
p.join()
elif int(choice2) == 2:
cmd_list=cmd.split() #use ';' to devide cmd str
for i in choice_list:
print(i)
p=Process(target=sftp_conn,args=(i,cmd_list))
p.start()
p.join()
except Exception as e:
print('Error:',e)
实现了批量连接多个主机,在每个主机上同时执行多条命令,上传或下载多个文件。
运行效果:
老爷本开8台虚拟机一个IDE跑了这么久不容易啊,快热炸了,路过顶一下再走呗~