一家中型公司,全国各省近2000台服务器竟然没有一个运维平台,我也是醉了,每天挨个挨个登陆机器,管理机器真是操蛋,为此自己工作之余借助paramiko模块写了一个批量执行命令,上传下载文件的脚本,写的代码烂到哭,但最起码还能凑合着用吧。
使用环境是python2.6-2.7,其中要在当前目录下生成一个ssh_login.txt文件,它是用户保存登陆用户名和密码以及主机名的文件,格式如下:
主机名,端口,用户名,验证方式是公私钥认证还是密码验证,密码, #每行以逗号结尾,不允许有空行,
172.168.19.25,22,root,password,xxxxx, 172.168.19.26,22,root,password,xxxxx,
脚本源码如下,使用方法是:
python 脚本名 [ -c command] -m put/down -l local_file_path -r remote_file_path
-c 的话是批量执行命令,此时上传下载功能将不使用。
-m是指定模式,是下载还是上传
-l 是指定本地文件路径
-r 是远端文件路径,必须是绝对路径,要写出文件名来。
-h 是捕获帮助信息。
比如我现在要批量执行命令 -- python xxx.py -c "uptime; df -hT"
比如我现在要批量上传文件 -- python xxx.py -m put -l /tmp/123.txt -r /tmp/123.txt
比如我现在要批量下载文件 -- python xxx.py -m down -l /tmp/123.txt -r /tmp/123.txt
这里要注意的是,如果是下载模式,那么下载后的文件格式是这样的 文件名_主机ip
如果运行出错了,那么会在当前目录下生成一个error.log,这里记录了如主机登陆不上或者是无法连接等错误信息。
默认启动10个进程,粘贴复制的时候可能把缩进对齐给弄乱了,如果有疑问,可以联系我的email:[email protected]
#/usr/bin/env python import paramiko import sys import os import getopt import multiprocessing import time import socket pkey_file='/root/.ssh/id_rsa' if os.path.exists('ssh_login.txt') is not True: print '\033[31mNo such the ssh_login.txt\033[0m' sys.exit() def ssh_connect(cmd,line,host): s = paramiko.SSHClient() s.set_missing_host_key_policy(paramiko.AutoAddPolicy()) s.load_system_host_keys() #paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG) 输出#paramiko调试信息 port=int(line.split(',')[1]) user=line.split(',')[2] auth_method=line.split(',')[3] if auth_method=='password': password=line.split(',')[4] s.connect(host,port,user,password,timeout=3) else: key = paramiko.RSAKey.from_private_key_file(pkey_file) s.connect(host,port,user,key,timeout=3) stdin,stdout,stderr = s.exec_command(cmd) result = stdout.read(),stderr.read() print '\033[32m='*25+"the result from ",host+"\033[32m=\033[0m"*25 for a in result: print a s.close() def sftp_put(line,host,lfile,rfile): port=int(line.split(',')[1]) user=line.split(',')[2] auth_method=line.split(',')[3] if auth_method=='password': try: passwd=line.split(',')[4] t = paramiko.Transport((host,port)) t.connect(username=user,password=passwd) sftp=paramiko.SFTPClient.from_transport(t) sftp.put(lfile,rfile) print "\033[32m I put %s to %s now,please waite a moment .....\033[0m\n"%(lfile,host) print sftp.stat(rfile) t.close(); except (IOError): print host,"\033[31m -- Must be input remote file absolute path!!\033[0m"
else:
try: key=paramiko.RSAKey.from_private_key_file(pkey_file) t=paramiko.Transport((host,port)) t.connect(username=user,pkey=key) sftp=paramiko.SFTPClient.from_transport(t) sftp.put(lfile,rfile) print "\033[32m I put %s to %s now,please waite a moment .....\033[0m\n"%(lfile,host) print sftp.stat(rfile) t.close(); except (IOError): print host,"\033[31m -- Must be input remote file absolute path!!\033[0m" def sftp_down(line,host,rfile,lfile): port=int(line.split(',')[1]) user=line.split(',')[2] auth_method=line.split(',')[3] if auth_method=='password': try: passwd=line.split(',')[4] t = paramiko.Transport((host,port)) t.connect(username=user,password=passwd) sftp=paramiko.SFTPClient.from_transport(t) sftp.get(rfile,lfile) os.rename(lfile,lfile+"_"+host) print "\033[32m I down %s from %s now,please waite a moment .....\033[0m"%(rfile,host) print sftp.stat(rfile) t.close(); except (IOError): print host,"\033[31m -- Must be input remote file absolute path!!\033[0m" else: try: key=paramiko.RSAKey.from_private_key_file(pkey_file) t=paramiko.Transport((host,port)) t.connect(username=user,pkey=key) sftp=paramiko.SFTPClient.from_transport(t) sftp.get(rfile,lfile) os.rename(lfile,lfile+'_'+host) print "\033[32m I down %s from %s now,please waite a moment .....\033[0m"%(rfile,host) print sftp.stat(rfile) t.close(); except (IOError): print host,"\033[31m -- Must be input remote file absolute path!!\033[0m" #main_program p=multiprocessing.Pool(processes=10) opts,args=getopt.getopt(sys.argv[1:],"c:m:h:r:l:") opts=dict(opts) cmd=opts.get('-c') #捕获-c这个参数 pd=opts.get('-m') #捕获-m这个参数,下面的一样 l_file=opts.get('-l') r_file=opts.get('-r') help=opts.get('-h') if help is not None: print "\033[35mUseag: %s [ -c command] -m put/down -l local_file_path -r remote_file_path\033[0m" %sys.argv[0] result=[] if cmd is not None: login_info=open('ssh_login.txt','r') err_log=open('error.log','a') err_log.write('='*30+'this is last result'+'='*30+'\n') for line in login_info: try: host=line.split(',')[0] result.append(p.apply_async(ssh_connect,(cmd,line,host,))) except BaseException,e: print "\033[46mError Info from %s\033[0m:"%host,e,'\n\n' err_log.write(str(time.ctime())+" | Error Info from "+str(host)+' : '+str(e)+'\n') continue p.close() p.join() print "\033[36m\t\t\t\tProgram Run Out!!\033[0m" err_log.flush() err_log.close() login_info.close() else: if pd == 'put': if l_file and r_file is not None: login_info=open('ssh_login.txt','r') err_log=open('error.log','a') err_log.write('='*30+'this is last result'+'='*30+'\n') for line in login_info: try: host=line.split(',')[0] result.append(p.apply_async(sftp_put,(line,host,l_file,r_file,))) except BaseException,e: print "\033[46mError Info from %s\033[0m:"%host,e,'\n\n' err_log.write(str(time.ctime())+" | Error Info from "+str(host)+' : '+str(e)+'\n') continue print "\033[36m\t\t\t\tProgram Run Out!!\033[0m" p.close() p.join() err_log.flush() err_log.close() login_info.close() else: print "\033[36m -l local_file_path -r remote_file_path\033[0m" elif pd=='down': if l_file and r_file is not None: login_info=open('ssh_login.txt','r') err_log=open('error.log','a') err_log.write('='*30+'this is last result'+'='*30+'\n') for line in login_info: try: host=line.split(',')[0] result.append(p.apply_async(sftp_down,(line,host,l_file,r_file,))) except BaseException,e: print "\033[46mError Info from %s\033[0m:"%host,e,'\n\n' err_log.write(str(time.ctime())+" | Error Info from "+str(host)+' : '+str(e)+'\n') continue p.close() p.join() print "\033[36m\t\t\t\tProgram Run Out!!\033[0m" err_log.flush() err_log.close() login_info.close() else: print "\033[36m -l local_file_path -r remote_file_path\033[0m" else: print "\033[31m The Mode Is Put Or Down!!\033[0m"