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

相关文章
|
5天前
|
计算机视觉 Python
如何使用Python将TS文件转换为MP4
本文介绍了如何使用Python和FFmpeg将TS文件转换为MP4文件。首先需要安装Python和FFmpeg,然后通过`subprocess`模块调用FFmpeg命令,实现文件格式的转换。代码示例展示了具体的操作步骤,包括检查文件存在性、构建FFmpeg命令和执行转换过程。
29 7
|
1月前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
44 2
|
2月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
23 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
38 2
|
29天前
|
数据采集 Java Python
爬取小说资源的Python实践:从单线程到多线程的效率飞跃
本文介绍了一种使用Python从笔趣阁网站爬取小说内容的方法,并通过引入多线程技术大幅提高了下载效率。文章首先概述了环境准备,包括所需安装的库,然后详细描述了爬虫程序的设计与实现过程,包括发送HTTP请求、解析HTML文档、提取章节链接及多线程下载等步骤。最后,强调了性能优化的重要性,并提醒读者遵守相关法律法规。
62 0
|
29天前
|
中间件 Docker Python
【Azure Function】FTP上传了Python Function文件后,无法在门户页面加载函数的问题
通过FTP上传Python Function至Azure云后,出现函数列表无法加载的问题。经排查,发现是由于`requirements.txt`中的依赖包未被正确安装。解决方法为:在本地安装依赖包到`.python_packages/lib/site-packages`目录,再将该目录内容上传至云上的`wwwroot`目录,并重启应用。最终成功加载函数列表。
|
16天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
15天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
3天前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
98 80
|
22天前
|
存储 索引 Python
Python编程数据结构的深入理解
深入理解 Python 中的数据结构是提高编程能力的重要途径。通过合理选择和使用数据结构,可以提高程序的效率和质量
133 59