python paramiko实现多线程远程执行命令、多线程远程上传文件、多线程远程下载文件

简介:
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
     =  0
     for  in  ( 'cmd' , 'put' , 'get' ):
         if  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 :
             =  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)
                     =  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)
                     =  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,如需转载请自行联系原作者

相关文章
|
1天前
|
安全 Java 关系型数据库
多线程(线程安全)
多线程(线程安全)
12 4
|
1天前
|
Java 调度
多线程(创建多线程的五种方式,线程状态, 线程中断)
多线程(创建多线程的五种方式,线程状态, 线程中断)
11 0
|
2天前
|
Linux 调度 Windows
【操作系统】线程、多线程模型
【操作系统】线程、多线程模型
11 1
|
2天前
|
并行计算 Python
Python并发编程与多线程
Python编程中,多线程和并发编程是优化复杂任务执行的关键。借助标准库中的`threading`模块,可实现多线程,如示例所示,创建线程并执行函数。然而,由于全局解释器锁(GIL),多线程在CPU密集型任务中并不高效。对于I/O密集型任务,多线程仍能提高效率。为充分利用多核,可采用多进程(如`multiprocessing`模块)或异步编程。选择技术时需依据任务类型和性能需求。
|
2天前
|
Java 调度
多线程的基本概念和实现方式,线程的调度,守护线程、礼让线程、插入线程
多线程的基本概念和实现方式,线程的调度,守护线程、礼让线程、插入线程
11 0
|
2天前
|
设计模式 安全 Java
Java多线程案例-Java多线程(3)
Java多线程案例-Java多线程(3)
8 1
|
2天前
|
存储 安全 Java
Java多线程安全风险-Java多线程(2)
Java多线程安全风险-Java多线程(2)
9 1
|
2天前
|
Java 调度
聊聊Java线程是个啥东西-Java多线程(1)
聊聊Java线程是个啥东西-Java多线程(1)
10 0
小白入门必备!计算机科学教程的Python精要参考PDF开放下载!
随着互联网产业的高速发展,在网络上早已积累了极其丰富的Python学习资料,任何人都可以基于这些资源,自学掌握 Python。 但实际上,网络上充斥的资源太多、太杂且不成体系,在没有足够的编程/工程经验之前,仅靠“看”线上资源自学,的确是一件非常困难的事。
|
3天前
|
人工智能 Linux 开发工具
[oeasy]python018_ 如何下载github仓库_git_clone_下载仓库
在这个文档中,作者讨论了如何继续进行编程学习,特别是关于GitHub的使用。首先,回顾了从编写简单代码到管理大量代码的过程。然后,提到了通过“保存运行一条龙”操作来处理代码,以及GitHub作为全球最大的开源软件平台的重要性。在GitHub上,用户可以找到各种软件项目,包括Linux、Python和Blender等。 作者解释了GitHub的基本操作,如点赞(star)、 fork(复制项目)和watch(关注项目更新)。还介绍了如何下载项目到本地,通过`git clone`命令复制仓库的URL并将其粘贴到终端进行下载。如果遇到问题,可以尝试更换HTTP链接或等待一段时间重试。
188 1