接https://www.cnblogs.com/tingxin/p/13060440.html 优化
默认用ssh key 登录,并在日志的文件名加入进程ID
import paramiko import threading import sys,os import datetime from conf import logconf import getpass hostname = "" def hostnamelist(): """ :return: hostname list """ global result,hosttoal try: hosts = open("vmhost", "r", encoding='utf-8') hostnames = hosts.readlines() hosts.seek(0) hosttoal = len(open("vmhost", "r", encoding='utf-8').readlines()) print("There are %d target host :/n%s" % (hosttoal,hostnames)) hosts.close() return hostnames except FileNotFoundError: print('无法打开指定的文件!') except LookupError: print('指定了未知的编码!') except UnicodeDecodeError: print('读取文件时解码错误!') finally: if hosts: hosts.close() class RemoteServer(object): """ Container class for SSH functionality. Needs to be used in a with statement. """ def __init__(self): self.ssh_client = None self.user = "root" self.password = None self.logtarget = '' self.server = '' self.status = True #set all the reulst is running successfully self.ssh_client = paramiko.SSHClient() self.privatekey = "" self.keyfile = "" self.ssh_client.load_system_host_keys() self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.logtarget = os.path.basename(__file__).split('.')[0] print(os.path.basename(__file__)) def __setattr__(self, key, value): self.__dict__[key]=value def __exit__(self, exc_type, exc_val, exc_tb): try: if self.ssh_client is not None: self.logger.info('Exit remote server (%s) now, Bye,Bye !', self.server) self.ssh_client.close() except: self.logger.error("received an exception closing the ssh connection.", exc_info=True) finally: self.ssh_client = None def connect(self): try: self.logger.info('tring to connect server %s', self.server) if self.password == None: self.logger.info("login with ssh key") self.privatekey = paramiko.RSAKey.from_private_key_file(self.keyfile) self.ssh_client.connect(self.server, 22, self.user, pkey=self.privatekey) else: self.logger.info("login with password") self.ssh_client.connect(self.server, 22, self.user, self.password) except paramiko.AuthenticationException: self.logger.error("Wrongful username or password. Please try again", exc_info=True) try: self.ssh_client.connect(self.server,22, self.user, self.password) except: self.logger.error("Wrongful username or password. Please try again", exc_info=True) sys.exit(1) except : self.logger.error('connect to remote server %s failed',self.server) self.logger.error("Unexpected error:", sys.exc_info()[0]) exit() return self def execute(self,sudo=False): self.logfile = self.logtarget +'.' + self.server.split('.')[0]+'_'+str(os.getpid()) self.logger = logconf.logconf(self.logfile) # init log config self.connect() self.logger.info("connect to server %s Successfully ! ", self.server) for command in commands: command = command.strip(" ") try: starttime = datetime.datetime.now() self.logger.info('Start execute command: (%s) on host (%s) ',command,self.server) stdin, stdout, stderr = self.ssh_client.exec_command(command,timeout=180) self.logger.info('Following is the (%s) result ',command) self.logger.info(stdout.read().decode(encoding='utf-8')) self.logger.info('Execute ({}) used times: ({}s) '.format(command, datetime.datetime.now() - starttime)) except paramiko.SSHException: self.logger.error(stderr.read().decode(encoding='utf-8'),exc_info=True) self.logger.info("End of execute on server (%s)",self.server) self.logger.error("Pls check the reason and run agin", self.server) exit() if sudo: stdin.write(self.password + ' ') stdin.flush() if stderr.read().decode(encoding='utf-8'): self.logger.error(stderr.read().decode(encoding='utf-8'), exc_info=True) self.logger.info("End of execute on server (%s)", self.server) self.logger.error("Pls check the command (%s) and run agin",command) self.status = False break if self.status == False: self.logger.info("One of the command is run failed on (%s),pls check the logfile (%s) for detail information !!! ", self.server,os.path.join(os.path.dirname(os.getcwd()),'worklog',self.logfile)) else: self.logger.info("all the batch process running successfully on (%s) ", self.server) if __name__ == '__main__': # cmd = ['date','hostname','cat /etc/security/limits.conf|grep -v ^#|grep -v ^$','cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$','cat /etc/sysctl.conf|grep -v ^#|grep -v ^$'] commands="" with open("command.txt",'r',encoding='utf-8') as batch: commands = batch.readlines() print("following command will be execute %s" %(commands)) username = "root" # 用户名 sshkey = input("Passwor or key ? Yes for key ,No for password :") while True: if sshkey == "Yes" or sshkey == "": password ="" print("Login with ssh key") break else: print("Login with Password") password = getpass.getpass('please type password of %s :' % username) break # username = input("Please Input Username :") # 用户名 # command = input("pls input command , which can be split by comma :") print("........................................Batch Process Begin........................................") for targethost in hostnamelist(): targethost = targethost.strip(" ") sshhost = RemoteServer() sshhost.server,sshhost.port,sshhost.user = targethost,22,"root" if password: sshhost.password = password else: sshhost.keyfile = "..confid_rsa".replace('\', '/') if sshhost.keyfile: print("Found key file for autologin") batch = threading.Thread(sshhost.execute()) batch.start() batch.join() print("........................................Batch Process End........................................")