赞
踩
根据工作需求,需要向多个服务器传输多个相同的文件或文件夹,paramiko自带的 put 功能只能传输单个文件,此文中记录一下批量传输文件或文件夹的脚本,以及会根据文件大小判定文件是否传输成功。
需要用到的模块:
- import xlrd
- import paramiko
- import os
- import time
- import re
- transport = paramiko.Transport((ip, 22))
- transport.connect(username=username, password=password)
-
- ssh = paramiko.SSHClient()
- ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 自动添加策略,保存服务器的主机名和秘钥信息,不添加,不在本地hnow_hosts文件中的记录将无法连接
- ssh._transport = transport
-
- sftp = paramiko.SFTPClient.from_transport(transport)
整个脚本的关键之处,定义传输函数,传参有ssh、sftp、本地地址、上传地址,分别判断本地地址与远程传输地址。判断本地地址是否是目录,如果是目录则一直递归,如果是文件,则删除老文件,上传新的文件。
- def _copy(ssh, sftp, local, remote):
- # 判断remote是否是目录
- if _is_exists(remote, function=sftp.chdir):
- # 是,获取local路径中的最后一个文件名拼接到remote中
- filename = os.path.basename(os.path.normpath(local))
- remote = os.path.join(remote, filename).replace('\\', '/')
- # 如果local为目录
- if os.path.isdir(local):
- # 在远程创建相应的目录
- _is_exists(remote, function=sftp.mkdir)
- # 遍历local
- for file in os.listdir(local):
- # 取得file的全路径
- localfile = os.path.join(local, file).replace('\\', '/')
- # 深度递归_copy()
- _copy(ssh=ssh, sftp=sftp, local=localfile, remote=remote)
- # 如果local为文件
- if os.path.isfile(local):
- try:
- ssh.exec_command("rm -rf %s"%(remote))
- time.sleep(1)
- sftp.put(local, remote)
-
- except Exception as error:
- print(error)
- print('[put]', local, '==>', remote, 'FAILED')
- else:
- print('[put]', local, '==>', remote, 'SUCCESSED')
处理地址格式,并判断该目录是否存在。
- def _is_exists(path, function):
- path = path.replace('\\', '/')
- try:
- function(path)
- except Exception as error:
- return False
- else:
- return True
整个脚本代码:
- import xlrd
- import paramiko
- import os
- import time
- import re
-
- CSheet = xlrd.open_workbook(r'C:\Users\Administrator\Desktop\11.xlsx')
- data = CSheet.sheets()[0]
- nrow = data.nrows
-
- FailedList = []
-
- # 检查路径是否存在
- def _is_exists(path, function):
- path = path.replace('\\', '/')
- try:
- function(path)
- except Exception as error:
- return False
- else:
- return True
-
-
- # 拷贝文件
- def _copy(ssh, sftp, local, remote):
- # 判断remote是否是目录
- if _is_exists(remote, function=sftp.chdir):
- # 是,获取local路径中的最后一个文件名拼接到remote中
- filename = os.path.basename(os.path.normpath(local))
- remote = os.path.join(remote, filename).replace('\\', '/')
- # 如果local为目录
- if os.path.isdir(local):
- # 在远程创建相应的目录
- _is_exists(remote, function=sftp.mkdir)
- # 遍历local
- for file in os.listdir(local):
- # 取得file的全路径
- localfile = os.path.join(local, file).replace('\\', '/')
- # 深度递归_copy()
- _copy(ssh=ssh, sftp=sftp, local=localfile, remote=remote)
- # 如果local为文件
- if os.path.isfile(local):
- try:
- ssh.exec_command("rm -rf %s"%(remote))
- time.sleep(1)
- sftp.put(local, remote)
-
- except Exception as error:
- print(error)
- print('[put]', local, '==>', remote, 'FAILED')
- else:
- print('[put]', local, '==>', remote, 'SUCCESSED')
-
-
- for i in range(1, nrow):
- ip = data.row_values(i)[0]
-
- try:
- transport = paramiko.Transport((ip, 22))
- transport.connect(username=username, password=password)
-
- ssh = paramiko.SSHClient()
- ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 自动添加策略,保存服务器的主机名和秘钥信息,不添加,不在本地hnow_hosts文件中的记录将无法连接
- ssh._transport = transport
-
- print("%s 连接成功" % (ip))
-
- sftp = paramiko.SFTPClient.from_transport(transport)
- _copy(ssh=ssh, sftp=sftp, local='C:\\Users\\Administrator\\Desktop\\test', remote='/etc/test')
-
-
- except Exception as reason:
- print(reason)
- FailedList.append(ip)
-
- print("连接失败列表:")
- for j in FailedList:
- print(j)
-
-
结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。