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,如需转载请自行联系原作者

相关文章
|
6月前
|
数据可视化 Linux iOS开发
Python脚本转EXE文件实战指南:从原理到操作全解析
本教程详解如何将Python脚本打包为EXE文件,涵盖PyInstaller、auto-py-to-exe和cx_Freeze三种工具,包含实战案例与常见问题解决方案,助你轻松发布独立运行的Python程序。
1563 2
|
5月前
|
监控 机器人 编译器
如何将python代码打包成exe文件---PyInstaller打包之神
PyInstaller可将Python程序打包为独立可执行文件,无需用户安装Python环境。它自动分析代码依赖,整合解释器、库及资源,支持一键生成exe,方便分发。使用pip安装后,通过简单命令即可完成打包,适合各类项目部署。
995 68
|
8月前
|
Web App开发 安全 数据安全/隐私保护
利用Python+Requests实现抖音无水印视频下载
利用Python+Requests实现抖音无水印视频下载
|
6月前
|
小程序 PHP 图形学
热门小游戏源码(Python+PHP)下载-微信小程序游戏源码Unity发实战指南​
本文详解如何结合Python、PHP与Unity开发并部署小游戏至微信小程序。涵盖技术选型、Pygame实战、PHP后端对接、Unity转换适配及性能优化,提供从原型到发布的完整指南,助力开发者快速上手并发布游戏。
|
7月前
|
缓存 数据可视化 Linux
Python文件/目录比较实战:排除特定类型的实用技巧
本文通过四个实战案例,详解如何使用Python比较目录差异并灵活排除特定文件,涵盖基础比较、大文件处理、跨平台适配与可视化报告生成,助力开发者高效完成目录同步与数据校验任务。
246 0
|
8月前
|
编译器 Python
如何利用Python批量重命名PDF文件
本文介绍了如何使用Python提取PDF内容并用于文件重命名。通过安装Python环境、PyCharm编译器及Jupyter Notebook,结合tabula库实现PDF数据读取与处理,并提供代码示例与参考文献。
|
8月前
|
编译器 Python
如何利用Python批量重命名文件
本文介绍了如何使用Python和PyCharm对文件进行批量重命名,包括文件名前后互换、按特定字符调整顺序等实用技巧,并提供了完整代码示例。同时推荐了第三方工具Bulk Rename Utility,便于无需编程实现高效重命名。适用于需要处理大量文件命名的场景,提升工作效率。
|
11月前
|
Python
使用Python实现multipart/form-data文件接收的http服务器
至此,使用Python实现一个可以接收 'multipart/form-data' 文件的HTTP服务器的步骤就讲解完毕了。希望通过我的讲解,你可以更好地理解其中的逻辑,另外,你也可以尝试在实际项目中运用这方面的知识。
507 69
|
9月前
|
编解码 Prometheus Java
当Python同时操作1000个文件时,为什么你的CPU只用了10%?
本文介绍如何构建一个高效的文件处理系统,解决单线程效率低、多线程易崩溃的矛盾。通过异步队列与多线程池结合,实现任务调度优化,提升I/O密集型操作的性能。
211 4
|
8月前
|
安全 Linux 网络安全
Python极速搭建局域网文件共享服务器:一行命令实现HTTPS安全传输
本文介绍如何利用Python的http.server模块,通过一行命令快速搭建支持HTTPS的安全文件下载服务器,无需第三方工具,3分钟部署,保障局域网文件共享的隐私与安全。
1949 0

热门文章

最新文章

推荐镜像

更多