您的位置:首页 > 编程语言 > Python开发

python paramiko实现多线程远程执行命令、多线程远程上传文件、多线程远程下载文件

2017-04-06 19:09 1071 查看
# !/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/
# !/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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python
相关文章推荐