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