Paramiko模块是一个用来连接远程服务器,进行文件上传下载和shell命令执行的PYTHON模块,使用方便。但是它不支持整个文件夹的上传,近期需要分发上传一个离线工具包到服务器去执行,考虑到远端可能没有安装压缩命令,所以想直接传输完整文件夹(含有嵌套的文件夹),但是paramiko模块的put方法只支持文件的上传。
因此基于put方法开发了一个文件夹的上传方法,在这里共享一下,主要思路是递归遍历文件夹目录,取得所有文件的路径,然后一遍去判断远程目录是否创建(没有则创建),一边用put方法去上传文件。
直接上代码:
import paramiko
import os
import time
def get_all_files_in_local_dir(local_dir):
"""递归获取当前目录下所有文件目录"""
all_files = []
# 获取当前指定目录下的所有目录及文件,包含属性值
files = os.listdir(local_dir)
for x in files:
# local_dir目录中每一个文件或目录的完整路径
filename = os.path.join(local_dir, x)
# 如果是目录,则递归处理该目录
if os.path.isdir(filename):
all_files.extend(get_all_files_in_local_dir(filename))
else:
all_files.append(filename)
return all_files
class Dossh:
def __init__(self,ip,port,uname,passwd):
self.ip =ip
self.port =port
self.uname = uname
self.passwd = passwd
self.sshclt = paramiko.SSHClient()
self.sshclt.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.sshclt.connect(hostname=self.ip, port=self.port, username=self.uname, password=self.passwd,
allow_agent=False, look_for_keys=False)
self.t = paramiko.Transport((self.ip, self.port))
self.t.connect(username=self.uname, password=self.passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.t)
def getssh(self):
return self.sshclt
def close_ssh(self):
self.sshclt.close()
self.sftp.close()
def uploadfile_path(self,local_path,remote_path):
"""
:param local_path:待上传文件夹路径
:param remote_path:远程路径
:return:
"""
#待上传目录名
local_pathname = os.path.split(local_path)[-1]
#上传远程后的目录名
real_remote_Path = remote_path+'/'+local_pathname
##判断是否存在,不存在则创建
try:
self.sftp.stat(remote_path)
except Exception as e:
self.sshclt.exec_command("mkdir -p %s"%remote_path)
self.sshclt.exec_command("mkdir -p %s"%real_remote_Path)
#获取本地文件夹下所有文件路径
all_files = get_all_files_in_local_dir(local_path)
#依次判断远程路径是否存在,不存在则创建,然后上传文件
for file_path in all_files:
#统一win和linux 路径分隔符
file_path = file_path.replace("\\", "/")
##用本地根文件夹名分隔本地文件路径,取得相对的文件路径
off_path_name = file_path.split(local_pathname)[-1]
#取得本地存在的嵌套文件夹层级
abs_path = os.path.split(off_path_name)[0]
#生产期望的远程文件夹路径
reward_remote_path =real_remote_Path+abs_path
#判断期望的远程目录是否存在,不存在则创建
try:
self.sftp.stat(reward_remote_path)
except Exception as e:
self.sshclt.exec_command("mkdir -p %s" % reward_remote_path)
#待上传的文件名
abs_file = os.path.split(file_path)[1]
#上传后的远端路径,文件名不变
to_remote = reward_remote_path+'/'+abs_file
time.sleep(0.1)
self.sftp.put(file_path,to_remote)
print(file_path, to_remote)
if __name__ == "__main__":
sshclent = Dossh(ma_ip,int(ma_port),ma_user,ma_passwd)
sshclent.uploadfile_path("./arthas-packaging-3.5.4-bin",'/home')
使用效果:
本地文件
远端路径
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)