本文共 10465 字,大约阅读时间需要 34 分钟。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | # !/usr/bin/env python # coding:utf-8 import paramiko,datetime,os,threading import pexpect from os import path, walk, makedirs from argparse import ArgumentParser,RawTextHelpFormatter from stat import S_ISDIR runing = True def get_args(): """实例化类,formatter_class参数允许help信息以自定义的格式显示""" parser = ArgumentParser(description = "This is a tool for execute command(s) on remote server(s) or get/put file(s) from/to the remote server(s)\nNotice: please always use '/' as path separater!!!" ,formatter_class = RawTextHelpFormatter,epilog = "Notice:\n If any options use more than once,the last one will overwrite the previous" ) # parser.add_argument('-u',metavar='USER',dest='user',help="remote username",required=True) # parser.add_argument('-p',metavar='PASSWORD',dest='passwd',help=" user's password") # `parser.add_argument('--pkey',nargs='?',metavar='PRIVATE KEY',dest='pkey',help="local private key,if value not followed by this option,the default is: ~/.ssh/id_rsa",default=None,const='%s/.ssh/id_rsa' % path.expanduser('~')) # parser.add_argument('--server', metavar='SERVER_INFO_FILE', help="file include the remote server's information\nwith the format of 'name-ip:port',such as 'web1-192.168.1.100:22',one sever one line", required=True) remote_command = parser.add_argument_group( 'remote command' , 'options for running remote command' ) remote_command.add_argument( '--cmd' ,metavar = '“COMMAND”' ,dest = 'cmd' , help = "command run on remote server,multiple commands sperate by ';'" ) sftp = parser.add_argument_group( 'sftp' , 'options for running sftp' ) sftp.add_argument( '--put' ,metavar = '', help = "transfer from local to remote" ,nargs = 2 ) sftp.add_argument( '--get' ,metavar = '', help = "transfer from remote to local" ,nargs = 2 ) # 全局字典 键(add_argument()中的dest):值(用户输入) # vars将Namespace object转换成dict object global args args = vars (parser.parse_args()) # 判断 --cmd --put --get 三个参数的唯一性 # 清除掉args字典中值为None的项.argparse默认给不出现的值赋值None print args n = 0 for i in ( 'cmd' , 'put' , 'get' ): if i in args: if args[i] is None : del args[i] else : n + = 1 if n > 1 : print ( '\n Only one of the "--cmd --put --get" can be used!' ) exit( 10 ) class run_cmd(threading.Thread): def __init__( self ,hostname = None ,password = None ,username = None ,port = None ,echo_cmd = None ): threading.Thread.__init__( self ) self .hostname = hostname self .password = password self .username = username self .port = port self .echo_cmd = echo_cmd self .thread_stop = False def run( self ): paramiko.util.log_to_file( 'paramiko.log' ) s = paramiko.SSHClient() s.set_missing_host_key_policy(paramiko.AutoAddPolicy()) s.connect(hostname = self .hostname,username = self .username, password = self .password) stdin,stdout,stderr = s.exec_command( self .echo_cmd) print stdout.read() s.close() def stop( self ): self .thread_stop = True class upload_thread(threading.Thread): def __init__( self , hostname = None , password = None , username = None , port = None , local_dir = None , remote_dir = None ): threading.Thread.__init__( self ) self .hostname = hostname self .port = port self .username = username self .password = password self .local_dir = local_dir self .remote_dir = remote_dir self .thread_stop = False def run( self ): try : t = paramiko.Transport(( self .hostname, self .port)) t.connect(username = self .username, password = self .password) sftp = paramiko.SFTPClient.from_transport(t) print 'upload file start %s ' % datetime.datetime.now() for root, dirs, files in os.walk( self .local_dir): for filespath in files: local_file = os.path.join(root, filespath) a = local_file.replace( self .local_dir, self .remote_dir) remote_file = os.path.join( self .remote_dir, a) try : sftp.put(local_file, remote_file) except Exception, e: sftp.mkdir(os.path.split(remote_file)[ 0 ]) sftp.put(local_file, remote_file) print "upload %s to remote %s" % (local_file, remote_file) for name in dirs: local_path = os.path.join(root, name) a = local_path.replace( self .local_dir, self .remote_dir) remote_path = os.path.join( self .remote_dir, a) try : sftp.mkdir(remote_path) print "mkdir path %s" % remote_path except Exception, e: print e print 'upload file success %s ' % datetime.datetime.now() t.close() except Exception, e: print e def stop( self ): self .thread_stop = True ''' class get_thread(threading.Thread): def __init__(self,hostname=None,password=None,username=None,port=None,local_dir=None,remote_dir=None): threading.Thread.__init__(self) self.hostname=hostname self.port=port self.username=username self.password=password self.local_dir=local_dir self.remote_dir=remote_dir self.thread_stop=False def run(self): try: t=paramiko.Transport((self.hostname,self.port)) t.connect(username=self.username,password=self.password) sftp=paramiko.SFTPClient.from_transport(t) print 'get file start %s ' % datetime.datetime.now() for root,dirs,files in os.walk(self.remote_dir): for name in dirs: remote_path = os.path.join(root,name) a = remote_path.replace(self.remote_dir,local_dir) local_path = os.path.join(self.local_dir,a) try: sftp.mkdir(local_path) print "mkdir path %s" % local_path except Exception,e: print e for filespath in files: remote_file = os.path.join(root,filespath) a = remote_file.replace(self.remote_dir,self.local_dir) local_file = os.path.join(self.local_dir,a) try: sftp.get(remote_file,local_file) except Exception,e: sftp.mkdir(os.path.split(local_file)[0]) sftp.get(remote_file,local_file) print "get %s to remote %s" % (remote_file,local_file) print 'get file success %s ' % datetime.datetime.now() t.close() except Exception,e: print e def stop(self): self.thread_stop=True ''' class get_thread(threading.Thread): def __init__( self ,hostname = None ,password = None ,username = None ,port = None ,local_dir = None ,remote_dir = None ): threading.Thread.__init__( self ) self .hostname = hostname self .port = port self .username = username self .password = password self .local_dir = local_dir self .remote_dir = remote_dir self .thread_stop = False def _walk_remote_dir( self , remote_dir): dirnames = [] filenames = [] for fd in self .sftp.listdir_attr(remote_dir): if S_ISDIR(fd.st_mode): dirnames.append(fd.filename) else : filenames.append(fd.filename) yield remote_dir, dirnames, filenames for dirname in dirnames: new_remote_dir = os.path.join(remote_dir, dirname) for walk in self ._walk_remote_dir(new_remote_dir): yield walk def run( self ): try : t = paramiko.Transport(( self .hostname, self .port)) t.connect(username = self .username,password = self .password) self .sftp = paramiko.SFTPClient.from_transport(t) print 'get file start %s ' % datetime.datetime.now() st_mode = self .sftp.stat( self .remote_dir).st_mode if not S_ISDIR(st_mode): filename = os.path.basename( self .remote_dir) self .sftp.get( self .remote_dir, os.path.join(local_dir, filename)) else : parent, child = os.path.split( self .remote_dir) for remote_dir, dirnames, filenames in self ._walk_remote_dir( self .remote_dir): remote_dir = remote_dir.replace(parent, '.' ) parentc = os.path.join(local_dir, remote_dir) if not os.path.exists(parentc): os.makedirs(parentc) for dirname in dirnames: try : os.makedirs(os.path.join(local_dir, remote_dir, dirname)) except : pass for filename in filenames: local_dirpath = os.path.join(local_dir, remote_dir, filename) remote_dirpath = os.path.join(parent, remote_dir, filename) self .sftp.get(remote_dirpath, local_dirpath) print 'get file success %s ' % datetime.datetime.now() t.close() except Exception,e: print e def stop( self ): self .thread_stop = True if __name__ = = '__main__' : get_args() if 'cmd' in args: username = 'root' password = 'xx' port = 22 ip = 'ip1 ip2' host = ip.split( ' ' ) echo_cmd = args[ 'cmd' ] for hostname in host: cmd_thread = run_cmd(hostname, password, username, port, echo_cmd) print hostname cmd_thread.start() cmd_thread.stop() if (cmd_thread.isAlive()): cmd_thread.join() elif 'put' in args: username = 'root' password = 'xx' port = 22 hostname = 'ip1' local_dir = args[ 'put' ][ 0 ] remote_dir = args[ 'put' ][ 1 ] print local_dir,remote_dir uploadthread = upload_thread(hostname, password, username, port, local_dir, remote_dir) uploadthread.start() uploadthread.stop() if (uploadthread.isAlive()): uploadthread.join() elif 'get' in args: username = 'root' password = 'xx' port = 22 hostname = 'ip1' local_dir = args[ 'get' ][ 0 ] remote_dir = args[ 'get' ][ 1 ] getthread = get_thread(hostname, password, username, port, local_dir, remote_dir) getthread.start() getthread.stop() if (getthread.isAlive()): getthread.join() |
使用
python test.py --cmd uptime
python test.py --put /home/nginx /home/nginx
python test.py --get /home/nginx /home/nginx
这个get有点问题,local会变成/home/nginx/nginx多了一层。
使用/home/nginx/ /home/nginx/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # !/usr/bin/env python # -*-coding:utf-8-*- import os,sys local = '/home/logs/a/' remote = '/opt/src/logs/a/test-dmin/' #remote='/opt/src/logs/a/test-dmin' 这两者结果是不一样的 parent, child = os.path.split(remote) print parent dirpath = remote dirpath = dirpath.replace(parent, '.' ) dirname = 'test/test2' print local,dirpath,dirname print os.path.join(local, dirpath, dirname) or # !/usr/bin/env python # coding:utf-8 import os,sys local_dir = '/home/nginx' remote_dir = '/home/nginx' dirname = 'test003' parent, child = os.path.split(remote_dir) remote_dir = remote_dir.replace(parent, '.' ) parentc = os.path.join(local_dir, remote_dir) print parentc print remote_dir print os.path.join(local_dir, remote_dir, dirname) |
本文转自 liqius 51CTO博客,原文链接:http://blog.51cto.com/szgb17/1913581,如需转载请自行联系原作者