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

相关文章
|
7月前
|
数据可视化 Linux iOS开发
Python脚本转EXE文件实战指南:从原理到操作全解析
本教程详解如何将Python脚本打包为EXE文件,涵盖PyInstaller、auto-py-to-exe和cx_Freeze三种工具,包含实战案例与常见问题解决方案,助你轻松发布独立运行的Python程序。
1768 2
|
6月前
|
监控 机器人 编译器
如何将python代码打包成exe文件---PyInstaller打包之神
PyInstaller可将Python程序打包为独立可执行文件,无需用户安装Python环境。它自动分析代码依赖,整合解释器、库及资源,支持一键生成exe,方便分发。使用pip安装后,通过简单命令即可完成打包,适合各类项目部署。
1196 68
|
6月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
671 0
|
8月前
|
数据采集 消息中间件 并行计算
Python多线程与多进程性能对比:从原理到实战的深度解析
在Python编程中,多线程与多进程是提升并发性能的关键手段。本文通过实验数据、代码示例和通俗比喻,深入解析两者在不同任务类型下的性能表现,帮助开发者科学选择并发策略,优化程序效率。
657 1
|
8月前
|
缓存 数据可视化 Linux
Python文件/目录比较实战:排除特定类型的实用技巧
本文通过四个实战案例,详解如何使用Python比较目录差异并灵活排除特定文件,涵盖基础比较、大文件处理、跨平台适配与可视化报告生成,助力开发者高效完成目录同步与数据校验任务。
278 0
|
9月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
数据采集 Java 数据处理
Python实用技巧:轻松驾驭多线程与多进程,加速任务执行
在Python编程中,多线程和多进程是提升程序效率的关键工具。多线程适用于I/O密集型任务,如文件读写、网络请求;多进程则适合CPU密集型任务,如科学计算、图像处理。本文详细介绍这两种并发编程方式的基本用法及应用场景,并通过实例代码展示如何使用threading、multiprocessing模块及线程池、进程池来优化程序性能。结合实际案例,帮助读者掌握并发编程技巧,提高程序执行速度和资源利用率。
704 0
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
Python中的多线程与多进程
本文将探讨Python中多线程和多进程的基本概念、使用场景以及实现方式。通过对比分析,我们将了解何时使用多线程或多进程更为合适,并提供一些实用的代码示例来帮助读者更好地理解这两种并发编程技术。
|
数据采集 存储 安全
如何确保Python Queue的线程和进程安全性:使用锁的技巧
本文探讨了在Python爬虫技术中使用锁来保障Queue(队列)的线程和进程安全性。通过分析`queue.Queue`及`multiprocessing.Queue`的基本线程与进程安全特性,文章指出在特定场景下使用锁的重要性。文中还提供了一个综合示例,该示例利用亿牛云爬虫代理服务、多线程技术和锁机制,实现了高效且安全的网页数据采集流程。示例涵盖了代理IP、User-Agent和Cookie的设置,以及如何使用BeautifulSoup解析HTML内容并将其保存为文档。通过这种方式,不仅提高了数据采集效率,还有效避免了并发环境下的数据竞争问题。
345 1
如何确保Python Queue的线程和进程安全性:使用锁的技巧

热门文章

最新文章

推荐镜像

更多