Paramiko是基于Python(2.7,3.4+)版本实现和封装了SSHv2协议,底层是用cryptography实现,我们如果希望远程登录主机或者远程下载或者上传文件到远程主机都可以使用该库实现。Paramiko属于第三方python库,需要我们使用pip进行安装,如果是离线需要在有网络的环境下载好whl文件,再到对应的离线环境进行安装。
类似于SSH协议,Paramiko主要分为SSHClient和SFTPClient,前者主要对远程主机进行操作,输入命令对远程主机进行控制,后者主要实现了从远程主机上上传下载文件,除此之外还有很多实用的方法,本文主要是自己在工作中经常使用的方法进行封装,更多更全面的介绍请参考paramiko的api文档https://www.paramiko.org/
import paramiko
class SSHConnection:
#初始化连接创建Transport通道
def __init__(self,host='xxx.xxx.xxx.xxx',port=22,user='xxx',pwd='xxxxx'):
self.host = host
self.port = port
self.user = user
self.pwd = pwd
self.__transport = paramiko.Transport((self.host,self.port))
self.__transport.connect(username=self.user,password=self.pwd)
self.sftp = paramiko.SFTPClient.from_transport(self.__transport)
#关闭通道
def close(self):
self.sftp.close()
self.__transport.close()
#上传文件到远程主机
def upload(self,local_path,remote_path):
self.sftp.put(local_path,remote_path)
#从远程主机下载文件到本地
def download(self,local_path,remote_path):
self.sftp.get(remote_path,local_path)
#在远程主机上创建目录
def mkdir(self,target_path,mode='0777'):
self.sftp.mkdir(target_path,mode)
#删除远程主机上的目录
def rmdir(self,target_path):
self.sftp.rmdir(target_path)
#查看目录下文件以及子目录(如果需要更加细粒度的文件信息建议使用listdir_attr)
def listdir(self,target_path):
return self.sftp.listdir(target_path)
#删除文件
def remove(self,target_path):
self.sftp.remove(target_path)
#查看目录下文件以及子目录的详细信息(包含内容和参考os.stat返回一个FSTPAttributes对象,对象的具体属性请用__dict__查看)
def listdirattr(self,target_path):
try:
list = self.sftp.listdir_attr(target_path)
except BaseException as e:
print(e)
return list
#获取文件详情
def stat(self,remote_path):
return self.sftp.stat(remote_path)
#SSHClient输入命令远程操作主机
def cmd(self,command):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
ssh._transport = self.__transport
stdin, stdout, stderr = ssh.exec_command(command)
result = stdout.read()
print(result)
return result
具体使用实例如下:
from paramikotools import SSHConnection
import os
import time
import datetime
from cmdline import parse_args
from util_log import Logging
ssh = None
logging = Logging().get_logger()
#递归遍历远程目录下的所有文件
def gci(remote_path,pathlist):
for f in ssh.listdirattr(remote_path):
if (str(f.longname).split(" ")[0].startswith('d')):
gci(os.path.join(remote_path,f.filename),pathlist)
else:
pathlist.append(os.path.join(remote_path,f.filename))
return pathlist
if __name__ == '__main__':
#接收参数
args = parse_args()
#初始化ssh
ssh = SSHConnection(host=args.srchost,user=args.srcuser,pwd=args.srcpasswd)
while True:
try:
#创建本地接收文件目录(按天创建目录)
datedir = os.path.join(args.dstpath,datetime.datetime.now().strftime('%Y%m%d'))
#创建子目录之前保证父级目录创建否则抛出异常
os.mkdir(args.dstpath)
os.mkdir(datedir)
except BaseException as e:
pass
beforedict = dict()
afterdict = dict()
pathlist = []
#获取所有文件名以及每个文件的当前大小
for i in gci(args.srcpath,pathlist):
beforedict.setdefault(i,ssh.stat(i).st_size)
#隔interval秒获取每个文件名以及当前大小
time.sleep(int(args.interval))
for i in gci(args.srcpath,pathlist):
afterdict.setdefault(i,ssh.stat(i).st_size)
#对比时间前后文件大小如果一致认为文件已经生成完成,将文件下载到本地
for i in beforedict.keys():
if beforedict.get(i) == afterdict.get(i):
try:
ssh.download(os.path.join(datedir,os.path.basename(i)),i)
logging.info('File '+i+' download completed')
ssh.remove(i)
logging.info('File '+i+' deleted')
except BaseException as e:
logging.error('File '+i+' download failed')
logging.error(e)
logging.error('File '+i+' delete failed')
ssh.close()
这是我在实际案例中所运用的paramiko的部分方法及其封装,希望能对大家有所帮助,具体更详细,更全面的方法请阅读paramiko官方的api接口,如果代码有问题希望大家批评指正,共同进步,本文到此结束,谢谢大家。