paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。
- 创建paramiko_client - 基于用户用密码
- 存在写死的代码 理解明白即可,可自定义在相应的配置文件中
- 其中包括创建sftp连接用于本地与服务器文件的上传与下载
- 配置文件在下方
#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/23 9:10
# @Author : ****
import paramiko
import ConfigParser
class PKClient(object):
def __init__(self, config_str, com_str=''):
"""
:param config_str: 配置文件
:param com_str: 远程服务器运行的指令
"""
self.config = ConfigParser.ConfigParser()
self.config.read(config_str)
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client_status = 0
self.sftp_client = None
self.com_str = com_str
def get_sftp_client(self):
"""
创建sftp连接
:return:
"""
if self.client_status == 0:
self.connect()
if not self.sftp_client:
self.sftp_client = paramiko.SFTPClient.from_transport(self.client.get_transport())
return self.sftp_client
def run_cmd(self):
"""
连接服务器后进行命令操作
:return:
"""
stdin, stdout, stderr = self.client.exec_command(self.com_str)
for item in stdout:
print(item)
self.client_status = 1
def connect(self):
"""
连接远程服务器
连接异常关闭连接
:return:
"""
try:
self.client.connect(hostname=self.config.get('ssh', 'hostname'), port=self.config.getint('ssh', 'port'),
username=self.config.get('ssh', 'username'),
password=self.config.get('ssh', 'password'),
timeout=self.config.getfloat('ssh', 'timeout'))
except Exception, e:
print(e)
try:
self.client.close()
except:
pass
self.run_cmd()
if __name__ == '__main__':
PKClient(r'D:\Python2.7\untitled\text-paramiko\config.ini', 'date').get_sftp_client()
- 此处为 config.ini 配置文件的内容
[ssh]
hostname=xxx.xxx.xxx.xxx
port=端口号
username=用户名
password=密码
timeout=1
- 文件的上传
#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/23 13:04
# @Author : ****
from paramiko_client import PKClient
client = PKClient('config.ini')
# client.connect()
sftp_client = client.get_sftp_client()
def put_callback(size1, size2): # 回调函数,用于显示(上传文件)本地与服务器端的文件大小,可优化为md5值进行比较
print(size1, size2)
# (本地,服务器端,回调函数(可省略))
sftp_client.put(r'D:\Python2.7\untitled\text-paramiko\config.ini', '/home/zyy/config.ini', put_callback)
- 文件的下载
#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/21 18:06
# @Author : ****
import os
from paramiko_client import PKClient
import ConfigParser
class BaseFileInfo:
def __init__(self, name=None, seq=None):
"""
:param name: 文件名
:param seq: 文件版本号
conf.get('total', 'req') 为大版本的版本号
"""
self.name = name
self.seq = seq
self.client = PKClient('config.ini', '')
self.sftp_client = self.client.get_sftp_client()
self.conf = ConfigParser.ConfigParser()
self.conf.read('res.txt')
self.total_seq = self.conf.get('total', 'req')
self.ori_total_seq = 0
self.file_map = {} # 存放 [] 下的每一项文件的名称及版本号
@staticmethod
def get_callback(size1, size2):
"""
:param size2: 服务器端文件大小
:param size3: 本地文件大小
:return:
"""
print(size1, size2)
def run(self):
"""
下载服务器端文件版本的序列号记录文件 res_des.txt
conf.sections() 这个东西为 res_des.txt文件中的[file] 每一项[]内的内容
:return:
"""
self.client.sftp_client.get('/home/zyy/client_res/res_des.txt', r'D:\Python2.7\untitled\text-paramiko\res.txt', self.get_callback)
if self.total_seq != self.ori_total_seq: # 比较本地与服务器端版本号是否一致
sectons = self.conf.sections() # res.txt 中的 []
for secton in sectons:
if secton == 'files':
for conf in self.conf.items(secton): # ('t1.txt', '1') 为 []下的每一个文件名称对应的版本号
name = conf[0]
seq = conf[1]
if name in self.file_map: # 文件名称在,版本号不同进行文件更新
file = self.file_map[name]
if file.seq != seq:
self.sftp_client.get('/home/zyy/client_res/' + name, r'D:\Python2.7\untitled\text-paramiko' + os.sep + name)
else:
self.sftp_client.get('/home/zyy/client_res/' + name, r'D:\Python2.7\untitled\text-paramiko' + os.sep + name)
info = BaseFileInfo(name, seq) # 文件名称及版本号
self.file_map[name] = info
if __name__ == '__main__':
BaseFileInfo().run()