博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python paramiko实现多线程远程执行命令、多线程远程上传文件、多线程远程下载文件...
阅读量:6442 次
发布时间:2019-06-23

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

你可能感兴趣的文章
python3导入paramiko模块
查看>>
软件项目送上门来了,还要学会说"不",接了项目拿了定金噩梦才刚刚开始
查看>>
循环、迭代、遍历和递归
查看>>
忘记mysql的root密码
查看>>
使用JavaScript 和 CSS 实现图像缩放和剪裁(转)
查看>>
我的友情链接
查看>>
Code Kata 5
查看>>
RHCE_LAB(4)GRUB提升安全性保护root密码安全
查看>>
Zabbix实现微信平台报警----基于zabbix3.0.4
查看>>
android 安全讲座第二层 使用AndBug调试Android Java Bytecode
查看>>
css3 Gradients 线性渐变
查看>>
ucfirst() 函数
查看>>
bootstrap-导航条层次的导航
查看>>
git rm使用
查看>>
xss***代码
查看>>
Python学习网站
查看>>
mybatis基础(一)
查看>>
Python的Django框架中的Context使用
查看>>
我的友情链接
查看>>
linux常用命令
查看>>